S3C2440 hotplug driver hotplug_uevent mechanism (thirty-three)

Publisher:温暖微笑Latest update time:2020-07-18 Source: eefocusKeywords:S3C2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Every time we insert a USB flash drive, the device node /dev/sda%d of the USB flash drive will be automatically created.


This is because device_create() is called inside, and the mdev mechanism of busybox will create device nodes in the /dev directory according to information such as the primary and secondary device numbers, as shown in the following figure:

If you want to use the sda1 device node above, you need to use mount /dev/sda1 /mnt to mount it on the USB disk when reading and writing data, which is very troublesome, as shown in the following figure:

2. In fact, you can add a line of statement in the /etc/mdev.conf file to automatically load the USB disk, and you can also do other things related to the device node in it.


2.1 What is /etc/mdev.conf?


It is a configuration file belonging to mdev. As mentioned before, mdev's main function is to manage device nodes under the /dev directory.


When there is an automatic registration of device nodes in the system, mdev will /etc/mdev.conf once. This file can implement things related to device nodes, such as automatically loading USB, printing the created device node information, etc.


3. Let's first analyze how device_ceate() calls /etc/mdev.conf, and then we'll talk about how to use mdev.conf (you can also skip this and go directly to Section 4 below to see how to use it)


(ps: class_device_create(), which was used to create character device nodes before, is actually similar to device_create in function)


3.1 class_device_create() eventually calls: class_device_create()->class_device_register()->class_device_add():


The device_create()->device_register()->device_add() function is as follows:

 

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 class_device_create()->class_device_register()->class_device_add()->kobject_uevent_env() function is as follows:


int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char *envp_ext[])

{

       char **envp;

       char *buffer;

       char *scratch;

       int i = 0;

       ... ...

 

       /* Get the string "add" through KOBJ_ADD, so 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 environment variables*/

       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 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 to create a device node based on the environment variable parameters passed in

       }

}

From the above code and comments, we can see that the device node is finally created through the environment variable parameters stored in the two string arrays *argv[] and *envp[].


3.2 Next, add print information in the kobject_uevent_env() function and then re-burn uboot:


kobject_uevent_env() function in linux-2.6.22.6libkobject_uevent.c

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


Load the previous button driver, insmod buttons.ko prints the following statement:


class_device: argv[0]=/sbin/mdev //Call mdev

 

class_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 adding a device node, if =remove: means uninstalling a device node

 

class_device: envp[3]=DEVPATH=/class/sixth_dev/buttons //Device path

 

class_device: envp[4]=SUBSYSTEM=sixth_dev //class name

 

class_device: envp[5]=SEQNUM=745

 

class_device: envp[6]=MAJOR=252 //Major device number

 

class_device: envp[7]=MINOR=0

3.4 Finally, these parameters enter the mdev_main() function of busybox's mdev.c according to /sbin/mdev:


int mdev_main(int argc, char **argv)

{

... ...

action = getenv("ACTION"); //Get the execution parameters passed in. If it is equal to "add", it means creating a device node

env_path = getenv("DEVPATH"); //Get the device path "/class/sixth_dev/buttons"

sprintf(temp, "/sys%s", env_path); //Specify temp (real device path) as "/sys/class/sixth_dev/buttons"

 

if (!strcmp(action, "remove")) //Uninstall device node

                    make_device(temp, 1);

 

else if (!strcmp(action, "add")) { //Create device node

                     make_device(temp, 0);

 ... ... 

}


3.5 Finally, the mdev_main()->make_device() function is called to create/uninstall the device node. The function is as follows:


static void make_device(char *path, int delete) //delete=0: create, delete=1: uninstall

{

       /*Determine 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); //Get the name of the device node to be created/uninstalled through the device path

                      //Example: path = "/sys /class/sixth_dev/buttons", then device_name = "buttons"


type = path[5]=='c' ? S_IFCHR : S_IFBLK; //If it is in the /sys/class/ directory, then it is a character device

                                              //Because the block device exists in the /sys/block/ directory

 

 

/* If the mdev.conf option is configured to support it, then parse the content and execute */

 if (ENABLE_FEATURE_MDEV_CONF) { 

       /* mmap the config file */

fd = open("/etc/mdev.conf", O_RDONLY); //Call the /etc/mdev.conf configuration file

     

      ... ... //Start operating the mdev.conf configuration file

}

 

 

 

       if (!delete) { //If it is to create a device node

 

              if (sscanf(temp, "%d:%d", &major, &minor) != 2) return; //Get the major and minor device numbers

 

        /*Call mknod() to 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 the mdev.conf option is configured to support it, call the chown command to change the owner, the default uid and gid = 0 */

              if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid);

}

 

     if (delete) unlink(device_name); //If it is to uninstall the device node

}

From the above code and comments, we can see that to use the mdev.conf configuration file, you also need to configure busybox's menuconfig so that mdev supports the mdev.conf option.


As shown below, enter the busybox directory and enter make menuconfig. We will find that we have already configured this option.

4. Next, let's take a look at how to use mdev.conf, refer to: busybox-1.7.0docsmdev.txt document


The usage is as follows:


the format: : [<@|$|*> ]


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.


It's probably:


Configuration file format:


: [<@|$|*> ]


The meaning of each parameter is as follows:


device regex:


Regular expression to express which device, regular expression explanation link: https://deerchao.net/tutorials/regex/regex.htm


uid:


owner (uid, gid: when registering a device node, it will be called by the chown command to change the owner of the device. The default value is 0)


gid:


Group ID


Octal permissions:


The permission value expressed in octal will be called by the chmod command to change the access rights of the device. The default value is 660.


@: Execute the command after creating the device node


$: Execute command before deleting device node


*: Execute commands after creating a device node and before deleting a device node


command: The command to be executed


5. Next, use mdev.conf to realize automatic loading of USB disk


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]: matches numbers from 1 to 9


+ : Repeat the match one or more times


$ACTION = "add": indicates registering the device node, otherwise it indicates unregistering the device node


/dev/$MDEV: indicates the device node to be created/deregistered


So when we plug in the USB drive and automatically create /dev/sda1, mdev will enter the /etc/mdev.conf configuration file, and then execute the mount /dev/ command to automatically mount the USB drive, as shown in the following figure:

Enter ls /dev/sda1 -l, and you can see that all device nodes are created through the configuration information in mdev.conf, as shown in the following figure:

When you take out the USB drive, umount /mnt will be automatically used to uninstall it.

Keywords:S3C2440 Reference address:S3C2440 hotplug driver hotplug_uevent mechanism (thirty-three)

Previous article:S3C2440 touch screen driver (Seventeen)
Next article:S3C2440 audio decoding chip WM8976 sound card driver transplantation (31)

Recommended ReadingLatest update time:2024-11-23 18:45

S3C2440 touch screen driver example development explanation
1. Development environment Host: VMWare--Fedora 9 Development board: Mini2440--64MB Nand, Kernel:2.6.30.4 Compiler: arm-linux-gcc-4.3.2 2. Prerequisite knowledge 1. Linux input subsystem (Input Subsystem):    In Linux, the input subsystem is composed of the input subsystem device driver layer, the input subsystem
[Microcontroller]
S3C2440 touch screen driver example development explanation
Web based on Linux Network File System (NFS) and S3C2440
  With the popularity of digital cameras and the Internet, more and more families have their own media libraries. The media library contains both image files shot by yourself and image data downloaded from the Internet. However, the means of displaying image data is single, mainly through PC. Therefore, it will become
[Microcontroller]
Web based on Linux Network File System (NFS) and S3C2440
u-boot-2011.06 is started from nandflash based on the transplantation of s3c2440 development board
Due to the price, NandFlash is more advantageous than NorFlash for storing large amounts of data. However, programs cannot be run directly on NandFlash, so S3C2440 provides a mechanism where the system automatically copies the first 4K of the content in NandFlash to an internal SRAM called "Steppingstone". Using thi
[Microcontroller]
S3C2440——Keyboard interrupt service routine
S3C2440 keyboard module circuit There are a total of S1, S2, S3, and S4 buttons, which correspond to the four interrupt sources EINT19, EINT2, EINT0, and EINT11 respectively. The interrupt framework and service routine are as follows: Interrupt response, take out the keyboard number (1-4) that triggered the interr
[Microcontroller]
S3C2440——Keyboard interrupt service routine
Writing and testing program of Linux key driver under S3C2440
Driver tang2440_buttons.c #include linux/module.h #include linux/kernel.h #include linux/fs.h #include linux/init.h #include linux/delay.h #include linux/poll.h #include linux/irq.h #include asm/irq.h #include linux/interrupt.h #include asm/uaccess.h #include mach/regs-gpio.h #include mach/hardware.h #include linux/pl
[Microcontroller]
s3c2440 network card interface expansion DM9000
Network is essential for embedded systems. However, s3c2440 does not have an integrated Ethernet interface, so if you want to make s3c2440 have Ethernet function, you must expand the network card interface. Here, we connect DM9000 externally so that it can be connected to Ethernet. DM9000 can be directly
[Microcontroller]
【mini2440】Serial port of S3C2440
1. Basic Circuit 2. Related registers 2.1 Pinout 2.2 Block Diagram 2.3 Serial Port 3. Related code The clock control logic in S3C2440A can generate the necessary clock signals, including FCLK of CPU, HCLK of AHB bus peripherals and PCLK of APB bus peripherals. S3C2440A contains two phase-locked loops (PLL): o
[Microcontroller]
【mini2440】Serial port of S3C2440
Research and implementation of vehicle-mounted GPS/GPRS tracking and monitoring system based on S3C2440
0 Introduction With the continuous development and improvement of the transportation system, the application scope and field of positioning and navigation systems are becoming more and more extensive. Vehicle tracking and monitoring systems based on GPS, GPRS/GSM, GIS, etc. are becoming more and more popular, showing
[Microcontroller]
Research and implementation of vehicle-mounted GPS/GPRS tracking and monitoring system based on S3C2440
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号