zoukankan      html  css  js  c++  java
  • hotplug/mdev机制


    title: hotplug/mdev机制
    date: 2019/1/9 19:35:14
    toc: true

    hotplug/mdev机制

    框架

    我们以前创建设备的时候,使用class_create来自动创建设备,是利用了mdev根据我们的提供的信息来创建设备节点

    kobject_uevent_env

    我们使用drv_class_dev来创建设备,具体的实例如下

    drv_class = class_create(THIS_MODULE, "drv");
    drv_class_dev = class_device_create(drv_class, NULL, MKDEV(major, 0), NULL, "xyz%d", minor);
    

    继续分析class_device_create,可以看到最后调用kobject_uevent_env来调用我们自己设置的辅助函数uevent_helper,可以在内核加入打印函数打印这个变量

    drv_class = class_create(THIS_MODULE, "drv");
    drv_class_dev = class_device_create(drv_class, NULL, MKDEV(major, 0), NULL, "xyz%d", minor);
    					class_device_register(class_dev);
    							class_device_initialize(class_dev);
    							class_device_add(class_dev);
    								//KOBJ_ADD	= (__force kobject_action_t) 0x01,	/* exclusive to core */
    								sysfs_create_link(&class_dev->kobj,&class_dev->dev->kobj, "device");
    								kobject_uevent(&class_dev->kobj, KOBJ_ADD);
    
    								// 设置环境变量后调用辅助函数
    								kobject_uevent_env(kobj, action, NULL)
    								{
    											action_string = action_to_string(action); //return "add";
    											/* environment index */
    											envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
    											/* environment values */
    											buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
    											/* complete object path */
    											devpath = kobject_get_path(kobj, GFP_KERNEL);
    
    											/* event environemnt for helper process only */
    											envp[i++] = "HOME=/";
    											envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
    											// 先将指针scratch指向分配到的buffer
    											// 再赋值到envp 环境变量中
    											/* default keys */
    											scratch = buffer;
    											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;
    											for (j = 0; envp_ext && envp_ext[j]; j++)
    												envp[i++] = envp_ext[j];
    											...
    
    											//我们自己在这里加入打印函数,查看下环境变量和uevent_helper
    											printk("userhelp=%s
    ",uevent_helper);
    											for (i=0;envp[i];i++) {
    												printk("envp[%d]=%s
    ",i,envp[i]);
    											}
    											printk("argv[1]=%s
    ",subsystem);
    
    											// 辅助函数,也就是我们自动创建设备的mdev
    											/* call uevent_helper, usually only enabled during early boot */
    											if (uevent_helper[0]) {
    												char *argv [3];
    
    												argv [0] = uevent_helper;
    												argv [1] = (char *)subsystem;
    												argv [2] = NULL;
    												call_usermodehelper (argv[0], argv, envp, 0);
    											}
    								}
    

    启动后加载一个驱动,打印如下,起始启动内核的时候也有许多的打印,userhelp=/sbin/hotplug

    // filename =dri_src.c
    major=register_chrdev(0, "drv_register", &drv_fops); // 注册, 告诉内核
    drv_class = class_create(THIS_MODULE, "drv_class");
    drv_class_dev = class_device_create(drv_class, NULL, MKDEV(major, 0), NULL, "xyz%d", minor);
    

    可以看到个信息包含了主次设备号,文件路径,模块的名字等,这里注意一下,当你修改了一个模块 a.ko 为 b.ko ,加载b.ko 后使用lsmod显示的依然是 a 模块,这里的信息也是 a 模块的
    这里的argv[1]其实就是envp[4]也就是类名

    # insmod dri_src.ko
    
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/module/dri_src						#模块名,一般就是文件名,但这个文件名指的是当时编译好的名字,也就是C文件的名字,生成ko后修改名字无效												
    envp[4]=SUBSYSTEM=module
    envp[5]=SEQNUM=754
    argv[1]=module
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/class/drv_class/xyz0				#设备文件的描述,最终会生成文件  /dev/xyz0
    													#输入子系统这里是 envp[3]=DEVPATH=/class/input/input1/event1
    envp[4]=SUBSYSTEM=drv_class							#类的名字 class_create创建,如果是输入子系统这里是
    													# envp[4]=SUBSYSTEM=input
    envp[5]=SEQNUM=755
    envp[6]=MAJOR=252
    envp[7]=MINOR=0
    argv[1]=drv_class									#就是类名
    
    
    
    # rmmod dri_src										#卸载模块的时候使用ACTION=remove
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=remove
    envp[3]=DEVPATH=/class/drv_class/xyz0
    envp[4]=SUBSYSTEM=drv_class
    envp[5]=SEQNUM=756
    envp[6]=MAJOR=252
    envp[7]=MINOR=0
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=remove
    envp[3]=DEVPATH=/class/drv_class
    envp[4]=SUBSYSTEM=class
    envp[5]=SEQNUM=757
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=remove
    envp[3]=DEVPATH=/module/dri_src
    envp[4]=SUBSYSTEM=module
    envp[5]=SEQNUM=758
    
    

    mdev_main

    接下来就去执行函数/sbin/mdev,也就是busybox的应用程序,定义在busybox-1.7.0util-linuxmdev.c
    匹配后执行make_device(temp, 0);,getenv是个库函数,我们之前在kobject_uevent_env设置了参数

    mdev_main(int argc, char **argv)
    	//扫描模式,一般是上电用的
    	scan 
    	//我们自己实际用的
    	action = getenv("ACTION");
    	env_path = getenv("DEVPATH");
    
    	sprintf(temp, "/sys%s", env_path);
    	if (!strcmp(action, "remove"))
    		make_device(temp, 1);
    	else if (!strcmp(action, "add")) {
    		make_device(temp, 0);
    
    

    make_device

    kernel 传递的DEVPATHenvp[3]=DEVPATH=/class/drv_class/xyz0,也就是参数实际是/sys/class/drv_class/xyz0

    1. 先判断是否已经有设备文件被创建了,也就是去 /sys/class/drv_class/xyz0/dev是否存在 这个文件包含了主次设备号
    // 先判断是否设备文件已经存在,也就是判断  /sys/class/drv_class/xyz0/dev是否存在 这个文件包含了主次设备号
    //# cat /sys/class/drv_class/xyz0/dev
    //252:0
    // strcat 拼接字符串
    
    	if (!delete) {
    		strcat(path, "/dev");
    		len = open_read_close(path, temp + 1, 64);
    		*temp++ = 0;
    		if (len < 1) return;
    	}
    
    1. 然后判断设备类型,就去读取到classc字符,就判断是字符设备了
    	/// sys/class/drv_class/xyz0 
    	device_name = bb_basename(path);
    				  //bb_basename 从前往后找到最后一个"/",这里就是找到文件名
    	type = path[5]=='c' ? S_IFCHR : S_IFBLK;
    
    1. 如果有配置文件,根据配置文件读取
    	if (ENABLE_FEATURE_MDEV_CONF)
    	{
    		fd = open("/etc/mdev.conf", O_RDONLY);
    	}
    
    1. 创建实际的设备节点,如果有配置文件,还需要手动更改设备文件属性
    	if (!delete) {
    		// 从设备文件的描述读取主次设备号 /sys/class/drv_class/xyz0/dev
    		if (sscanf(temp, "%d:%d", &major, &minor) != 2) return;
    		// mknod 创建设备文件  type=c 就是字符设备  makedev 包含了主次设备号
    		if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST)
    
    		if (major == root_major && minor == root_minor)
    			symlink(device_name, "root");
    
    		// 如果有配置文件,还需要手动更改设备文件属性
    		if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid);
    	}
    
    1. 所以我们如果需要使用配置文件自动创建设备文件,则需要使能ENABLE_FEATURE_MDEV_CONF,在make menuconfig 搜索mdev,可以看到已经启用了
    │     -> Linux System Utilities                                                          │
    │       -> mdev (MDEV [=y])                                                              │
    │         -> Support /etc/mdev.conf (FEATURE_MDEV_CONF [=y])   
    

    mdev.conf

    如何使用这个配置文件去自动创建设备文件? 我们搜索文档busybox-1.7.0/docs/mdev.txt查看如下格式,也就是发现设备文件(前/后)来执行命令

    The file has the format:
    	<device regex> <uid>:<gid> <octal permissions>
    
    For example:
    	hd[a-z][0-9]* 0:3 660
    
    	<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]
    The special characters have the meaning:
    	@ Run after creating the device.
    	$ Run before removing the device.
    	* Run both after creating and before removing the device.
    
    
    	device regex:正则表达式,表示哪一个设备
    	uid: owner
    	gid: 组ID
    	octal permissions:以八进制表示的属性
    						 用户组 读写执行+读写执行+读写执行  110+110+000=660=crwcrw---
    	   @:创建设备节点之后执行命令
    	   $:删除设备节点之前执行命令
    	  *: 创建设备节点之后 和 删除设备节点之前 执行命令
    	command:要执行的命令
    

    配置文件学习

    存在这样一个驱动,自动创建4个设备文件,代码仓库的4th

    for (minor = 0; minor < 4; minor++)
    {
        firstdrv_class_dev[minor] = class_device_create(firstdrv_class, NULL, MKDEV(major, minor), NULL, "xyz%d", minor);
    }
    

    自动创建设备如下

    # ls /dev/xyz* -l
    crw-rw----    1 0        0        252,   0 Jan  4 07:13 /dev/xyz0
    crw-rw----    1 0        0        252,   1 Jan  4 07:13 /dev/xyz1
    crw-rw----    1 0        0        252,   2 Jan  4 07:13 /dev/xyz2
    crw-rw----    1 0        0        252,   3 Jan  4 07:13 /dev/xyz3
    

    更改属性

    使用字符全匹配,更改权限为777,先卸载驱动

    # vi /etc/mdev.conf
    xyz0 0:0 777
    xyz1 0:0 777
    xyz2 0:0 777
    
    # ls /dev/xyz* -l
    crwxrwxrwx    1 0        0        252,   0 Jan  4 07:21 /dev/xyz0
    crwxrwxrwx    1 0        0        252,   1 Jan  4 07:21 /dev/xyz1
    crwxrwxrwx    1 0        0        252,   2 Jan  4 07:21 /dev/xyz2
    crw-rw----    1 0        0        252,   3 Jan  4 07:21 /dev/xyz3
    

    使用正则匹配

    # vi /etc/mdev.conf
    xyz[0123]?  0:0 777
    
    # ls /dev/xyz* -l
    crwxrwxrwx    1 0        0        252,   0 Jan  4 07:25 /dev/xyz0
    crwxrwxrwx    1 0        0        252,   1 Jan  4 07:25 /dev/xyz1
    crwxrwxrwx    1 0        0        252,   2 Jan  4 07:25 /dev/xyz2
    crwxrwxrwx    1 0        0        252,   3 Jan  4 07:25 /dev/xyz3
    
    

    @:创建设备节点之后执行命令

    这里使用@表示在创建设备节点后执行命令

    # vi /etc/mdev.conf
    xyz[0123]?  0:0 777 @ echo create /dev/$MDEV > /dev/console
    
    insmod dri.ko 
    # create /dev/xyz2
    create /dev/xyz3
    create /dev/xyz0
    create /dev/xyz1
    

    $:删除设备节点之前执行命令

    # vi /etc/mdev.conf
    xyz[0123]?  0:0 777 $ echo del /dev/$MDEV > /dev/console
    
    insmod dri.ko 
    # del /dev/xyz2
    del /dev/xyz3
    del /dev/xyz0
    del /dev/xyz1
    

    *: 创建之后 和 删除之前

    注意$ACTION前有个空格,不能少

    # cat /etc/mdev.conf
    xyz[0123]?  0:0 777 * if [ $ACTION = "add" ];then  echo create /dev/$MDEV > /dev/console; else echo del /dev/$MDEV > dev/console ;fi
    
    #insmod dri_4th.ko
    # create /dev/xyz2
    create /dev/xyz3
    create /dev/xyz0
    create /dev/xyz1
    
    #rmmod dri
    del /dev/xyz1
    del /dev/xyz0
    del /dev/xyz2
    del /dev/xyz3
    

    使用脚本

    创建一个脚本文件mdev.sh,放到一个指定的目录,加入执行权限hmod +x /mnt/mdev.sh

    #!/bin/sh
    if [ $ACTION = "add" ]; 
    then 
    	echo create /dev/$MDEV > /dev/console; 
    else 
    	echo remove /dev/$MDEV > /dev/console; 
    fi
    

    修改配置文件

    # chmod +x /mnt/mdev.sh
    # cat /etc/mdev.conf
    xyz[0123]?  0:0 777 * /mnt/mdev.sh
    

    然后会和上面同样的结果

    U盘自动挂载

    u盘插入

    usb 1-1: new full speed USB device using s3c2410-ohci and address 3
    usb 1-1: configuration #1 chosen from 1 choice
    scsi1 : SCSI emulation for USB Mass Storage devices
    sd 1:0:0:0: [sda] 60555264 512-byte hardware sectors (31004 MB)
    sd 1:0:0:0: [sda] Write Protect is off
    sd 1:0:0:0: [sda] Assuming drive cache: write through
    sd 1:0:0:0: [sda] 60555264 512-byte hardware sectors (31004 MB)
    sd 1:0:0:0: [sda] Write Protect is off
    sd 1:0:0:0: [sda] Assuming drive cache: write through
     sda: sda1 sda2
    

    查看下U盘设备,这个u盘有两个分区,一个是PE,所以sda1是第一个分区,sda2是第二个分区

    # ls -l /dev/sda*
    brw-rw----    1 0        0          8,   0 Jan  4 06:57 /dev/sda
    brw-rw----    1 0        0          8,   1 Jan  4 06:57 /dev/sda1
    brw-rw----    1 0        0          8,   2 Jan  4 06:57 /dev/sda2
    

    手动挂载

     mount /dev/sda1 /mnt
    

    自动挂载

    创建文件,加入配置文件vi /etc/mdev.conf

    sda[1-9]+ 0:0 660 * if [ $ACTION = "add" ]; then mount /dev/$MDEV /mnt; else umount /mnt; fi
    
    • [1-9] 匹配数字1到9
    • + 表示重复前面1次及以上 也就是表示1~无穷大的数字
    • 0:0 uid,默认为0就好了
    • 660权限
    • *,创建设备节点之后 和 删除设备节点之前 执行命令
    • /dev/$MDEV,表示要创建/注销的那个设备节点

    或者使用脚本mdev.sh,更好看

    #!/bin/sh
    if [ $ACTION = "add" ]; 
    then 
    	mount /dev/$MDEV /mnt; 
    else 
    	umount /mnt; 
    fi
    

    常用的命令

    ifconfig eth0 192.168.95.200
    mount  -t nfs -o nolock,vers=2 192.168.95.222:/home/book/stu /mnt
    使用nfs在uboot下下载内核  
    nfs 30000000 12.16.45.222:/uimage   
    bootm 30000000
    

    env

    输入env可以查看当前shell的环境变量

    # env
    USER=root
    OLDPWD=/etc
    HOME=/
    TERM=vt102
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    SHELL=/bin/sh
    PWD=/mnt
    
    # env
    USER=root
    OLDPWD=/mnt
    HOME=/
    TERM=vt102
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    SHELL=/bin/sh
    PWD=/
    
    

    附录 U盘插入的打印信息

    
    # usb 1-1: new full speed USB device using s3c2410-ohci and address 3
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1
    envp[4]=SUBSYSTEM=usb
    envp[5]=SEQNUM=761
    envp[6]=MAJOR=189
    envp[7]=MINOR=2
    envp[8]=DEVTYPE=usb_device
    envp[9]=PHYSDEVBUS=usb
    envp[10]=DEVICE=/proc/bus/usb/001/003
    envp[11]=PRODUCT=951/1666/100
    envp[12]=TYPE=0/0/0
    envp[13]=BUSNUM=001
    envp[14]=DEVNUM=003
    argv[1]=usb
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/class/usb_endpoint/usbdev1.3_ep00
    envp[4]=SUBSYSTEM=usb_endpoint
    envp[5]=SEQNUM=762
    envp[6]=MAJOR=253
    envp[7]=MINOR=2
    envp[8]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1
    envp[9]=PHYSDEVBUS=usb
    envp[10]=PHYSDEVDRIVER=usb
    argv[1]=usb_endpoint
    usb 1-1: configuration #1 chosen from 1 choice
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0
    envp[4]=SUBSYSTEM=usb
    envp[5]=SEQNUM=763
    envp[6]=DEVTYPE=usb_interface
    envp[7]=PHYSDEVBUS=usb
    envp[8]=DEVICE=/proc/bus/usb/001/003
    envp[9]=PRODUCT=951/1666/100
    envp[10]=TYPE=0/0/0
    envp[11]=INTERFACE=8/6/80
    envp[12]=MODALIAS=usb:v0951p1666d0100dc00dsc00dp00ic08isc06ip50
    argv[1]=usb
    scsi1 : SCSI emulation for USB Mass Storage devices
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/class/scsi_host/host1
    envp[4]=SUBSYSTEM=scsi_host
    envp[5]=SEQNUM=764
    envp[6]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host1
    argv[1]=scsi_host
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/class/usb_endpoint/usbdev1.3_ep81
    envp[4]=SUBSYSTEM=usb_endpoint
    envp[5]=SEQNUM=765
    envp[6]=MAJOR=253
    envp[7]=MINOR=3
    envp[8]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0
    envp[9]=PHYSDEVBUS=usb
    envp[10]=PHYSDEVDRIVER=usb-storage
    argv[1]=usb_endpoint
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/class/usb_endpoint/usbdev1.3_ep02
    envp[4]=SUBSYSTEM=usb_endpoint
    envp[5]=SEQNUM=766
    envp[6]=MAJOR=253
    envp[7]=MINOR=4
    envp[8]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0
    envp[9]=PHYSDEVBUS=usb
    envp[10]=PHYSDEVDRIVER=usb-storage
    argv[1]=usb_endpoint
    scsi 1:0:0:0: Direct-Access     Kingston DataTraveler 3.0 PMAP PQ: 0 ANSI: 6
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0
    envp[4]=SUBSYSTEM=scsi
    envp[5]=SEQNUM=767
    envp[6]=PHYSDEVBUS=scsi
    envp[7]=MODALIAS=scsi:t-0x00
    argv[1]=scsi
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/class/scsi_disk/1:0:0:0
    envp[4]=SUBSYSTEM=scsi_disk
    envp[5]=SEQNUM=768
    envp[6]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0
    envp[7]=PHYSDEVBUS=scsi
    envp[8]=PHYSDEVDRIVER=sd
    argv[1]=scsi_disk
    sd 1:0:0:0: [sda] 60555264 512-byte hardware sectors (31004 MB)
    sd 1:0:0:0: [sda] Write Protect is off
    sd 1:0:0:0: [sda] Assuming drive cache: write through
    sd 1:0:0:0: [sda] 60555264 512-byte hardware sectors (31004 MB)
    sd 1:0:0:0: [sda] Write Protect is off
    sd 1:0:0:0: [sda] Assuming drive cache: write through
     sda: sda1 sda2
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/block/sda
    envp[4]=SUBSYSTEM=block
    envp[5]=SEQNUM=769
    envp[6]=MINOR=0
    envp[7]=MAJOR=8
    envp[8]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0
    envp[9]=PHYSDEVBUS=scsi
    envp[10]=PHYSDEVDRIVER=sd
    argv[1]=block
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/block/sda/sda1
    envp[4]=SUBSYSTEM=block
    envp[5]=SEQNUM=770
    envp[6]=MINOR=1
    envp[7]=MAJOR=8
    envp[8]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0
    envp[9]=PHYSDEVBUS=scsi
    envp[10]=PHYSDEVDRIVER=sd
    argv[1]=block
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/block/sda/sda2
    envp[4]=SUBSYSTEM=block
    envp[5]=SEQNUM=771
    envp[6]=MINOR=2
    envp[7]=MAJOR=8
    envp[8]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0
    envp[9]=PHYSDEVBUS=scsi
    envp[10]=PHYSDEVDRIVER=sd
    argv[1]=block
    sd 1:0:0:0: [sda] Attached SCSI removable disk
    userhelp=/sbin/mdev
    envp[0]=HOME=/
    envp[1]=PATH=/sbin:/bin:/usr/sbin:/usr/bin
    envp[2]=ACTION=add
    envp[3]=DEVPATH=/class/scsi_device/1:0:0:0
    envp[4]=SUBSYSTEM=scsi_device
    envp[5]=SEQNUM=772
    envp[6]=PHYSDEVPATH=/devices/platform/s3c2410-ohci/usb1/1-1/1-1:1.0/host1/target1:0:0/1:0:0:0
    envp[7]=PHYSDEVBUS=scsi
    envp[8]=PHYSDEVDRIVER=sd
    argv[1]=scsi_device
    
    
  • 相关阅读:
    promise 理解
    强化学习的概念
    Ubuntu安装机器学习环境步骤
    jsp文件复制到web项目出错
    jdbc导致的问题
    C#窗体-猜数字
    软件工程结对作业01
    第二阶段冲刺10天 第3天进展报告
    第二阶段冲刺10天 第2天进展报告
    第二阶段冲刺10天 第1天进展报告
  • 原文地址:https://www.cnblogs.com/zongzi10010/p/10246447.html
Copyright © 2011-2022 走看看