当我们使用 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) |