1, equipment description structure Cdev
Drive model
In the Linux system, the device type is very numerous, character device, block device, network interface device, USB device, PCI device, platform device, hybrid device, etc., also means that its corresponding hungry driver model is different, which led to the need to master a lot of driver model, So whether we can extract some common rules from the many driving models is the key to the Linux drive.
A, driver initialization
1), Device description structure (in the Cdev.h file)
In any drive model, the device is described by a structure in the kernel. Our character devices are described using struct cdev in the kernel.
struct cdev{
struct Kobject kobj;
struct module owner;
const struct File_operation *ops;//device operation set
struct List_head list;
dev_t dev;//Device number
unsigned int count;//number of devices
}
Some of these members are used by program developers themselves, and some are used by the kernel.
Developers have to use: unsigned int count;//device number. dev_t Dev;//main device number
What is the main device number? Enter Linux,ls-l/dev/can see before time has a num1,num2, the former NUM1 is the main device number, num2 is the second device number.
Main device Number:
Character device file-"character device driver: How does the character device file and the character device driver set up the corresponding relationship?" By the main device number.
Secondary device number:
Serial port 1, serial port 2--"serial driver: What is the driver to differentiate the serial port 1 and the serial port 2? The secondary device number.
Device number--operation:
The Linux kernel uses the dev_t type to define the device number, dev_t this type is a 32-bit unsigned int with a high 12-bit primary device number, and a low 20-bit number for the secondary device.
Q 1: If you know how the main device number and the secondary device number make up the dev_t type
Answer: dev_t Dev=mkdev (main device number, secondary device number)
Q 2: How do I break out the main device number from the dev_t?
Answer: Device number =major (dev_t dev)
Q 3: ... Break out the secondary device number?
A: Secondary device number =minor (dev_t dev)
Device number Assignment
How do I assign a master device number to a device?
A, static application
The developer chooses a number as the primary device number and then uses the function register_chrdev_region to apply to the kernel: disadvantage: If the requested device number has already been used by other drivers in the kernel, the request fails.
b, dynamic distribution
Use Alloc_chrdev_region to allocate a usable master device number by the kernel. Advantage: Because the kernel knows which device numbers are already in use, it does not cause the assigned device number to be used.
Device number-Logoff
Regardless of the method used to assign the device number, you should use the Unregister_chrdev_region function to release the device numbers when the driver exits.
struct file_operation struct members are function pointers, and these function names are consistent with the system invocation of our file programming.
This table is file_operation.
Set of operating functions:
struct file_operation
is a collection of function pointers that define what operations can be performed on the device, the function pointers in the structure point to the corresponding functions of the implementation in the drive, the functions that implement a device-specific operation, and the function pointer null for unsupported operations, such as
struct File_operation dev_fops=
{
. Llseek=null,
. Read=dev_read,
. Write=dev_write,
. Ioctl=dev_ioctl,
. Open=dev_open,
. Release=dev_release,
};
Driver initialization: It is usually done in the module initialization function.
1. Description structure--Distribution
The definition of a Cdev variable can take both static and dynamic methods:
Static assignment: struct Cdev mdev;
Dynamic assignment: struct Cdev *pdev=cdev_alloc ();
2. Description structure--Initialization
The initialization of struct Cdev is done using the Cdev_init function.
Cdev_init (struct cdev *cdev,const struct file_operations *fops), where FoPs is a member of Cdev
Parameter: cdev--CDEV structure to initialize
fops--set of operating functions corresponding to a device, which is a member variable of Cdev
3. Description structure--Registration
The registration of the character device is done using the Cdev_add function.
Cdev_add (struct Cdev *p,dev_t dev,unsigned count)
Parameter: P character device structure to be added to the kernel
Dev: Device number
Count: The number of devices for this class of devices.
The above three steps to complete the character device is already registered in the kernel, if it is a hardware device, you also need to do the relevant hardware initialization.
B, matters equipment operation also known as equipment method
1, equipment operation prototype
Int (*open) (struct inode *,struct file *)
Turn on the device in response to the open system call
Int (*release) (struct inode *,struct file*)
Turn off the device in response to the close system call
loff_t (*llseek) (struct file*,loff_t,int)
Reposition the write pointer in response to the Lseek system call.
ssize_t (*read) (struct file*,char__user*,size_t, loff_t*)
Reads the data from the device in response to the read system call.
ssize_t (*write) (struct file *,const char__user *,size_t,loff_t *)
Writes data to the device in response to a write system call.
struct File:
In a Linux system, each open file is associated with a struct file in the kernel, which is created by the kernel at the time the file is opened and released after the file is closed.
Important members: loff_t F_ops//read-write pointer to file, struct file_operations *f_op;//the action of the file. File_operations This file has a mapping table that maps user requirements to the appropriate driver functions.
struct Inode:
Each file that exists in the file system is associated with an inode structure, which is primarily used to record the physical information of a file. Therefore, it is different from the struct file structure that represents the open file, when a file is not opened, it is not associated with the file structure, but it is associated with an inode structure whose key member: dev_t i_rdev;//device number.
Device Operation-----Open
The open device method is used by the driver to complete the initialization for a later operation, ready to work. In most drivers, open completes the following tasks: marking the secondary device number, starting the device.
Device Operation-----Release
The release method works just as opposed to open
This device method is sometimes called close, and it should shut down the device.
Device Operation-----Read
The Read device method typically accomplishes 2 things:
Reads data from the device (which is part of the hardware Access class operation) and returns the read data to the application.
ssize_t (*read) (struct file *filp,char __user *buff,size_t count,loff_t *OFFP)
Parameters: where the parameters from the application (or system call) have, the amount of data to read count, the data to be read to save the location buff; kernel parameter: FD is used by the kernel to open the corresponding struct FILE,OFFP it points to the location where the file is read and written.
FILP: A file structure pointer associated with a character device file, created by the kernel, a buff: the data that is read from the device, the location to be saved to, and the parameter provided by the read system call.
Count: The amount of data requested for transmission, provided by the read system call.
OFFP: The Read and write location of the file is passed in after the kernel is removed from the file structure.
The buff parameter is derived from the user-space pointer, which cannot be referenced directly by the kernel code and must use a specialized function
int copy _from_user (void *to,const void __user *from,int N)
int Copy_to_user (void __user *to,const void *from,int N)
ssize_t dev_read (struct file *file,char *buf,size_t count,loff_t *ppos);
Device Operation----Write
The write device method typically accomplishes 2 things:
Extracting data from the address provided by the application, writing the data to the device (belonging to the hardware access class operation), ssize_t (*write) (struct file *,const char __user *,ssize_t,loff_t *) whose parameters are similar to read.
C, Driver logoff
When we unload the driver from the kernel, we need to use the Cdev_del function to complete the logoff of the character device.
Parsing character device driver labels:
1. Find the module initialization function
First of all, the allocation device structure CDEV, this code adopts static allocation
The corresponding operation function set structure is as follows
Devno file start to define
Here's how to implement the function in the set of operation functions
First look at the file Open function
File Read function
Write function similar to read function
Seek file Locator function
The file release function, because there is no processing hardware, so directly return 0;
The following is the logoff device, which is inside the module unload function
Character Device driver Model