Linux创建字符设备 自动生成设备节点
platform模型驱动和字符设备模型驱动

platform模型驱动和字符设备模型驱动字符设备驱动模型:1、申请设备号:动态申请(alloc_chrdev_region()),动态申请(register_chrdev_region())struct cdev btn_cdev;//申请设备号if(major){//静态申请设备号dev_id = MKDEV(major, 0);register_chrdev_region(dev_id, 1, "button");}else{//动态申请设备号alloc_chardev_region(&dev_id, 0, 1, "button");major = MAJOR(dev_id);}在Linux中以主设备号用来标识与设备文件相连的驱动程序。
次编号被驱动程序用来辨别操作的是哪个设备。
cdev 结构体的 dev_t 成员定义了设备号,为 32 位,其中高 12 位为主设备号,低20 位为次设备号。
设备号的获得与生成:获得:主设备号:MAJOR(dev_t dev);次设备号:MINOR(dev_t dev);生成:MKDEV(int major,int minor);2、初始化设备:void cdev_init(struct cdev *, struct file_operations *);cdev_init()函数用于初始化cdev 的成员,并建立cdev 和file_operations 之间的连接。
3、注册设备int cdev_add(struct cdev *, dev_t, unsigned);cdev_add()函数向系统添加一个 cdev,完成字符设备的注册。
4、创建设备节点手动创建设备节点:mknod 的标准形式为:mknod DEVNAME {b | c} MAJOR MINOR1,DEVNAME是要创建的设备文件名,如果想将设备文件放在一个特定的文件夹下,就需要先用mkdir在dev目录下新建一个目录;2, b和c 分别表示块设备和字符设备:b表示系统从块设备中读取数据的时候,直接从内存的buffer中读取数据,而不经过磁盘;c表示字符设备文件与设备传送数据的时候是以字符的形式传送,一次传送一个字符,比如打印机、终端都是以字符的形式传送数据;3,MAJOR和MINOR分别表示主设备号和次设备号:为了管理设备,系统为每个设备分配一个编号,一个设备号由主设备号和次设备号组成。
关于linux的fb_framebuffer 设备驱动

草稿V2.4.01framebuffer设备即帧缓冲设备(简写fb)提供了显示接口的抽象描述。
他同时代表着显示接口的存储区,应用程序通过定义好的函数访问,不需要知道底层的任何操作。
Framebuffer驱动使用的设备节点,通常位于/dev目录,如/dev/fb*.从用户角度看,fb设备和其他/dev下面的设备类似:普通的字符设备,主设备号29,次设备号定义fb的索引。
通常,使用如下方式(前面的数字表示次设备号)0=/dev/fb0第一个fb设备1=/dev/fb1第二个fb设备考虑到向下兼容,可以创建符号链接:/dev/fb0current->fb0/dev/fb1current->fb1fb也是一种普通的内存设备,可以读写其内容。
例如,屏幕抓屏:cp/dev/fb0myfilefb虽然可以像内存设备(/dev/mem)一样,对其read,write,seek以及mmap。
但区别在于fb使用的不是整个内存区,而是显存部分。
通过ioctl可以读取或设定fb设备参数,很重要的一点,颜色表(cmap)也要通过Ioctl设定。
查看<linux/fb.h>就知道有多少ioctl应用以及相关数据结构。
这里给出摘要:-你可以获取设备一些不变的信息,如设备名,屏幕的组织(平面,象素,...)对应内存区的长度和起始地址。
-也可以获取能够改变的信息,例如位深,颜色格式,时序等。
如果你改变这些值,驱动程序将对值进行优化,以满足设备特性(如果你的设定,设备不支持,返回EINVAL)。
-你也可以获取或设定部分颜色表。
所有这些特性让应用程序十分容易的使用framebuffer设备。
Xserver可以使用/dev/fb*而不需知道硬件的寄存器是如何组织的。
XF68_FBDev是一个用于位映射(单色)Xserver,唯一要做的就是在应用程序在相应的位置设定是否显示。
在新内核中,帧缓冲设备可以工作于模块中,允许动态加载。
字符设备驱动——设备号、设备节点概念辨析(转)

字符设备驱动——设备号、设备节点概念辨析(转) 设备节点被创建在/dev下,是连接内核与⽤户层的枢纽,就是设备是接到对应哪种接⼝的哪个ID 上。
相当于硬盘的inode⼀样的东西,记录了硬件设备的位置和信息在Linux中,所有设备都以⽂件的形式存放在/dev⽬录下,都是通过⽂件的⽅式进⾏访问,设备节点是Linux内核对设备的抽象,⼀个设备节点就是⼀个⽂件。
应⽤程序通过⼀组标准化的调⽤执⾏访问设备,这些调⽤独⽴于任何特定的驱动程序。
⽽驱动程序负责将这些标准调⽤映射到实际硬件的特有操作。
设备节点,驱动,硬件设备是如何关联到⼀起的呢?这是通过设备号实现的,包括主设备号和次设备号。
当我们创建⼀个设备节点时需要指定主设备号和次设备号。
应⽤程序通过名称访问设备,⽽设备号指定了对应的驱动程序和对应的设备。
主设备号标识设备对应的驱动程序,次设备号由内核使⽤,⽤于确定设备节点所指设备。
主设备号:驱动程序在初始化时,会注册它的驱动及对应主设备号到系统中,这样当应⽤程序访问设备节点时,系统就知道它所访问的驱动程序了。
你可以通过/proc/devices⽂件来查看系统设备的主设备号。
次设备号:驱动程序遍历设备时,每发现⼀个它能驱动的设备,就创建⼀个设备对象,并为其分配⼀个次设备号以区分不同的设备。
这样当应⽤程序访问设备节点时驱动程序就可以根据次设备号知道它说访问的设备了。
设备节点(设备⽂件):Linux中设备节点是通过“mknod”命令来创建的。
⼀个设备节点其实就是⼀个⽂件,Linux中称为设备⽂件。
有⼀点必要说明的是,在Linux 中,所有的设备访问都是通过⽂件的⽅式,⼀般的数据⽂件程序普通⽂件,设备节点称为设备⽂件。
总结:⾮要说设备节点与主设备号有什么区别的话?其实两者根本就不是⼀个东西,没有可⽐性。
linux下对设备的访问是要通过⽂件的形式的,故设备都以⽂件形式存放在/dev⽬录下,它没有实际上的作⽤,就相当于是⼀个接⼝,为应⽤程序访问设备提供的⼀个⼿段。
使用misc_register函数注册设备-KC08131405-d01解读

模块三:嵌入式网关之驱动程序编写
模块三:嵌入式网关之驱动程序编写
知识点:使用misc_register函数注册设备
学习目标 一、杂项设备的注册方法 二、将ds18b20_driver驱动注册为杂项设备 三、操作演示
四、新版Linux内核字符设备的注册方法
模块三:嵌入式网关之驱动程序编写
.minor = MISC_DYNAMIC_MINOR,//minor: 次设备号, 动态生成 .name = DEVICE_NAME, //name : 设备文件名称 .fops = &ds18b20_fops //fops : file_operations指针 };
定义这个杂项设备结构体,并指定次设备号动态生成,指定设备文件 名为前面给出的“ds18b20_driver”,指定对设备文件进行各种操作的函 数地址为“ &ds18b20_fops“。
模块三:嵌入式网关之驱动程序编写
知识点:使用misc_register函数注册设备
杂项设备采用 misc_register() 函数注册时,会自动创建设备节点(即
设备文件),无需另用mknod命令创建设备文件。因为misc_register()函
数会调用 class_device_create() 函数或者 device_create() 函数来自动创建
使用insmod命令加载驱动,再输入ls -l /dev/ds18b20_driver命令可 以看到如下信息。
crw-rw---1 root root 10, 55 Jan 1 00:00 /dev/ds18b20_driver
模块三:嵌入式网关之驱动程序编写
知识点:使用misc_register函数注册设备
linux sd节点生成流程

在Linux系统中,SD(Secure Digital)卡节点是通过内核自动创建的,这一过程通常涉及以下几个步骤:1. 内核初始化:当Linux系统启动时,内核会加载并初始化。
在这个过程中,内核会检测连接的SD 卡设备。
2. 设备检测:内核通过SD卡控制器发出的中断或轮询方式检测到SD卡的插入。
3. 驱动加载:内核加载与SD卡相关的驱动模块,如`pxamci`或其他对应的SD卡驱动。
4. 驱动注册:SD卡驱动模块会向内核注册自己的驱动,这样内核就知道如何与SD卡进行交互了。
5. SD卡初始化:驱动会对SD卡进行初始化,包括设置必要的电压、执行卡的识别过程等。
6. SD卡节点创建:在SD卡被成功初始化后,内核会根据SD卡的属性创建相应的设备节点。
这个节点通常是`/dev/sdX`的形式,其中`X`是SD卡的磁盘号。
7. 文件系统挂载:如果SD卡包含了文件系统,内核会尝试挂载这个文件系统到一个目录下,比如`/mnt/sdcard`。
8. 系统更新:有些系统会自动更新`/etc/fstab`文件,以便在下次启动时自动挂载SD卡。
9. 用户空间应用感知:一旦SD卡节点创建完成,用户空间的应用程序就可以通过这个节点与SD卡进行交互,比如读写文件。
这个过程通常是自动的,不需要用户干预。
但是,如果需要手动创建SD卡节点,可以使用mknod命令,例如:bashmknod /dev/sdX b 8 0这里b表示块设备,8是主设备号,0是次设备号。
需要注意的是,这个操作应该在SD 卡被正确检测到并挂载文件系统之后进行。
如果要在程序中动态创建SD卡节点,可以使用Linux内核提供的alloc_chrdev_region 函数来动态分配一个字符设备节点。
这通常在编写内核模块时使用。
嵌入式linux(贺丹丹等编著)课后习题答案

嵌入式linux(贺丹丹等编著)课后习题答案第八章一、填空题。
1、ARM-Linux内核的配置系统由三个部分组成,它们分别是Makefile、配置文件和配置工具。
2、配置工具一般包括配置命令解释器和配置用户界面,前者主要作用是对配置脚本中使用的配置命令进行解释;而后者则是提供基于字符界面、基于Ncurses图形界面以及基于X Window图形界面的用户配置界面。
3、Makefile文件主要包含注释、编译目标定义和适配段。
4、Linux内核常用的配置命令有make oldconfig、make config、make menuconfig和make xconfig。
其中以字符界面配置的命令是make config。
5、内核编译结束后,会在“/arch/arm/boot/”目录下面和根目录下面生成一个名为zImage的内核镜像文件。
二、选择题C AD D B三、叙述题1、Linux内核各个部分与内核源码的各个目录都是对应起来的,比如有关驱动的内容,内核中就都组织到“drive”这个目录中去,有关网络的代码都集中组织到“net”中。
当然,这里有的目录是包含多个部分的内容。
具体各个目录的内容组成如下:arch:arch目录包括了所有和体系结构相关的核心代码。
include:include 目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在include/linux 子目录下;init:init 目录包含核心的初始化代码(不是系统的引导代码),有main.c 和Version.c 两个文件;mm:mm 目录包含了所有的内存管理代码。
与具体硬件体系结构相关的内存管理代码位于arch/*/mm 目录下;drivers:drivers 目录中是系统中所有的设备驱动程序。
它又进一步划分成几类设备驱动,每一种有对应的子目录,如声卡的驱动对应于drivers/sound;ipc:ipc 目录包含了核心进程间的通信代码;modules:modules 目录存放了已建好的、可动态加载的模块;fs:fs 目录存放Linux 支持的文件系统代码。
linux udev规则

linux udev规则Linux中的udev是一种设备管理器,用于动态管理设备节点和设备驱动程序的加载。
udev规则是在udev管理器中定义的规则集,用于自定义设备的命名、权限设置和其他操作。
下面是关于linux udev规则的详细介绍:规则文件位置:udev规则文件通常存储在/etc/udev/rules.d/目录下,以.rules为后缀。
您可以在该目录中创建新的规则文件或编辑已有的文件。
规则语法:udev规则采用简单的文本配置语法。
每个规则由一行表示,并包含以下几个部分:规则名称:规则名称是一个描述性的字符串,以SUBSYSTEM、KERNEL或ATTR开头,后跟一个可选的匹配条件。
匹配条件:匹配条件用于在设备和属性之间进行匹配。
您可以使用设备的子系统(subsystem)、内核属性(kernel attribute)和设备属性(device attribute)进行匹配。
动作:规则的最后部分是要执行的动作。
动作可以是设置设备权限、创建符号链接、运行脚本等。
规则示例:命名设备节点:您可以使用udev规则为设备节点定义自定义名称。
例如,您可以为一个特定的USB设备设置自定义名称,以便更容易识别。
示例规则为一个USB设备节点命名:SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", ATTR{idProduct}=="XXXX", NAME="my_device"设置设备权限:您可以使用udev规则设置设备节点的权限。
例如,您可以设置特定设备节点的所有者和访问权限。
示例规则设置设备权限:SUBSYSTEM=="input", MODE="0666"创建符号链接:您可以使用udev规则在/dev目录下创建符号链接,以便使用更友好的设备名称。
示例规则创建一个名为my_link 的符号链接:KERNEL=="sda1", SYMLINK+="my_link"规则的加载和生效:当系统启动时,udev会读取/etc/udev/rules.d/目录中的规则文件,并将规则加载到内核中。
linux created symlink 用法

linux created symlink 用法在Linux系统中,symlink(符号链接)是一种特殊类型的文件,它允许用户创建一个指向另一个文件或目录的链接。
symlink与文件复制类似,但是它只存储目标文件或目录的路径,而不是实际的复制数据。
这使得symlink非常适合在系统上组织和归类文件,同时提供了一种方便的方式来访问文件或目录。
以下是在Linux系统中创建symlink的一般用法:1. 创建符号链接:可以使用命令行工具`ln`来创建symlink。
使用`ln`命令的基本语法如下:```arduinoln -s 源文件/目录目标文件/目录名```其中,`-s`选项表示创建symlink,`源文件/目录`是要链接的目标,而`目标文件/目录名`是symlink的名称。
例如,如果要在当前目录下创建一个名为`mylink`的symlink,指向名为`myfile.txt`的文件,可以执行以下命令:```arduinoln -s myfile.txt mylink```现在,在系统中可以像访问普通文件一样访问`mylink`,它将直接指向`myfile.txt`。
2. 创建多层链接:symlink可以链接到另一个symlink,形成多层链接结构。
使用`-d`选项可以创建多层链接。
例如:```arduinoln -d 源路径目标路径/目录名```例如,如果有一个名为`dir1`的目录,其中包含名为`dir2`的子目录,并且要创建一个链接到`dir2`的symlink,可以使用以下命令:```arduinoln -d dir1/dir2 link_to_dir2```现在,`link_to_dir2`将指向`dir1/dir2`目录。
3. 符号链接的权限和所有权:symlink与其目标文件或目录共享相同的权限和所有权。
用户可以使用常规的文件和目录权限工具来更改symlink的权限和所有权。
例如,可以使用`chmod`和`chown`命令来更改symlink的权限和所有者。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linux创建字符设备自动生成设备节点1. 创建字符设备生成设备节点2. busyboxLinux System Utilities --->[*] mdev[*] Support /etc/mdev.conf[*] Support command execution at device addition/removal3. kernelFile systems --->Pseudo filesystems --->[*] sysfs file system support[*] Virtual memory file system support (former shm fs)[*] Tmpfs POSIX Access Control Lists4. rootfsvi ./etc/init.d/rcSmount -t tmpfs mdev /devmkdir /dev/ptsmount -t devpts devpts /dev/ptsmount -t sysfs sysfs /sysmount -aecho /sbin/mdev > /proc/sys/kernel/hotplugmdev -s-----------------------------------------------------------------------设备节点是由谁负责创建呢?我自个写着玩的时候一直都是自个用mknod来手动创建设备文件的。
实际中设备文件应由谁创建呢?由驱动程序吗?还是系统自带的一些服务(udev等)会在设备接入时来动态的创建设备文件节点啊?如果是那个的话,一个不识别的设备它们(udev等)又怎么知道要如何创建节点呢?比如说U盘系统怎么会知道是创建成sda,sdb等。
设备节点是由你写的驱动程序里面实现的。
struct class *myclass = class_create(THIS_MODULE, “char_dev”);class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “char_dev”);这二个函数就是创建一个设备,和他的节点号。
在你加入设备时udev就会判断,然后建立节点。
至于你说的不识别的设备,你得加载驱动啊,加载驱动的时候里面只要有上述的二个函数,通过UDEV就会创建了。
-------------------------------------------------------------------------------------------- 两种方法建立设备节点,一种是自己手动用mknod,另一种是存在udev,它会自动创建相应的设备节点。
另外,楼主你写的驱动首先是要进行注册的,要创建一个class和device,class在/dev目录下,device 在sysfs目录下,这样,你加载模块是就会根据已创建的device去找sysfs目录下的class。
---------------------------------------------------------------------------------------------使用linux-2.6.30.4。
文件的管理使用的是 sysfs.(由udev制作的文件系统)涉及两个函数:virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");使用需添加头文件 #include <linux/device.h>说明:当使用利用udev制作的文件系统时,Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点。
内核中定义了struct class结构体,一个struct class结构体类型变量对应一个类(有待商榷),内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。
这样,加载模块的时候,用户空间中的udev会自动响应 device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
在linux-2.6.30.4,struct class定义在头文件include/linux/device.h中,struct class {const char *name;struct module *owner;struct class_attribute *class_attrs;struct device_attribute *dev_attrs;struct kobject *dev_kobj;int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);void (*class_release)(struct class *class);void (*dev_release)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);struct dev_pm_ops *pm;struct class_private *p;};class_create(…)头文件include/linux/device.h中,#define class_create(owner, name) /({ /static struct lock_class_key __key; /__class_create(owner, name, &__key); /})__class_create在/drivers/base/class.c中实现:struct class *__class_create(struct module *owner, const char *name,struct lock_class_key *key)device_create(…)函数在/drivers/base/core.c中实现:struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)* device_create - creates a device and registers it with sysfs* @class: pointer to the struct class that this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for the char device to be added* @drvdata: the data to be added to the device for callbacks* @fmt: string for the device's name使用示例:virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");示例程序(一个简单的字符驱动):view plaincopy to clipboardprint?1.struct class *virtual_disk_class; /*by yinhf.*/2./*设备驱动模块加载函数*/3.int VirtualDisk_init(void)4.{5.int result;6. dev_t devno = MKDEV(VirtualDisk_major, 0); /*构建设备号*/7./* 申请设备号*/8.if (VirtualDisk_major) /* 如果不为0,则静态申请*/9. result = register_chrdev_region(devno, 1, "VirtualDisk");10.else/* 动态申请设备号 */11. {12. result = alloc_chrdev_region(&devno, 0, 1, "VirtualDisk");13. VirtualDisk_major = MAJOR(devno);/* 从申请设备号中得到主设备号 */14. }15.if (result < 0)16.return result;17.18./* 动态申请设备结构体的内存*/19. Virtualdisk_devp = kmalloc(sizeof(struct VirtualDisk), GFP_KERNEL);20.if (!Virtualdisk_devp) /*申请失败*/21. {22. result = - ENOMEM;23.goto fail_kmalloc;24. }25. memset(Virtualdisk_devp, 0, sizeof(struct VirtualDisk));/*将内存清零*/26./*初始化并且添加cdev结构体*/27. VirtualDisk_setup_cdev(Virtualdisk_devp, 0);28.// devfs_mk_cdev(devno, S_IFCHR|S_IRUGO|S_IWUSR, "VirtualDisk"); /*yinhf*/29. printk(KERN_ALERT "Virtualdisk Success/n");30./* create virtual_disk_class under /sysfs by yinhf.*/31. virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");32.if(IS_ERR(virtual_disk_class))33. {34. printk("Err: failed in creating virtual_disk_class./n");35.return -1;36. }37./* register your own device in sysfs, and this will cause udev to create corresponding device node */38. device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");39. printk (KERN_INFO "Registered character driver VirtualDisk./n");40./*end create virtual_disk_class by yinhf.*/41.return 0;42. fail_kmalloc:43. unregister_chrdev_region(devno, 1);44.return result;45.}struct class *virtual_disk_class; /*by yinhf.*/ /*设备驱动模块加载函数*/ intVirtualDisk_init(void) { int result; dev_t devno = MKDEV(VirtualDisk_major, 0); /*构建设备号*/ /* 申请设备号*/ if (VirtualDisk_major) /* 如果不为0,则静态申请*/ result =register_chrdev_region(devno, 1, "VirtualDisk"); else /* 动态申请设备号 */ { result =alloc_chrdev_region(&devno, 0, 1, "VirtualDisk"); VirtualDisk_major = MAJOR(devno);/* 从申请设备号中得到主设备号 */ } if (result < 0) return result; /* 动态申请设备结构体的内存*/Virtualdisk_devp = kmalloc(sizeof(struct VirtualDisk), GFP_KERNEL); if (!Virtualdisk_devp) /*申请失败*/ { result = - ENOMEM; goto fail_kmalloc; } memset(Virtualdisk_devp, 0, sizeof(struct VirtualDisk));/*将内存清零*/ /*初始化并且添加cdev结构体*/VirtualDisk_setup_cdev(Virtualdisk_devp, 0); // devfs_mk_cdev(devno, S_IFCHR|S_IRUGO|S_IWUSR, "VirtualDisk"); /*yinhf*/ printk(KERN_ALERT "Virtualdisk Success/n"); /* createvirtual_disk_class under /sysfs by yinhf.*/ virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk"); if(IS_ERR(virtual_disk_class)) { printk("Err: failed in creatingvirtual_disk_class./n"); return -1; } /* register your own device in sysfs, and this will cause udev to create corresponding device node */ device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk"); printk (KERN_INFO "Registered character driver VirtualDisk./n"); /*end createvirtual_disk_class by yinhf.*/ return 0; fail_kmalloc: unregister_chrdev_region(devno, 1);return result; }view plaincopy to clipboardprint?1./*模块卸载函数*/2.void VirtualDisk_exit(void)3.{4. cdev_del(&Virtualdisk_devp->cdev); /*注销cdev*/5. kfree(Virtualdisk_devp); /*释放设备结构体内存*/6. device_destroy(virtual_disk_class, MKDEV(VirtualDisk_major, 0)); //deletedevice node under /dev7. class_destroy(virtual_disk_class); //delete class created by us8. unregister_chrdev_region(MKDEV(VirtualDisk_major, 0), 1); /*释放设备号*/9.}/*模块卸载函数*/ void VirtualDisk_exit(void) { cdev_del(&Virtualdisk_devp->cdev); /*注销cdev*/ kfree(Virtualdisk_devp); /*释放设备结构体内存*/ device_destroy(virtual_disk_class,MKDEV(VirtualDisk_major, 0)); //delete device node under /dev class_destroy(virtual_disk_class);//delete class created by us unregister_chrdev_region(MKDEV(VirtualDisk_major, 0), 1); /*释放设备号*/ }参考网址:/engerled/archive/2011/02/24/6205722.aspx------------------------------------------------------------------------------------从linux内核2.6的某个版本之后,devfs不复存在,udev成为devfs的替代。