1.devfs设备文件系统
起源:Linux2.4内核引入
优点:(1)可以通过程序在设备初始化时在/dev目录下创建设备文件,卸载时删除
(2)设备程序可以指定设备名、所有者和权限位,并且用户空间程序可以修改它们
(3)不再需要为设备驱动程序分配主设备号以及处理次设备号,程序中通过register_chrdev()传递0,以获取可用的主设备号(在2.6内核中常使用register_chrdev_region())。在devfs_register()中指定次设备号
设备文件的相关函数:
/*创建设备目录*/
devfs_handle_t devfs_mk_dir(devfs_handle_t dir,const char *name,void *info);
/*创建设备文件*/
devfs_handle_t devfs_register(devfs_handle_t dir,const char *name,unsigned int flags,unsigned int major,unsigned int minor,umode_t umode_t mode,void *ops,void *info);
/*销毁设备文件*/
void devfs_unregister(devfs_handle_t de);
使用范例:
static devfs_handle_t devfs_handle;
static int __init xxx_init(void)
{
int ret;
int i ;
/*在内核中注册设备*/
ret = register_chrdev(XXX_MAJOR,DEVICE_NAME,&xxx_fops);
if(ret<0){
printk(DEVICE_NAME "can't register major number\n");
return ret;
}
/*创建设备文件*/
devfs_handle = devfs_register(NULL,DEVICE_NAME,DEVFS_FL_DEFAULT),
XXX_MAJOR,0,S_IFCHR|S_IRUSR|S_IWUSR,&xxx_fops,NULL);
...
printk(DEVICE_NAME "Initialized\n");
return 0;
}
static void __exit xxx_exit(void)
{
devfs_unregister(devfs_handle);/*销毁设备文件*/
unregister_chrdev(XXX_MAJOR,DEVICE_NAME);/*注销设备*/
}
module_init(xxx_init);
module_exit(xxx_exit);
2.udev设备文件系统
起源:Linux2.6内核中引入
设计目标:
在用户空间执行;
动态建立/删除设备文件;
不关心主/次设备号(重点);
提供LSB标准的名称;
也可提供固定名称
与devfs相比:采用devfs,当一个不存在的/dev节点被打开时,devfs能自动加载对应的驱动
而udev设计者则认为Linux应该在设备被发现的时候加载驱动模块,而不是在访问它的时候
udev的组成:
udev下载包地址:http://www.is.kernel.org/pub/linux/utils/kernel/hotplug/
udev工作过程:
(1)当内核检测到系统中出现新设备后,内核会在sysfs文件系统中为新设备生成新的
记录并导出一些设备的特定信息
(2)udev获取内核导出信息,调用namedev(设备命名子系统)给该设备指定名称,如果是新设备,udev将调用
libsysfs(提供访问sysfs文件系统从中获取信息的标准接口)指定主次设备号创建设备文件
namedev指定设备名称的5步准则:
1,标签label/序号serial:检查设备是否有唯一的识别记号.
# USB Epson printer to be called lp_epson
LABEL, BUS="usb", serial="HXOLL0012202323480", NAME="lp_epson"
# USB HP printer to be called lp_hp
LABEL, BUS="usb", serial="W09090207101241330", NAME="lp_hp"
2,设备总线号:检查总线的设备编号.
# sound card with PCI bus id 00:0b.0 to be the first sound card
NUMBER, BUS="pci", id="00:0b.0", NAME="dsp"
# sound card with PCI bus id 00:07.1 to be the second sound card
NUMBER, BUS="pci", id="00:07.1", NAME="dsp1"
3,总线上的拓扑:检查设备在总线上的位置.
#USB mouse plugged into the third port of the first hub to be called mouse0
TOPOLOGY, BUS="usb", place="1.3", NAME="mouse0"
#USB tablet plugged into the second port of the second hub to be called mouse1
TOPOLOGY, BUS="usb", place="2.2", NAME="mouse1"
4,替换名称:检查导出的名称匹配替代的字符串时,就会替代指定的名称.
# ttyUSB1 should always be called visor
REPLACE, KERNEL="ttyUSB1", NAME="visor"
5, 内核提供的名称:如果以上都不符合,用缺省名称.
udev规则文件(当系统中出现新硬件时按照此规则执行)
以"#"开头的行代表注释行
匹配部分用专用的关键字(ACTION行为、KERNEL匹配内核设备名、BUS匹配总线类型,SYSFS匹配从sysfs得到的信息)
赋值部分(NAME创建设备文件名、SYMLINK符号链接名、OWNER设置设备所有者、GROUP设置设备的组、IMPORT调用外部程序)
例如:SUBSYSTEM=='net',ACTION=="add",SYSFS{address}=="00:0d:87:f6:59:f3",IMPORT="/sbin/rename_netiface %k eth0"
解释:当系统中出现新硬件属于net子系统范畴,系统发出的动作时“add”,并且且此硬件sysfs文件系统中的“address”信息为"00:0d:87:f6:59:f3"
对此硬件执行的动作时调用外部程序/sbin/rename_netiface并传递参数“%k(代表内核对该设备定义的名称”)、eth0;
又例如:BUS="usb" SYSFS{serial}="HXOLL0012202323480",NAME="lp_epson",SYMLINK="printers/epson_stylus"
解释:该规则中匹配的项目有BUS和SYSFS,赋值项目为NAME和SYMLINK,当一台USB打印机的序列号是"HXOLL0012202323480"时,创建/dev/lp_epson文件
并同时创建一个符号链接/dev/printers/epson_styles
}