Hot swapping of Linux kernel drivers

[Recommended reading]

Talking about the cloning and duplication of sk_buff in linux kernel network

In-depth linux kernel architecture--process & thread

Understand the linux kernel technology that Docker depends on

This article briefly records the hot plug in the Linux driver. When developing the Linux kernel driver, classes are often created in the program and devices are created in the class. For example, the following paragraph is excerpted from the previous code

major = register_chrdev(0, "fifth_drv", &sencod_drv_fops);
fifthdrv_class = class_create(THIS_MODULE, "fifth_drv");
fifthdrv_class_dev = class_device_create(fifthdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */

After that, the buttons node will be generated in the /dev directory. I will not experiment with this, it is very simple. So, why is the device node generated after executing the above code? Next, let's take a look at what the class_device_create function does

Call the class_device_register function

Call the class_device_add function, this function is easier, so its content will not be displayed, and finally call

kobject_uevent(&class_dev->kobj, KOBJ_ADD);

call kobject_uevent_env,

action_string = action_to_string(action); //action is the parameter KOBJ_ADD passed in, indicating that a device should be added at this time
/* Allocate memory to hold environment variables */
/* environment values */
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
to omit......
/* set environment variables */
envp [i++] = scratch;
scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
envp [i++] = scratch;
scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
to omit......
argv [0] = uevent_helper;
argv [1] = (char *)subsystem;
argv [2] = NULL;
call_usermodehelper (argv[0], argv, envp, 0);

This function is to set environment variables, and finally executes a user function uevent_helper, passing the environment variables in,

Add print here, print out which user function is executed? And what are the environment variables at this time?

It can be seen that the executed user program is /sbin/mdev, and the environment variables are the following ones. Therefore, it is possible to draw a conclusion that when creating a device node, the driver actually executes the /dev/mdev of the user space. program, and pass some information about the device node to mdev, note that the ACTION at this time is add,

The device node is finally generated through mdev. As for how to generate the device node, you can analyze the mdev_main function of busybox to draw a conclusion. Similarly, when uninstalling the driver, the ACTION value of the passed environment variable is remove, which is uninstalled by mdev device driver.

It briefly explains how the driver is generated as a device node, so what does it have to do with our hot-swapping mechanism in this section?

The hot-swapping mechanism is to perform some actions automatically by the system when inserting/removing a device. When analyzing the mdev_main function, it can be seen that in the function, it will judge whether the script /etc/mdev.conf currently exists in the system. If it exists, the content of the script will be executed. In this script, some commands can be defined, and these commands are specified to be executed after the device is created or before it is deleted. Then, for example, if we insert a USB disk on the development board, first The device node /dev/sdx will be generated in the system /dev directory. This mechanism is as mentioned above, and then to determine whether the /dev/mdev.conf script exists, we can let the u disk be automatically mounted in this script. In order to realize the mechanism of hot plugging.

mdev.conf of the format:
<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]
device regex: A regular expression indicating which device
uid: owner
gid: Group ID
octal permissions: properties expressed in octal
@: Execute the command after creating the device node
$: Execute the command before deleting the device node
*: Execute the command after creating the device node and before deleting the device node
command: command to execute

Ok, let’s realize the U disk through a regular expression

automount for

sda[1-9]+ 0:0 777 * if [ $ACTION = "add" ]; then mount /dev/$MDEV /mnt; else umount /mnt; fi

If the device node generated by the U disk is sda1...sda9,

sda[1-9]+: [1-9]+ means that any one of the numbers 1-9 appears once,

0:0: is the user and group ID

777: Attributes of the generated device

*: Execute the command after creating the device node and before deleting the device node

Followed by a command, if the environment variable at this time is "add", mount the U disk, if not, unmount the U disk.

A simple hot-plug-based U disk mount is complete.

Tags: Linux Operation & Maintenance

Posted by Cesar on Tue, 10 Jan 2023 15:22:45 +0530