device_create()-
>device_register()
->device_add()
函数如下所示:
int class_device_add(struct class_device *class_dev)
{
... ... kobject_uevent(&class_dev->kobj, KOBJ_ADD);
// KOBJ_ADD是一个枚举值
//调用了kobject_uevent_env(kobj, action, NULL);
// action=KOBJ_ADD
}
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,char *envp_ext[])
{
char **envp;
char *buffer;
char *scratch;
int i = 0;
... ...
/* 通过KOBJ_ADD获取字符串"add",所以action_string="add" */
action_string = action_to_string(action); // action=KOBJ_ADD
/* environment index */
envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL); //分配一个环境变量索引值
/* environment values */
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL); //分配一个环境变量缓冲值
/* event environemnt for helper process only */
/*设置环境变量*/
envp[i++] = "HOME=/";
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
scratch = buffer;
envp [i++] = scratch;
scratch += sprintf(scratch, "ACTION=%s", action_string) + 1; //"ACTION= add"
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
envp [i++] = scratch;
scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
... ...
/*调用应用程序,比如mdev*/
if (uevent_helper[0]) {
char *argv [3];
argv [0] = uevent_helper; // uevent_helper[]= "/sbin/hotplug";
argv [1] = (char *)subsystem;
argv [2] = NULL;
call_usermodehelper (argv[0], argv, envp, 0); //调用应用程序,根据传入的环境变量参数来创建设备节点
}
}
class_device: argv[0]=/sbin/mdev //调用mdev class_device: argv[1]=sixth_dev //类名 class_device: envp[0]=HOME=/ class_device: envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin class_device: envp[2]=ACTION=add //add:表示添加设备节点, 若=remove:表示卸载设备节点 class_device: envp[3]=DEVPATH=/class/sixth_dev/buttons //设备的路径 class_device: envp[4]=SUBSYSTEM=sixth_dev //类名 class_device: envp[5]=SEQNUM=745 class_device: envp[6]=MAJOR=252 //主设备号 class_device: envp[7]=MINOR=0
int mdev_main(int argc, char **argv)
{
... ...
action = getenv("ACTION"); //获取传进来的执行参数,它等于“add”,则表示创建设备节点
env_path = getenv("DEVPATH"); //获取设备的路径“/class/sixth_dev/buttons”
sprintf(temp, "/sys%s", env_path); //指定temp (真正设备路径)为“/sys/class/sixth_dev/buttons”
if (!strcmp(action, "remove")) //卸载设备节点
make_device(temp, 1);
else if (!strcmp(action, "add")) { //创建设备节点
make_device(temp, 0);
... ...
}
static void make_device(char *path, int delete) //delete=0:创建, delete=1:卸载
{
/*判断创建的设备节点是否是有效的设备*/
if (!delete) {
strcat(path, "/dev");
len = open_read_close(path, temp + 1, 64);
*temp++ = 0;
if (len < 1) return;
}
device_name = bb_basename(path); //通过设备路径,来获取要创建/卸载的设备节点名称
//例: path =“/sys /class/sixth_dev/buttons”,那么device_name=“buttons”
type = path[5]=='c' ? S_IFCHR : S_IFBLK; //判断如果是在/sys/class/目录下,那么就是字符设备
//因为块设备,是存在/sys/block/目录下的
/* 如果配置了支持mdev.conf选项,那么就解析里边内容并执行 */
if (ENABLE_FEATURE_MDEV_CONF) {
/* mmap the config file */
fd = open("/etc/mdev.conf", O_RDONLY); //调用/etc/mdev.conf配置文件
... ... //开始操作 mdev.conf配置文件
}
if (!delete) { //如果是创建设备节点
if (sscanf(temp, "%d:%d", &major, &minor) != 2) return; //获取主次设备号
/*调用mknod ()创建字符设备节点*/
if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST)
bb_perror_msg_and_die("mknod %s", device_name);
if (major == root_major && minor == root_minor)
symlink(device_name, "root");
/*若配置了支持mdev.conf选项,则调用chown命令来改变属主,默认uid和gid=0 */
if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid);
}
if (delete) unlink(device_name); //如果是卸载设备节点
}
<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有