Brief Introduction to Linux character Device Driver

Source: Internet
Author: User
Article Title: Brief Introduction to Linux character device driver analysis. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.

In Linux, device drivers are organized into a set of functions for completing different tasks. These functions make linux device operations look like files. In the view of applications, a hardware device is just a device file. Applications can operate on hardware devices like normal files, such as open (), close (), read () and write.

Linux mainly divides devices into two categories: character devices and Block devices. A character device sends and receives data in the form of characters, while a block device sends and receives data in the form of a data buffer. Character device drivers are relatively simple.

Let's assume a very simple virtual character device: the device only has a four-byte global variable int global_var, and the device name is "globalvar ". Read/write operations on the "globalvar" device are the operations on the global variable global_var.

The driver is a part of the kernel, so we need to add a module initialization function for it to complete the initialization of the controlled device, and call the register_chrdev () function to register the character device:

       
        
Static int _ init globalvar_init (void) {if (register_chrdev (MAJOR_NUM, "globalvar", & gobalvar_fops )){//... Registration Failed} else {//... Registered successfully }}
       

The MAJOR_NUM parameter in the register_chrdev function is the main device number, "globalvar" indicates the device name, And globalvar_fops indicates the struct containing the entry point of the basic function. The type is file_operations. When the globalvar module is loaded, globalvar_init is executed. It will call the kernel function register_chrdev and store the driver's basic entry point pointer in the kernel's character device address table, the entry address is provided when the user process calls the device.

The module unmount function corresponds to the module initialization function. You need to call the "inverse function" of register_chrdev"

       
        
Unregister_chrdev (): static void _ exit globalvar_exit (void) {if (unregister_chrdev (MAJOR_NUM, "globalvar ")){//... Failed to uninstall} else {//... Uninstalled successfully }}
       

With the addition of new features in the kernel, The file_operations struct has become larger and larger, but most drivers only use part of it. For character devices, the main endpoints are: open (), release (), read (), write (), ioctl (), llseek (), and poll ().

When the open () function is used to call the open () system for special files on the device, the open () function of the driver is called:

Int (* open) (struct inode *, struct file *);

The inode parameter is the pointer to the inode (index node) Structure of the special file of the device. The parameter file is the pointer to the file structure of the device. The main task of open () is to determine whether the hardware is in the ready state and verify the validity of the sub-device number (the Sub-device number can be obtained using MINOR (inode-> I-rdev) control the number of processes on the device, return status code based on the execution status (0 indicates success, negative indicates error), and so on;

Release () function when the last user process that opens the device executes the close () system call, the kernel will call the release () function of the driver:

Void (* release) (struct inode *, struct file *);

The main task of the release function is to clear unfinished input/output operations, release resources, and reset the User-Defined exclusive flag.

When you call the read () system for a special file on the device, the read () function of the driver is called:

Ssize_t (* read) (struct file *, char *, size_t, loff_t *);

Used to read data from devices. When this function pointer is assigned a NULL value, an error occurs in the read System Call and-EINVAL ("Invalid argument, Invalid parameter") is returned "). If the function returns a non-negative value, it indicates the number of bytes successfully read (the returned value is of the "signed size" data type, which is usually an inherent Integer type on the target platform ).

In the globalvar_read function, the memory interaction between the kernel space and the user space requires the functions described in section 2nd:

       
        static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off){ … copy_to_user(buf, &global_var, sizeof(int)); …}
       

The write () function calls the write () function of the driver when a special file of the device is called by the write () system:

Ssize_t (* write) (struct file *, const char *, size_t, loff_t *);

Send data to the device. Without this function, the write system will return a-EINVAL to the calling program. If the returned value is not negative, it indicates the number of bytes successfully written.

The memory interaction between the kernel space and the user space in the globalvar_write function requires the functions described in section 2nd:

       
        static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off){…copy_from_user(&global_var, buf, sizeof(int));…}
       

Ioctl () is a special control function that can be used to transmit control information to a device or obtain status information from a device. The function is prototype:

Int (* ioctl) (struct inode *, struct file *, unsigned int, unsigned long );

The unsigned int parameter is the code of the command to be executed by the device driver. It is customized by the user. The unsigned long parameter provides parameters for the corresponding command. The type can be integer or pointer. If the device does not provide an ioctl entry point, the ioctl system will return an error (-ENOTTY, "No such ioctl fordevice, this ioctl command is not available for this device "). If the device method returns a non-negative value, the value is returned to the caller to indicate that the call is successful.

 

[1] [2] Next page

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.