• hotpluguevent机制(1)


    hotplug就是热拔插,在linux里面,这个功能是通过class_device_create这个函数来实现的,那么我们来分析下这个函数:

    class_device_create(cls, NULL, MKDEV(major, 0), NULL, "dma"); /* /dev/dma */
              class_device_register(class_dev);
                        class_device_add(class_dev);
                                  kobject_uevent(&class_dev->kobj, KOBJ_ADD);
                                           kobject_uevent_env(kobj, action, NULL);
                                                    action_string = action_to_string(action);
                                                    /* 分配保存环境变量的内存 */
                                                    envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
                                                    /* 设置环境变量 */
                                                    envp[i++] = "HOME=/";
                                                    scratch = buffer;
                                                    envp [i++] = scratch;
                                                     .................................
                                                     /* 可以加打印语句将下面的变量打印出来,详见注释1 */
                                                    char *argv [3];
                                                    argv [0] = uevent_helper;
                                                    argv [1] = (char *)subsystem;
                                                    argv [2] = NULL;
                                                    call_usermodehelper (argv[0], argv, envp, 0);  
                                                           /* 开启一个用户模式下的应用程序,其中path为应用程序的路径 */
                                                            call_usermodehelper_keys(path, argv, envp, NULL, wait);
                                                                      
     
    注释1:
    if (uevent_helper[0]) {
    char *argv [3];
                  /* 蓝色字体是我们加进去的打印语句 */
                  printk("100ask:uevent_helper=%s ",uevent_helper);
                  for(i=0;envp[i];i++)
                    {
                        printk("envp[%d]=%s ",i,envp[i]);
                    }
     
    argv [0] = uevent_helper;
    argv [1] = (char *)subsystem;
    argv [2] = NULL;
    call_usermodehelper (argv[0], argv, envp, 0);
    }
    在内核中加入如上的打印语句之后,重新编译内核:make uImage
    然后用新内核启动,会看到很多打印环境变量的信息。
    我们选择一个包含函数:class_device_create的驱动程序,加载后打印如下信息:
    100ask:uevent_helper=/sbin/mdev     //我们看到uevent_helper是mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add                        //ACTION=add,记住它
    envp[3]=DEVPATH=/module/third_drv
    envp[4]=SUBSYSTEM=module
    envp[5]=SEQNUM=716
    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/third_drv/buttons
    envp[4]=SUBSYSTEM=third_drv
    envp[5]=SEQNUM=717
    envp[6]=MAJOR=252                   //主设备号
    envp[7]=MINOR=0                       //次设备号
     
    于是我们知道call_usermodehelper 将会开启应用程序mdev,那么我们猜测mdev就根据主次设备号等环境变量来创建设备节点!
    其实uevent_helper=mdev是在/etc/init.d/rcS里面的设置的,因为有这么一句:
    echo /sbin/mdev > /proc/sys/kernel/hotplug
     
    那么mdev到底做了什么呢?我们来看一下:busybox mdev.c  这个文件:
    sprintf(temp, "/sys%s", env_path);//temp=/sys/class/third_drv/buttons,详见注释2
    make_device(temp, 0);
              strcat(path, "/dev");//temp=/sys/class/third_drv/buttons/dev,这个dev文件里面放的就是主次设备号
              /* 确定设备名,类型,主次设备号 */
             device_name = bb_basename(path);          //确定设备名
             type = path[5]=='c' ? S_IFCHR : S_IFBLK; //获得类型
             sscanf(temp, "%d:%d", &major, &minor);  //扫描主次设备号
             mknod(device_name, mode | type, makedev(major, minor)) //根据设备名,主次设备号以及类型来创建设备节点
     
    注释2:
    DEVPATH=/class/third_drv/buttons
    env_path = getenv("DEVPATH");
    sprintf(temp, "/sys%s", env_path);
    于是乎:temp=/sys/class/third_drv/buttons
  • 相关阅读:
    C#解析Json数据(利用Newtonsoft.Json库)
    巧妙解决百度地图加偏纠偏问题
    sql 日期时间函数+格式转换
    遇到sql server 遇到以零作除数错误
    js实现鼠标移到链接文字弹出一个提示层的方法
    sql语句 如何判断A表中的a列数据是否在B表中的b列中存在
    MVC使用Gantt Chart实现甘特图,管理事情进度
    jQueryGantt—集变态与惊艳于一身
    自动化测试
    小程序测试及一些限制
  • 原文地址:https://www.cnblogs.com/0822vaj/p/3500288.html
Copyright © 2020-2023  润新知