1. Device Description Structure Cdev
The wide variety of drive models required me to extract some of their commonalities from a multitude of models:
A. Driver initialization
A.1 Assigning device description structure
A.2 Initializing device description structure
A.3 Registering Device description structure
A.4 Hardware Initialization
B. Implement device operation
C. Driver logoff
------------------------------------------------------------------
Device Description Structure:
In any drive model, the device is described by a structure in the kernel, and our character devices are described using struct cdev in the kernel.
struct Cdev {
struct Kobject kobj;
struct module *owner;
const struct File__operations *ops;//device operation set
struct List_head list;
dev__t dev;//Device number
unsigned int count;//number of devices
};
To view the device number under the/dev directory:
Ls-l/dev
Each row of the five, six is the primary and secondary equipment number.
The main device number links the driver to the device file.
The second device number is to let the driver differentiate the serial port 1, serial Port 2. Distinguish between devices of the same type.
A. Device number operation:
The Linux kernel uses the dev_t type to define the device number, dev_t this type of unsigned int with a substance of 32, where the height 12 is the primary device number, and the lower 20 is the device number.
1. How to know the primary and secondary equipment number. How to combine into dev_t type?
dev_t dev = MKDEV
2. How to break down the primary and secondary equipment number from the dev_t?
Main device number =major (dev_t dev)
Secondary device number =minor (dev_t dev)
B. Device number assignment:
Static application: The developer chooses a number as the main device number, and then uses the function register_chrdev_region to apply to the kernel, the disadvantage: if the requested device number is already used by other drivers in the kernel, the request fails.
Dynamic allocation:
Use Alloc_chrdev_region to allocate a usable master device number by the kernel.
Advantage: Because the kernel knows which numbers are already in use, it does not cause the assigned number to be used.
C. Logoff of the device number:
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.
--------------------------------------------------------------
Set of operating functions
const struct file_operation *ops; acts as a mapping relationship table.
File_operation is similar to a table, which corresponds to a function in the driver, with a system call function.
The corresponding unsupported operation sets the function pointer to NULL,
struct File_operation dev_fops = {
. llseek= NULL,
. Read = Dev_read,
}
-------------------------------------------------------------
2. Character device driver Model
A. Driver initialization
A.1 Assignment Description structure:
The definition of cdev variable can be static and dynamic two methods
static assignment: struct Cdev mdev
Dynamic Assignment: struct Cdev * Pdev = Cdev_alloc (); The initialization of the
A.2 initialization description Structure
struct Cdev is done using the Cdev_init function.
Cdev_init (struct cdev *cdev,const struct file_operation *fops)
Cdev: Cdev structure to initialize
FoPs: Set of operating functions for the device
A.3 Registration Description Structure
character device registration use Cdev_add function to complete
Cdev_add (struct Cdev *p,dev_t dev,unsigned count)
P: Character device structure to be added to the kernel
Dev : Device number
Count: Number of devices for this device
A.4 hardware initialization
B. Implementing device Operation
Open release write Llseek read (these operations alias device method)
Understand when the operation was called, Understand what these actions do?
Int (*open) (struct inode*,struct file*): Turn on the device, corresponding to the open system.
Int (*release) (struct inode*,struct file*): Shuts down the device in response to the close system call.
loff_t (*llseek) (struct file*,loff_t,int): repositions read-write pointers, responding to lseek system calls.
ssize_t (*read) (struct File*,char __user*,size_t,loff_t*): reads data from the device, responds 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 when the file is opened and released after the file is closed.
loff_t F_pos/* file read/write pointer */
struct File_operations *f_op/* The action for the file */
struct Inode: Each file system file is associated with an inode structure, which is primarily used to record the physical information of a file, so it is different from the file structure that represents the open files, and a file is not opened without associating the document structure. But it is associated with an inode structure.
dev_t I_rdev: Device number.
---------------------------------------------------------------
Device operation
Open: Indicates the secondary device number, starting the device.
Release: Turn off the device
READ: Reads data from the device and returns the data read to the application.
Note: The buff parameter is a pointer from the user space, which cannot be referenced directly by the kernel code, and must use a special 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 (*read) (struct file *filp, char __user *buff, size_t count, loff_t *OFFP)
Parametric analysis:
FILP: A file structure pointer associated with a character device file, created by the kernel.
Buff: The data to be read from the device, where it needs to be saved. This parameter is 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.
Driver Logoff:
Using function Cdev_del
Character device driver model