Chinaunix首页 | 论坛 | 博客

分类: LINUX

2012-11-22 13:40:29

    当我们使用 cdev_add() 或 register_chrdev() 创建字符设备时,该字符设备并不会存在于 sys 文件系统的设备树中,最多只会在 /sys/module 目录下记录该设备的存在与否。而在用户空间如果我们想使用 mknod 创建该设备的节点时,通常我们会先使用 cat /proc/devices 命令查看该设备的主次设备号。这种做法显然有一个重要的弊端:当系统的设备比较多时,手动使用 mknod 去创建设备节点显得十分低效,而且容易出错。
    mdev 是运行在用户空间的进程,它会根据 sys 文件系统下的信息,自动创建设备节点。前提很明确,设备必须在 sys 文件系统下留有信息,通常在驱动中使用下面两条语句来实现:
    cls = class_create(THIS_MODULE,"xxx");
    device_create(cls, NULL, MKDEV(major,0), NULL, "yyy");

   
1.class_create 在 sys 下创建类目录 /sys/class/xxx;
2.device_create 在 sys 下创建设备目录 /sys/device/yyy,如果它所属的类不为空,创建 /sys/class/xxx/yyy 到 /sys/device/yyy 的链接;
3.设置环境变量,调用用户空间的 mdev 应用程序。

mdev 创建设备节点过程分析(基于busybox1.7.0):
mdev_main
    action = getenv("ACTION");  //action = "add"
    env_path = getenv("DEVPATH");  //env_path = "/class/xxx/yyy"
    sprintf(temp, "/sys%s", env_path);  //temp = "/sys/class/xxx/yyy"
    make_device(temp, 0);  //make_device(char *path, int delete)
        char *temp = path + strlen(path);  //temp指向path的末尾
        strcat(path, "/dev");  //path = /sys/class/xxx/yyy/dev
        len = open_read_close(path, temp + 1, 64);  //假设主次设备号为"252:0",则 temp = "/252:0"
        *temp++ = 0;  //path = /sys/class/xxx/yyy + "\0" + "252:0"; temp = "252:0"
        
        device_name = bb_basename(path);  //device_name = "yyy"
        type = path[5]=='c' ? S_IFCHR : S_IFBLK;
        
        sscanf(temp, "%d:%d", &major, &minor);  //读取主次设备号   
        mknod(device_name, mode | type, makedev(major, minor));//创建节点


                       ——忠于梦想 勇于实践    linux_xpj@opencores.org

阅读(2334) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~