Linux设备驱动之Hotplug_uevent机制

源码分析:

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);

                    /* 设置环境变量 */          Garmen:环境变量是什么?答:你在开发板输入env就可以看到了环境变量了
                    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;
                    /*Garmen:最终调用call_usermodehelper 这个函数*/
                    call_usermodehelper (argv[0], argv, envp, 0);

分析: busybox mdev.c

Garmen:应用程序会根据这些环境变量来创建设备节点

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"的内容确定主次设备号

        /*Garmen:调用mknod创建设备节点*/
        mknod(device_name, mode | type, makedev(major, minor)

问:我接上U盘,想自动挂载,怎么办?
答:写mdev.conf来自动挂载,就这么简单
mdev.conf的格式:

<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]

解析:

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

1、
GID为GroupId,即组ID,用来标识用户组的唯一标识符
UID为UserId,即用户ID,用来标识每个用户的唯一标示符
2、
正则表达式小解析:
①在电脑上查找文件:.c(“”表示通配符,任意字符的意思)
②更精确的话,用正则表达式:

“.”:表示人一直字符,()换行符除外)
“*”: 重复0次或者更多次
“+”:  重复1次或者更多次
“?”:重复0次或者1次
“[...]”   :表示这些...字符里面的某一个;例如[abc]表示abc字符里面的某一个字符

写mdev.conf
文件位置在:/etc/mdev.conf

1、

leds 0:0 777
led1 0:0 777
led2 0:0 777
led3 0:0 777

2、
leds?[123]? 0:0 777

3、

leds?[123]? 0:0 777 @ echo create /dev/$MDEV > /dev/console     //Garmen:/dev/$MDEV:环境变量

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 /mnt;
else
    umount /mnt;
fi

你可能感兴趣的:(linux)