zoukankan      html  css  js  c++  java
  • 23、uevent/hotplug热拔插机制

     (class_device_create的目的是为了让mdev根据它注册的信息来创建设备节点)

    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_string = action_to_string(action);//kobject_uevent函数的第二个参数就是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参数和环境变量的值,如下面100ask开头的这行
              argv [1] = (char *)subsystem;
              argv [2] = NULL;
              call_usermodehelper (argv[0], argv, envp, 0);//调用应用程序argv[0],并传入envp环境变量

    分析: 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' == > 字符设备节点

        type = path[5]=='c'?S_IFCHR:S_IFBLK;//path=/sys/class/sixth_drv/buttons
        

        根据"/sys/class/sixth_drv/buttons/dev"的内容确定主次设备号(class下面都是字符设备)
        (sscanf(temp,"%d:%d",&major,&minor))


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

    在/etc/init.d/rcS(启动脚本)中有一句

    echo  /sbin/mdev  >  /proc/sys/kernel/hotplug

    这句设置了设置了uevent_helper为“/sbin/mdev

    mdev的主函数在运行的时候,如果有/etc/mdev.conf这个文件就会根据文件里的内容做某些事情

    我接上U盘,想自动挂载,怎么办?(查看内核中mdev.txt文档)
    mdev.conf的格式:
    <device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]

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

    写mdev.conf
    1.
    leds 0:0 777(表示在有leds设备节点的时候设置组属性是777,默认的属性是660)
    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

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

    ($MDEV表示执行命令时的设备节点)

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

    把命令写入一个脚本:(chmod +x /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

  • 相关阅读:
    Windows下的SASS环境搭建
    cocos开发环境搭建
    cocos2d-x中描述精灵帧图片的plist和json文件各个key的含义
    seajs模块路径解析 简单总结
    【LESS系列】内置函数说明
    Zepto自定义模块打包构建
    【LESS系列】高级特性
    【LESS系列】三角形Mixins
    关于delete和对象复制
    vue使用技巧
  • 原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/8667089.html
Copyright © 2011-2022 走看看