• 34、uevent机制说明


    class_device_create(4.3.2内核是device_create->device_create_vargs->device_register->device_add->kobject_uevent下面的差不多一样)
      class_device_register
        class_device_add
          kobject_uevent(&class_dev->kobj, KOBJ_ADD);//4.3.2的内核KOBJ_ADD在kobject_actions数组中定义为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 */
              /* 启动脚本(/etc/init.d/rcS) echo /sbin/mdev > /proc/sys/kernel/hotplug //启动脚本中设置的mdev相关内容可以查看busybox中mdev.txt文档
              * 设置了uevent_helper为“/sbin/mdev“
              */
              
              argv [0] = uevent_helper; // = "/sbin/mdev"//通过在这里加打印环境变量可以打印出来,执行驱动安装指令可以看到调用的是mdev,启动的时候打印的有点乱
              argv [1] = (char *)subsystem;
              argv [2] = NULL;
              call_usermodehelper (argv[0], argv, envp, 0);//一步步分析进call_usermodehelper_exec函数里面的queue_work(khelper_wq, &sub_info->work),其将mdev这个用户空间进程挂到khelper_wq内核队列中等待执行,内核队列在start_kernel()中一步步调用到usermodehelper_init函数去创建

              

    insmod buttons.ko(执行)

    ACTION=add

    DEVPATH=/class/sixth_drv/buttons

    SUBSYSTEM=sixth_drv

    ....等环境变量.....

    分析: busybox mdev.c(mdev是busybox的一个指令)

    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//执行 /sbin/mdev 应用程序

      action=getenv(ACTION)//获得环境变量

      if(!strcmp(action,"add"))如果是add
      temp = /sys/class/sixth_drv/buttons//被赋值/sys+DEVPATH
      make_device(temp, 0);

        fd = open(/etc/mdev.conf)//如果有配置文件,会执行相关动作
        /* 确定设备文件名,类型,主次设备号 */path等于temp = /sys/class/sixth_drv/buttons
        device_name = bb_basename(path); = "buttons"
        type = path[5]=='C'?S_IFCHR:S_IFBLK;//字符设备或者块设备

        '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:正则表达式,表示哪一个设备(发现该设备会根据后面数据创建设备节点,通过在创建或者删除的时候执行命令)

    '.'表示任意字符(换行符除外)

    ‘*’重复0次或更多次

    ‘+’重复1次或更多次

    ‘?’重复0次或1次

    ‘[]’表示里面的字符里的某一个
    uid: owner
    gid: 组ID
    octal permissions:以八进制表示的属性,默认属性660
    @:创建设备节点之后执行命令
    $:删除设备节点之前执行命令
    *: 创建设备节点之后 和 删除设备节点之前 执行命令
    command:要执行的命令

    写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(s后面的?表示s出现0次或者1次)

    3.
    leds?[123]? 0:0 777 @ echo create /dev/$MDEV > /dev/console//指令仅把create /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

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

    cat /proc/mounts查看挂摘的设备

  • 相关阅读:
    MapBox TileMill
    优秀电影
    Mapnik 编译安装过程
    Debian 入门安装与配置2
    学习opengl十大网站(转载)
    PostgresSQL 学习资料记录处
    c++模板编程-异质链表
    Linux-统一事件源
    三组I/O复用模型的比较
    ZigZag-LeetCode
  • 原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/8858850.html
Copyright © 2020-2023  润新知