Linux classification driver uninstallation of character device framework Pressure

Source: Internet
Author: User

The 2.6 kernel introduces a series of character device subsystems, such as the input file system, USB sub-system, and MISC sub-system. After mastering these subsystems, let's take a look at the significance of Linux kernel design? There are more and more devices that can be connected, and the types of these devices are becoming more and more complex. Traditional character devices/Block devices cannot meet the requirements. Take character devices as an example, currently, the Linux character device system cannot represent the minimum intersection of all supported character devices. Moreover, as the number of devices increases, the longer and longer linear device chain lists cause a lot of inconvenience to management, therefore, we need to add a layer to relieve some pressure on the Character equipment system, so we will summarize all the "class-one" devices into "one" device, this device is then added to the linked list as a character device, and the real character device needs to be managed by a new "layer". After the re-design, the summarized "that" character device is no longer a traditional device, but a "device class". At the same time, the/dev directory also has a corresponding "device class ", for example,/dev/input, which contains a series of files, some of which represent the "device class" mentioned above, for example, mice is all the mouse, and some files represent real devices, for example, mouse0 or mouse1. From the application point of view, the input subsystem does unload the pressure on the character device system, because it adds a layer. The code is needed to implement this layer:
Static int _ init input_init (void)
{
Int err;
Err = class_register (& input_class );
Err = input_proc_init ();
Err = register_chrdev (input_major, "input", & input_fops); // you only need to initialize one character device. The master device number is 0xd.
Return 0;
}
Static const struct file_operations input_fops = {
. Owner = this_module,
. Open = input_open_file,
};
Static int input_open_file (struct inode * inode, struct file * file)
{
Struct input_handler * Handler;
Const struct file_operations * old_fops, * new_fops = NULL;
Handler = input_table [iminor (inode)> 5]; // you can see that the input subsystem currently only supports eight types of devices.
New_fops = fops_get (Handler-> FoPs); // obtain the real fops set in the "layer" of the input subsystem.
Old_fops = file-> f_op;
File-> f_op = new_fops;
Err = new_fops-> open (inode, file );
...
}
It can be seen from the code of the above character device system that the real character device to be detached needs the input layer for centralized implementation. We can imagine that a device class in the input subsystem should have a handler which is indexed by the minor obtained from the inode of the device file. Let's look at an example:
# Stat Mice
File: 'mice'
Size: 0 blocks: 0 Io block: 4096 character special file
Device: 1607 H/5639d inode: 23921566 links: 1 device type: D, 3f # The primary device number is 0xd, and the secondary device number is 0x3f
...
Note that the primary and secondary device numbers are separated by the input sub-system into eight sub-spaces based on the 3-bit height. Each sub-space represents all the devices of a category of devices in the input sub-system.
Static int _ init mousedev_init (void)
{
Mousedev_mix = mousedev_create (null, & mousedev_handler, mousedev_mix); // The/dev/input/mice file is created.
Input_register_handler (& mousedev_handler );
Return 0;
}
Mousedev_init only initializes the frame of the mouse device in the input subsystem, and then creates a common mouse class through mousedev_create. When will the actual mouse class file be created? Each input device has an input_handler. The mouse is mousedev_handler. It is registered into the system through mousedev_init. All handler forms a linked list, and the input subsystem also has another linked list in the system, that is, the input device. Whenever a new device is inserted into the machine, the device driver at the lower level will manage the input system when it knows that the device is an input device, that is to say, initialize an input_dev, link it to the input_dev linked list, traverse the input_handler linked list, and call the connect method after finding the input_handler that "can process this device, for the mouse, that is, mousedev_connect, a mouse device: mousedev_create: Will be initialized in mousedev_connect:
Static struct mousedev * mousedev_create (struct input_dev * Dev, struct input_handler * Handler, int minor)
{
Struct mousedev * mousedev;
Mousedev = kzarloc (sizeof (struct mousedev), gfp_kernel );
...
If (minor = mousedev_mix)
Strlcpy (mousedev-> name, "mice", sizeof (mousedev-> name ));
Else
Snprintf (mousedev-> name, sizeof (mousedev-> name), "Mouse % d", minor );
...
Mousedev-> Dev. devt = mkdev (input_major, mousedev_minor_base + minor); // used to create files under/dev/Input
...
}
The input_dev and input_handler linked lists in the input subsystem are similar to the device and device_driver linked lists in the underlying bus. They use the same idea. The device and device_driver layers are at most at the PCI level. The probe function calls the initialization procedure of the input subsystem, such as allocating input_dev and registering for interruption. After input_dev is registered, the device is under the jurisdiction of the input subsystem. The entire layer is device -- PCI... -- input_dev -- input_handler -- input character device --/dev/input/xxx. When the interrupt occurs, the interrupt handler obtains input_dev from the parameter, then, we can use input_report_xx to report the issue. The report can follow the level clues we just mentioned to reach the point where the user space needs the interrupted result, for example, the interruption of moving the mouse will be used by XWindow.
The input subsystem is just an example of uninstalling the original structure pressure. For example, the USB subsystem, the sound subsystem, and the MISC subsystem are implemented in this way. It gives you a feeling that there is nothing different, if all character devices are implemented directly under the chrdev framework, all character devices will be created under/dev. If many characters are classified, for example, into the input class, or in the USB class, each device still has a character device file under/dev, but the location is different and may be put into the input/USB subdirectory, the result of stat is still character special file. There is no difference. When sysfs/udevd is used, you may not even create input, USB, or other sub-directories, still, it's okay to create all the files in the/dev directory. Note that the input/USB/MISC subsystem only regulates the kernel device driver structure, which is transparent to user space. I feel that such normalization of the Linux kernel best reflects the truth of the computer industry, that is, "adding a Level". By introducing a new level, the Linux Kernel, without changing the original character driver structure, several new classification driver layers are successfully inserted into the existing framework, which also shows the flexibility of the character device framework in the Linux kernel.

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.