1. Every time we insert u After hours , Will automatically create a key U The device node of the disk /dev/sda%d

This is because it calls device_create() Realized , busybox Of mdev The mechanism will be based on the primary and secondary device number and other information , stay /dev Create a device node under , As shown in the figure below :
 Insert picture description here
And want to use the above sda1 Device node , When reading and writing data , You also need to use mount /dev/sda1 /mnt, To mount u It's only when it's hard , It's going to be very troublesome , As shown in the figure below :
 Insert picture description here

2. Actually , Can be in /etc/mdev.conf Add a line of statements to the file to realize automatic loading u disc , You can also do other things related to device nodes inside

2.1 and /etc/mdev.conf What is it again? ?

It belongs to mdev A profile for , and mdev As I said before , Its main function is to manage /dev Device nodes under the directory

When there is an automatic registration device node in the system ,mdev Will call /etc/mdev.conf once , This file can do things related to device nodes , Like auto loading usb, Print the created device node information, etc

3. Let's first analyze device_create(), How to call /etc/mdev.conf Of , I'll talk about how to use it later mdev.conf( It can also be skipped directly , Look directly at the next 4 Section , How to use )

(PS: Used to create character device node class_device_create(), In fact, yes. device_create It's almost functional )

3.1 device_create() Finally called :device_create()->device_register()->device_add():

device_create()->device_register()->device_add() The function is shown below :int class_device_add(struct class_device *class_dev){   ... ...   kobject_uevent(&class_dev->kobj, KOBJ_ADD);         // KOBJ_ADD Is an enumeration value   // Called kobject_uevent_env(kobj, action, NULL);              // action=KOBJ_ADD}

3.2 device_create()->device_register()->device_add()->kobject_uevent_env() The function is shown below :

int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,char *envp_ext[]){   char **envp;   char *buffer;   char *scratch;   int i = 0;   ... ...   /*  adopt KOBJ_ADD Get string "add", therefore action_string="add"  */   action_string = action_to_string(action);              // action=KOBJ_ADD   
       /* environment index */   envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);      // Assign an environment variable index value    /* environment values */ buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);     // Assign an environment variable buffer value       /* event environemnt for helper process only *//* Set the environment variable */   envp[i++] = "HOME=/";   envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";   scratch = buffer;   envp [i++] = scratch;   scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;  //"ACTION= add"   envp [i++] = scratch;   scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;   envp [i++] = scratch;   scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;   ... ...   /* Call the application , such as mdev*/   if (uevent_helper[0]) {char *argv [3];  argv [0] = uevent_helper;       // uevent_helper[]= "/sbin/hotplug";  argv [1] = (char *)subsystem;  argv [2] = NULL;  call_usermodehelper (argv[0], argv, envp, 0);        // Call the application , Create a device node based on the passed in environment variable parameters    }}

From the code and comments above , Finally through *argv[], *envp[] Two string arrays of environment variable parameters to create the device node

3.2 The next step is kobject_uevent_env() Function to add print information , And burn the core again :

 Insert picture description here

3.3 Then let's take registering a key driver as an example

Input insmod key.ko, Printed the following statement :

class_device: argv[0]=/sbin/mdev             // call mdevclass_device: argv[1]=sixth_dev                      // Class name class_device: envp[0]=HOME=/class_device: envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
class_device: envp[2]=ACTION=add      //add: Means to add a device node , if =remove: Represents the unload device node class_device: envp[3]=DEVPATH=/class/sixth_dev/buttons  // The path to the device class_device: envp[4]=SUBSYSTEM=sixth_dev             // Class name class_device: envp[5]=SEQNUM=745class_device: envp[6]=MAJOR=252                          // The main equipment, class_device: envp[7]=MINOR=0

3.4 Finally, these parameters are based on /sbin/mdev It's in busybox Of mdev.c Of mdev_main() In the function :

int mdev_main(int argc, char **argv){... ...action = getenv("ACTION");          // Get the passed in execution parameters , It's equal to “add”, To create a device node env_path = getenv("DEVPATH");   // Get the path of the device “/class/sixth_dev/buttons”sprintf(temp, "/sys%s", env_path);   // Appoint temp ( The real device path ) by “/sys/class/sixth_dev/buttons”if (!strcmp(action, "remove"))           // Unload device node make_device(temp, 1);else if (!strcmp(action, "add")) {       // Create device nodes  make_device(temp, 0);
 ... ... }

3.5 The final call mdev_main ()->make_device() Function to create / Unload device node , The function is shown below :

static void make_device(char *path, int delete) //delete=0: establish , delete=1: uninstall {   /* Judge whether the created device node is a valid device */   if (!delete) {  strcat(path, "/dev");  len = open_read_close(path, temp + 1, 64);  *temp++ = 0;  if (len < 1) return;   }device_name = bb_basename(path);    // Through the device path , To get to create / Name of the device node unloaded   // example : path =“/sys /class/sixth_dev/buttons”, that device_name=“buttons”
 type = path[5]=='c' ? S_IFCHR : S_IFBLK;     // Judge if it's in /sys/class/ Under the table of contents , So that's the character device   // Because the block device , Exist /sys/block/ In the catalog /*  If support is configured mdev.conf Options , Then parse the contents and execute    */
       /* mmap the config file */fd = open("/etc/mdev.conf", O_RDONLY);     // call /etc/mdev.conf The configuration file     ... ...         // Start the operation  mdev.conf The configuration file }
       if (!delete) {                  // If you are creating a device node   if (sscanf(temp, "%d:%d", &major, &minor) != 2) return;   // Get the primary and secondary device number /* call mknod () Create a character device node */if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) bb_perror_msg_and_die("mknod %s", device_name);  if (major == root_major && minor == root_minor) symlink(device_name, "root");  /* If support is configured mdev.conf Options , Call chown Command to change the owner , Default uid and gid=0 */  if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid);} if (delete) unlink(device_name);           // If it's an offload device node }

From the analysis of the above code and comments to , To use mdev.conf The configuration file , You also need to configure busybox Of menuconfig, send mdev Support mdev.conf Options are fine

Here's the picture , Get into busybox Catalog , Then input make menuconfig, We found that we have configured this option
 Insert picture description here

4. Next , Let's see how to use mdev.conf, Reference resources busybox-1.7.0/docs/mdev.txt file

The usage method is shown below :

the format:   <device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]The special characters have the meaning:@ Run after creating the device.$ Run before removing the device.* Run both after creating and before removing the device.

Is probably :

Profile format :

<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]

The meaning of each parameter is as follows :

device regex:

Regular expressions , To express which device , Regular expressions explain Links :https://deerchao.net/tutorials/regex/regex.htm


owner (uid,gid: When registering device nodes , Will be chown Command invocation , To change the owner of the device , The default is 0 that will do )


Group ID

octal permissions:

The permission value in octal , Will be chmod Command invocation , To change access to the device , Default fill 660 that will do

@ : After creating the device node, execute the command

$ : Execute the command before deleting the device node

* : After creating the device node and Before deleting the device node Carry out orders

command : Commands to execute

5. Next, I'll use mdev.conf, Realization u Disk auto loading

vi /etc/mdev.conf

Add the following sentence :

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

[1-9] : matching 1~9 The number of ,

+ : Repeat matching once or more

$ACTION==“add” : Represents a registered device node , Otherwise, the device node will be logged off

/dev/$MDEV : Means to create / The device node that was logged off

So when we plug in u disc , Automatically created /dev/sda1 when ,mdev Will enter /etc/mdev.conf The configuration file , And then execute mount /dev/ command , You can load it automatically U disc , As shown in the figure below :
 Insert picture description here
And take it out u Disk time , It's also automatic umount /mnt To uninstall