热拔插驱动

  • 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 owner
gid 组ID
octal 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 协议 ,转载请注明出处!

call back机制 上一篇
DMA驱动 下一篇