热拔插驱动
- hotplug/uevent机制
hotplug内核框架
class_device_create
class_device_register
class_device_add
kobject_uevent
kobject_uevent_env(kobj, action, NULL)
// action_string = “add”
action_string = action_to_string(action)
/* 分配保存环境变量的内存 */
/* environment values */
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL)
/* 设置环境变量 */
scratch = buffer;
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 */
argv [0] = uevent_helper; = “mdev”
argv [1] = (char *)subsystem;
argv [2] = NULL;
call_usermodehelper (argv[0], argv, envp, 0);
- 过程总结:
上述的代码从
class_device_class
开始,创建一个设备节点,然后层层深入每个函数调用的关键函数,最终找到kobject_uevent
函数,根据传入的action,如add
命令,则分配环境变量所需要的内存,再设置环境变量,设置完毕之后,调用call_usermodehelper
,调用一个应用程序,这个应该程序会根据环境变量创建设备节点,这个外部函数一般设置为/sbin/mdev
mdev介绍
mdev是busybox中的一个udev管理程序的精简版本,它也可以自己创建设备节点和设备的自动挂载,只是mdev是被hotplug直接调用
mdev扫描/sys/class和/sys/block中所有的类设备目录,如果在目录中含有名为”dev”的文件,且文件中包含的是设备号,则mdev就利用这些信息为这个设备在/dev下创建设备节点为什么是/sbin/mdev?
启动脚本
cat /etc/init.d/rcS
:
echo /sbin/mdev > /proc/sys/kernel/hotplug
设置了uevent_helper 为“/sbin/mdev”.
如何实现自动挂载
如果想实现U盘的自动挂载
1 内核支持hotplug
2 需要编辑配置文件/etc/mdev.conf
,该文件的作用是在找到匹配设备时自动执行自定义命令mdev.conf的格式
<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]
device regex
正则表达式,表示哪一个设备uid
ownergid
组IDoctal permissions
以八进制表示的属性,默认660@
创建设备节点之后执行命令$
删除设备节点之前执行命令*
创建设备节点之后执行,删除设备节点之前执行命令command
要执行的命令
正则表达式
- 什么是正则表达式:
1 在电脑上查文件,.c : *是通配符,表示任意字符
2 更精确的查找,使用正则表达式
.
表示任意字符(换行符除外)
`表示重复0次或者更多次
+表示重复1次或者更多次
?表示重复0次或者1次
[ xxx ]表示这些字符里面的某一个,如
[abc]、
[1~9]`
写mdev.conf:(参考 busybox 的 mdev.txt )
1 实现led驱动在挂载时输出相关信息
1.1 原始的做法
vi /etc/mdev.conf
leds 0:0 777
led1 0:0 777
led2 0:0 777
led3 0:0 777
1.2 修改为
leds? [123]? 0:0 777
1.3 添加打印命令
leds? [123]? 0:0 777 * echo create /dev/$MDEV > /dev/console
1.4 改成输入输出打印不同的命令
leds? [123]? 0:0 777 * if [ $ACTION = “add”]; then echo create /dev/$MDEV > /dev/console;
else echo remove /dev/$MDEV > /dev/console;
1.5 把上面的命令写入一个脚本 add_remove_led.sh
#!/bin/sh
if [ $ACTION = “add”]
then
echo create /dev/$MDEV > /dev/console;
else
echo remove /dev/$MDEV > /dev/console;
fi
1.6 再修改/etc/mdev.conf文件
leds?[123]? 0:0 777 * /bin/add_remove_led.sh
2 设置U盘自动挂载
sda[1-9]+ 0:0 777 * if [$ACTION = “add”];then mount /dev/$MDEV /mnt;
else umount /mnt;
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!