Detailed explanation of udev in Linux system

This article is integrated with reference to a lot of information on the Internet. It is only for the convenience of learning and memory. There is no other purpose. If there is copyright infringement, please contact in time.

udev introduction

udev is a newly added device file management module on the Linux kernel2.6 series. Its function is mainly to dynamically manage device files, such as adding and deleting operations. When the newly inserted device is detected by the driver, it will register new data (some information files related to this device) on sysfs. At the same time, the kernel will send uevent of the device to udev, and udev will access the configuration rules after receiving it. Then perform the corresponding operations according to the configuration rules, such as modifying the device group, group, permissions, creating link files, and mounting. Similarly, after the device is unplugged, udev will also receive uevent events sent by the kernel, udev will perform operations such as deleting device files, demounting, deleting link files, etc. according to uevnet rules. In this way, the device files can be managed dynamically, and the device can be hot swapped. There is no need to create a lot of static device files in the / dev directory in advance .
In addition to the above-mentioned dynamic management of device files, another highlight of udev is that it runs in user space and can perform corresponding operations according to customer-defined rules. For example, there are multiple USB interfaces on the device, and there are two USB interface printers. If they are connected to the device at the same time, then two device files will be generated in the / dev / directory on the device, such as / dev / sda and / dev / sdb . So what is their correspondence? sda corresponds to printer 1 or printer 2. This is related to the operation of the customer, such as the order of insertion, and the situation of the machine related to the midway equipment. This cannot be handled in the previous static device file management and devfs. We only need to modify the rules of udev to achieve one-to-one mapping. For example, the device file links printer1, printer2 are created based on the device serial number, vendorID, and so on. As long as the printer 1 is plugged in, a link file printer1 will be generated, and we no longer need constraints such as the sequence of insertion of timing devices.Since udev is a module running in user space, the kernel will still generate sda, sdab and other device files.
The working principle of udev: the sysfs file system was introduced in the Linux2.6 version. sysfs organizes the devices and buses connected to the system into a hierarchical file and provides access to user space. udev runs in user mode, not in the kernel . The udev initialization script creates a device node when the system starts, and after a new device is detected, a series of files are generated on sysfs, and udev creates a new device node. udev must support sysfs and tmpfs in the kernel, sysfs provides device entry and uevent channel for udev, and tmpfs provides storage space for udev device files . The following figure is the work flow chart of udev. The configuration file is stored in the /etc/udev/udev.conf file.
Insert picture description here
Why use udev, because the device file management methods (static files and devfs) used previously have some defects:

  • Uncertain device mapping. Especially for those dynamic devices, such as USB devices, the mapping of device files to actual devices is not reliable and deterministic. Take an example: if you have two USB printers. One may be called / dev / usb / lp0, and the other is / dev / usb / lp1. However, it is not clear which is which, lp0, lp1 and the actual device do not have a one-to-one correspondence, because he may find that the order of the device, the printer itself is turned off and other reasons lead to this mapping is not sure. The ideal way should be: two printers should be mapped using a unique device file based on their serial number or other identification information. But neither static files nor devfs can do this.
  • There are not enough primary / secondary equipment numbers. We know that each device file has two 8-digit numbers: one is the main device number, and the other is the auxiliary device number. These two 8-bit numbers plus the device type (block device or character device) to uniquely identify a device. Unfortunately, the numbers around them are not enough.
  • There are too many files in the / dev directory. A system uses static device file association, so there must be enough files in this directory. At the same time, you don't know which device files are activated on your system.
  • The naming is not flexible enough. Although devfs solves some of the previous problems, it itself brings some problems. One of them is that the naming is not flexible enough; you can change the name of the device file very simply. The default devfs command mechanism itself is also very strange, he needs to modify a lot of configuration files and programs. ;
  • Kernel memory usage, another problem unique to devfs is that as a kernel driver module, devfs needs to consume a lot of memory, especially when there are a large number of devices on the system (such as the system we mentioned above has thousands of disks on one)

The goal of udev is to solve these problems mentioned above. He uses the user-space tool to manage the / dev / directory tree, which is separate from the file system. Knowing how to change the default configuration allows you to know how to customize your system, such as creating device character connections, changing device file groups, and permissions.

udev rules

As mentioned above, udev will perform related operations according to user rules. So where are these rules files placed and what are the rules? Among the rules, this article only explains some common ones. For details, please check the man udev documentation.
The main udev configuration file is ** / etc / udev / udev.conf **. This file is usually very short, as shown below. Among them, udev_root specifies the root directory where device files are stored, udev_rules specifies the storage path of the rules, and udev_log specifies the level of logging. There are other configurations that will not be explained here, such as the database where logs are stored.

udev_root="/dev/"

udev_rules="/etc/udev/rules.d/"

udev_log="err"

The rule file is stored in the directory specified by udev_rules, and the file name suffix is ​​.lures. There may be multiple rule files, and the matching sequence is performed by installing ASCII codes. If a matching rule is found, the matching is suspended and the subsequent rule files are not matched. Therefore, custom rule files basically start with numbers, which increases the priority of rule files. The following figure is a simple rule file. The rule file is in units of lines, and one line is a rule

KERNEL=="*", OWNER="root" GROUP="root", MODE="0600"
KERNEL=="tty", NAME="%k", GROUP="tty", MODE="0666", OPTIONS="last_rule"
KERNEL=="scd[0-9]*", SYMLINK+="cdrom cdrom-%k"
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", SYSFS{device/media}=="cdrom", SYMLINK+="cdrom cdrom-%k"
ACTION=="add", SUBSYSTEM=="scsi_device", RUN+="/sbin/modprobe sg"

In the rules file, rules are composed of a series of key-value pairs, which are separated by commas. Key-value pairs are divided into matching keys and assignment keys. The match key is used to specify the matching rule, and the assignment key is used for assignment. The assignment key can handle a multi-value list.

udev rule all operators

  • "==": Compare key and value, if equal, the condition is satisfied;
  • "! =": Compare key and value, if not equal, the condition is satisfied;
  • "=": Assign a value to a key;
  • "+ =": Assign a key to multiple entries.
  • ": =": Assign a value to a key and reject all subsequent changes to the key. The purpose is to prevent subsequent rule files from assigning values ​​to the key.

Match key for udev rules

  • ACTION : The behavior of the event (uevent), for example: add (add device), remove (remove device).
  • KERNEL : kernel device name, for example: sda, cdrom.
  • DEVPATH : The devpath of the device.
  • SUBSYSTEM : The subsystem name of the device, for example, the subsystem of sda is block.
  • BUS : The bus name of the device in the devpath, for example: usb.
  • DRIVER: The device driver name of the device in devpath, for example: ide-cdrom.
  • ID: The identification number of the device in the devpath.
  • SYSFS {filename} : Under the devpath of the device, the contents of the device's property file "filename". For example: SYSFS {model} == “ST936701SS” means: If the model of the device is ST936701SS, the device matches the matching key.
  • ENV {key} : environment variable. In a rule, you can set up to five matching keys for environment variables.
  • PROGRAM: Call external commands.
  • RESULT: The return result of the external command PROGRAM.

Udev's important assignment key

  • NAME: The device file name generated under / dev. Only the first assignment of a device's NAME takes effect, and the matching rules after that will be ignored for the device's NAME assignment. If there is no rule for assigning a name to the device, udev will use the kernel device name to generate the device file.
  • SYMLINK: Generate symbolic links for device files under / dev /. Since udev can only generate one device file for a certain device, it is recommended to use symbolic links in order not to overwrite the files generated by the system's default udev rules.
  • OWNER, GROUP, MODE: Set permissions for the device.
  • ENV {key}: import an environment variable.

udev value and callable replacement operator

  • $ kernel,% k: The kernel device name of the device, for example: sda, cdrom.
  • $ number,% n: The kernel number of the device, for example: the kernel number of sda3 is 3.
  • $ devpath,% p: The devpath path of the device.
  • $ id,% b: The ID number of the device in devpath.
  • $ sysfs {file},% s {file}: The content of the file in the sysfs of the device. In fact, it is the attribute value of the device.
  • $ env {key},% E {key}: The value of an environment variable.
  • $ major,% M: The major number of the device.
  • $ minor% m: The minor number of the device.
  • $ result,% c: The result returned by PROGRAM.
  • $ parent,% P: The device file name of the parent device.
  • $ root,% r: The value of udev_root, the default is / dev /.
  • $ tempnode,% N: Temporary device name.
  • %%: The symbol% ​​itself.
  • $$: The symbol $ itself.

The rule in the picture below is to produce the specified link name according to the IDvendor and IDproduct of the scanner. The link is fixed every time the scanner is turned on, so the mapping relationship can be well determined.

SYSFS{idVendor}=="0686",SYSFS{idProduct}=="400e", SYMLINK+="scanner", MODE="0664", group="scanner"

If the rules take effect after the rules are modified, we can plug and unplug our device to generate an event or add information in the event file in the device to update our udev rules for the purpose of sending events. A more convenient method is to run the following command

udevadm test /sys/class/block/sdc4
udevinfo -q path -n /dev/sda 这个命令会产生一个该设备名对应的在sysfs下的路径
udevinfo -a -p /sys/block/sda 这个命令会显示一堆信息,这些信息实际来自于操作系统维护的sysfs链表。

udev port

The udev source code can be downloaded from the udev download URL . The following are the migration steps.

  • Download the udev source package and unzip it
  • Modify the CROSS cross-compilation tool in the Makefile to the compiler of your own development board
  • Execute make to compile.
  • Then execute strip udev uded udevstart udevinfo udevtest. And copy these files to the rootfs / bin directory.
  • Add support for udev, modify the /etc/init.d/rcS script, and add the following command:
/bin/mount -t sysfs sysfs /sys
/bin/mount -t tmpfs tmpfs /dev
/bin/udevd --deamon
/bin/udevstart 
  • Create directory udev under / etc
  • Create rules.d and file udev.conf under / etc / udev. The contents of udev.conf are as follows:
    # udev.conf
    # The initial syslog(3) priority: 'err', 'info', 'debug' or its
    # numerical equivalent. For runtime debugging, the daemons internal
    # state can be changed with: 'udevcontrol log_priority='.
    udev_root="/dev/"
    udev_rules="/etc/udev/rules.d"
    udev_log="err"
  • Create your own rules file in the rules.d directory. The file must use the .rules suffix.
    Since udev needs sysfs support and tmpfs support, you need to mount these two directories before starting udev.
Published 35 original articles · Like1 · Visits 1870

Guess you like

Origin blog.csdn.net/lzj_linux188/article/details/105094697