To develop this driver, several new
=
To link normal files with a kernel module two numbers are used:
To achieve this, a file (which will be used to access the device driver) must be created, by typing the following command as root:
In the above,
Within the driver, in order to link it with its corresponding
=
#include
statements which appear frequently in device drivers need to be added:=
/* Necessary includes for device drivers */
#include // here linux/init.h
#include // here linux/config.h
#include //here linux/module.h
#include // here linux/kernel.h /* printk() */
#include // here linux/slab.h /* kmalloc() */
#include // here linux/fs.h /* everything... */
#include // here linux/errno.h /* error codes */
#include // here linux/types.h /* size_t */
#include // here linux/proc_fs.h
#include // here linux/fcntl.h /* O_ACCMODE */
#include // here asm/system.h /* cli(), *_flags */
#include // here asm/uaccess.h /* copy_from/to_user */
MODULE_LICENSE("Dual BSD/GPL");
/* Declaration of memory.c functions */
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
void memory_exit(void);
int memory_init(void);
/* Structure that declares the usual file */
/* access functions */
struct file_operations memory_fops = {
read: memory_read,
write: memory_write,
open: memory_open,
release: memory_release
};
/* Declaration of the init and exit functions */
module_init(memory_init);
module_exit(memory_exit);
/* Global variables of the driver */
/* Major number */
int memory_major = 60;
/* Buffer to store data */
char *memory_buffer;
After the #include
files, the functions that will be defined later are declared. The common functions which are typically used to manipulate files are declared in the definition of the file_operations
structure. These will also be explained in detail later. Next, the initialization and exit functions—used when loading and removing the module—are declared to the kernel. Finally, the global variables of the driver are declared: one of them is the major number
of the driver, the other is a pointer to a region in memory, memory_buffer
, which will be used as storage for the driver data.The “memory” driver: connection of the device with its files
In UNIX and Linux, devices are accessed from user space in exactly the same way as files are accessed. These device files are normally subdirectories of the/dev
directory.To link normal files with a kernel module two numbers are used:
major number
and minor number
. The major number
is the one the kernel uses to link a file with its driver. The minor number
is for internal use of the device and for simplicity it won’t be covered in this article.To achieve this, a file (which will be used to access the device driver) must be created, by typing the following command as root:
# mknod /dev/memory c 60 0
In the above,
c
means that a char
device is to be created, 60
is the major number
and 0
is the minor number
.Within the driver, in order to link it with its corresponding
/dev
file in kernel space, the register_chrdev
function is used. It is called with three arguments: major number
, a string of characters showing the module name, and a file_operations
structure which links the call with the file functions it defines. It is invoked, when installing the module, in this way:=
int memory_init(void) {
int result;
/* Registering device */
result = register_chrdev(memory_major, "memory", &memory_fops);
if (result < 0) {
printk(
"<1>memory: cannot obtain major number %d\n", memory_major);
return result;
}
/* Allocating memory for the buffer */
memory_buffer = kmalloc(1, GFP_KERNEL);
if (!memory_buffer) {
result = -ENOMEM;
goto fail;
}
memset(memory_buffer, 0, 1);
printk("<1>Inserting memory module\n");
return 0;
fail:
memory_exit();
return result;
}
0 nhận xét:
Đăng nhận xét