文章最后面我会附上medv.conf配置文档medv.txt,是英文的,部分朋友的英语不是很好,但还是希望大家要硬着头皮去读,不要有畏惧心理,相信你读完了后会给你带来很大的帮助。你要相信外文资料讲得很地道,翻译过来没有那种感觉,以上只是个人看法。

class_device_create

class_device_register
class_device_add
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
kobject_uevent_env(kobj, action, NULL);

// action_string = "add";
action_string = action_to_string(action);

/* 分配保存环境变量的内存 */
/* environment values */
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);

/* 设置环境变量 */
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;

/* 调用应用程序: 比如mdev */
/* 启动脚本 echo /sbin/mdev > /proc/sys/kernel/hotplug 
* 设置了uevent_helper为“/sbin/mdev“
*/

argv [0] = uevent_helper;  // = "/sbin/mdev"
argv [1] = (char *)subsystem;
argv [2] = NULL;
call_usermodehelper (argv[0], argv, envp, 0);

分析: busybox mdev.c

100ask: uevent_helper = /sbin/mdev
envp[0] = HOME=/
envp[1] = PATH=/sbin:/bin:/usr/sbin:/usr/bin
envp[2] = ACTION=add
envp[3] = DEVPATH=/class/sixth_drv/buttons
envp[4] = SUBSYSTEM=sixth_drv
envp[5] = SEQNUM=720
envp[6] = MAJOR=252
envp[7] = MINOR=0

mdev_main
temp = /sys/class/sixth_drv/buttons
make_device(temp, 0);
/* 确定设备文件名,类型,主次设备号 */
device_name = bb_basename(path);  = "buttons"

'c' == > 字符设备节点
根据"/sys/class/sixth_drv/buttons/dev"的内容确定主次设备号

mknod(device_name, mode | type, makedev(major, minor)

我接上U盘,想自动挂载,怎么办?
mdev.conf的格式:
<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]

device regex:正则表达式,表示哪一个设备
uid: owner
gid: 组ID
octal permissions:以八进制表示的属性
@:创建设备节点之后执行命令
$:删除设备节点之前执行命令
*: 创建设备节点之后 和 删除设备节点之前 执行命令
command:要执行的命令

写mdev.conf放在/etc/目下,sh脚本文件放在bin目录下,device regex用正则表达式
写相对方便一点,command可以写在脚本文件中,但是要注意sh脚本文件是可以执行的。

下面是几个例子:
1.
leds 0:0 777
led1 0:0 777
led2 0:0 777
led3 0:0 777
dma  0:0 777
2.
leds?[123]? 0:0 777

/*For your convenience, the shell env var $MDEV is set to the device name.  So if
the device "hdc" was matched, MDEV would be set to "hdc".*/
3.
leds?[123]? 0:0 777 @ echo create /dev/$MDEV > /dev/console

4.
leds?[123]? 0:0 777 * if [ $ACTION = "add" ]; then echo create /dev/$MDEV > /dev/console; else echo remove /dev/$MDEV > /dev/console; fi

5. 
leds?[123]? 0:0 777 * /bin/add_remove_led.sh

把命令写入一个脚本:
add_remove_led.sh

#!/bin/sh
if [ $ACTION = "add" ]; 
then 
echo create /dev/$MDEV > /dev/console; 
else 
echo remove /dev/$MDEV > /dev/console; 
fi

6. U盘自动加载
sda[1-9]+ 0:0 777 * if [ $ACTION = "add" ]; then mount /dev/$MDEV /mnt; else umount /mnt; fi

7.
sda[1-9]+ 0:0 777 * /bin/add_remove_udisk.sh

add_remove_udisk.sh
#!/bin/sh
if [ $ACTION = "add" ]; 
then 
mount /dev/$MDEV /tmp; 
else 
umount /tmp;

fi

mdev.txt

-------------
 MDEV Primer
-------------

For those of us who know how to use mdev, a primer might seem lame.  For
everyone else, mdev is a weird black box that they hear is awesome, but can't
seem to get their head around how it works.  Thus, a primer.

-----------
 Basic Use
-----------

Mdev has two primary uses: initial population and dynamic updates.  Both
require sysfs support in the kernel and have it mounted at /sys.  For dynamic
updates, you also need to have hotplugging enabled in your kernel.

Here's a typical code snippet from the init script:
[0] mount -t proc proc /proc
[1] mount -t sysfs sysfs /sys
[2] echo /sbin/mdev > /proc/sys/kernel/hotplug
[3] mdev -s

Alternatively, without procfs the above becomes:
[1] mount -t sysfs sysfs /sys
[2] sysctl -w kernel.hotplug=/sbin/mdev
[3] mdev -s

Of course, a more "full" setup would entail executing this before the previous
code snippet:
[4] mount -t tmpfs -o size=64k,mode=0755 tmpfs /dev
[5] mkdir /dev/pts
[6] mount -t devpts devpts /dev/pts

The simple explanation here is that [1] you need to have /sys mounted before
executing mdev.  Then you [2] instruct the kernel to execute /sbin/mdev whenever
a device is added or removed so that the device node can be created or
destroyed.  Then you [3] seed /dev with all the device nodes that were created
while the system was booting.

For the "full" setup, you want to [4] make sure /dev is a tmpfs filesystem
(assuming you're running out of flash).  Then you want to [5] create the
/dev/pts mount point and finally [6] mount the devpts filesystem on it.

-------------
 MDEV Config   (/etc/mdev.conf)
-------------

Mdev has an optional config file for controlling ownership/permissions of
device nodes if your system needs something more than the default root/root
660 permissions.

The file has the format:
    <device regex>       <uid>:<gid> <permissions>
 or @<maj[,min1[-min2]]> <uid>:<gid> <permissions>

For example:
    hd[a-z][0-9]* 0:3 660

The config file parsing stops at the first matching line.  If no line is
matched, then the default of 0:0 660 is used.  To set your own default, simply
create your own total match like so:
.* 1:1 777

You can rename/move device nodes by using the next optional field.
<device regex> <uid>:<gid> <permissions> [=path]
So if you want to place the device node into a subdirectory, make sure the path
has a trailing /.  If you want to rename the device node, just place the name.
hda 0:3 660 =drives/
This will move "hda" into the drives/ subdirectory.
hdb 0:3 660 =cdrom
This will rename "hdb" to "cdrom".

Similarly, ">path" renames/moves the device but it also creates
a direct symlink /dev/DEVNAME to the renamed/moved device.

You can also prevent creation of device nodes with the 4th field as "!":
tty[a-z]. 0:0 660 !
pty[a-z]. 0:0 660 !

If you also enable support for executing your own commands, then the file has
the format:
<device regex> <uid>:<gid> <permissions> [=path] [@|$|*<command>]
    or
<device regex> <uid>:<gid> <permissions> [>path] [@|$|*<command>]
    or
<device regex> <uid>:<gid> <permissions> [!] [@|$|*<command>]

For example:
---8<---
# block devices
([hs]d[a-z]) root:disk660>disk/%1/0
([hs]d[a-z])([0-9]+) root:disk660>disk/%1/%2
mmcblk([0-9]+) root:disk660>disk/mmc/%1/0
mmcblk([0-9]+)p([0-9]+) root:disk660>disk/mmc/%1/%2
# network devices
(tun|tap) root:network660>net/%1
---8<---

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.

The command is executed via the system() function (which means you're giving a
command to the shell), so make sure you have a shell installed at /bin/sh.  You
should also keep in mind that the kernel executes hotplug helpers with stdin,
stdout, and stderr connected to /dev/null.

For your convenience, the shell env var $MDEV is set to the device name.  So if
the device "hdc" was matched, MDEV would be set to "hdc".

----------
 FIRMWARE
----------

Some kernel device drivers need to request firmware at runtime in order to
properly initialize a device.  Place all such firmware files into the
/lib/firmware/ directory.  At runtime, the kernel will invoke mdev with the
filename of the firmware which mdev will load out of /lib/firmware/ and into
the kernel via the sysfs interface.  The exact filename is hardcoded in the
kernel, so look there if you need to know how to name the file in userspace.

------------
 SEQUENCING
------------

Kernel does not serialize hotplug events. It increments SEQNUM environmental
variable for each successive hotplug invocation. Normally, mdev doesn't care.
This may reorder hotplug and hot-unplug events, with typical symptoms of
device nodes sometimes not created as expected.

However, if /dev/mdev.seq file is found, mdev will compare its
contents with SEQNUM. It will retry up to two seconds, waiting for them
to match. If they match exactly (not even trailing '\n' is allowed),
or if two seconds pass, mdev runs as usual, then it rewrites /dev/mdev.seq
with SEQNUM+1.

IOW: this will serialize concurrent mdev invocations.

If you want to activate this feature, execute "echo >/dev/mdev.seq" prior to
setting mdev to be the hotplug handler. This writes single '\n' to the file.
NB: mdev recognizes /dev/mdev.seq consisting of single '\n' character
as a special case. IOW: this will not make your first hotplug event
to stall for two seconds.

Linux系统之热插拨事件uevent相关推荐

  1. Linux系统双机热备的方案

    目前,双机和集群采用的操作系统主要有UNIX.Linux.BSD及微软公司的Windows NT/2000.随着Linux的迅速发展,稳定性.安全性及功能的不断增强,人们对Linux的使用越来越广泛, ...

  2. 一次Linux系统密码修改失败事件

    一.事件描述   某业务系统采用移动云主机,某次因误操作导致移动云内嵌密码管理相关Pga进程导致页面无法修改密码,东移动云主机web终端登录也无法修改,密码错误次数最大已无法登录,无奈只能重启主机,修 ...

  3. linux双机热备方案,Hadoop HDFS系统双机热备方案 PDF

    1. 前言 HDFS包含两种角色:数据节点(datanode)和名字节点(namenode),名字节点只有一个,数据节点最多支持2000个.HDFS可以确保在硬件失效情况下数据存储的可靠性.常见的三种 ...

  4. 1. Linux系统简介

    目录 1.1 操作系统是什么 1.2 Linux是什么,有哪些特点? 1.3 Linux和UNIX的关系及区别 UNIX 的坎坷历史 Linux 的那些往事 UNIX与Linux的亲密关系 UNIX/ ...

  5. Linux系统中内核态、用户态和零拷贝技术解析

    ​目录 ​第一:存储介质的性能 ​第二:内核态和用户态 第三:内核态和用户态是怎么控制数据传输的? ​第四:什么是 DMA ? ​第五:零拷贝技术实现的方式 第六:mmap + write 第七:se ...

  6. Linux设备模型(四) uevent

    热插拔事件:在linux系统中,当系统配置发生变化时,如添加kset到系统或移动kobject,一个通知会从内核空间发送到用户空间,这就是热插拔事件. 热插拔事件的产生通常是由在总线驱动程序层的逻辑所 ...

  7. Linux系统固定USB串口设备名称

    概述 Linux系统下使用多个USB转串口设备或一个USB设备拥有多个串口时,经常会遇到多个串口对应的设备名称无法区分的问题.Linux系统下的串口名称分配和硬件的上电顺序有关,如果是开机启动或者接在 ...

  8. 远程管理linux系统工具,远程管理Linux系统工具的设计与实现Linux013

    一种远程管理Linux系统工具的设计与实现 摘  要 现在,Linux已经是应用比较广泛的操作系统之一,在其系统中有很多的服务.为了实现远程配置和管理Linux中的各种服务,需要有一种远程管理Linu ...

  9. linux系统发送信号的系统调用是,linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction...

    信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...

最新文章

  1. usaco The Tamworth Two 两只塔姆沃斯牛
  2. OKR是什么?-源目标OKR
  3. ubuntu 图形化更换apt源
  4. 微型计算机原理答案第四章,微机原理第四章习题答案.doc
  5. (75)内核APC执行过程,分析 KiDeliverApc 函数
  6. error: expected ‘{‘ before ‘;‘ token
  7. java 多线程下载文件并实时计算下载百分比(断点续传)
  8. Android之滑动事件冲突解决 Touch事件处理机制总结
  9. EAGER的获取是代码的味道
  10. 小米笔记本写代码真香,包邮送一台!
  11. 《基于MFC的OpenGL编程》Part 14 Quadrics
  12. SharpHsql -- 只适合用于演示数据的数据库引擎
  13. angular源码分析之platformBrowserDynamic
  14. cmi码型变换matlab程序_58 张图,手把手教会你 Simscape Multibody 物理建模与刚体变换!...
  15. Qt实现 QQ好友列表QToolBox
  16. Docker 入门教程
  17. Excel图表制作(一):商务图表之加最大值和最小值标签的基本图
  18. vue图片时间轴滑动_在vue2.0 中制作时间轴拖动组件
  19. Android 蓝牙知识
  20. 成都瀚网科技:抖音发作品到底需要多久的时间才能够给流量呢?

热门文章

  1. abap 在屏幕如何调用选择屏幕以及如何获得选择屏幕的操作
  2. yolov5_trt_web检索衣服图案
  3. Tableau创建计算字段
  4. 物联卡套餐该如何选择
  5. 快手的未来,没有宿华
  6. 全文检索语句中的AND和OR的用法
  7. UNIX发展史(BSD,GNU,linux)(转)
  8. ANACONDA下载opencv,py-opencv,libopencv的区别
  9. django搭建个人博客(一)
  10. 如何用 Node.js 爬虫?