udev和驱动的自动加载
一、概述
在一般的驱动编写时,我们可以通过加载模块来向系统添加设备,也可以通过移除模块来删除设备。但是很多时候我们会设想到一种更加智能的的场景,即当设备被添加到系统后,驱动可以自动加载,这对于实际的可支持热插拔的硬件来说更有必要。比如说,我们插入一个USB无线网卡,那么对应的驱动就应该自动加载,而不是由用户来手动加载。要想实现这一工能,我们就需要依赖一个工具 — udev。在大多数嵌入式系统中通常使用mdev,其功能比udev要弱很多,同样的我们也可以移植udev到嵌入式系统上。
先补充一点Linux设备模型的知识:使用了Linux设备模型后,任何设备的添加、删除或者状态修改都会导致内核向用户空间发送相应的事件,这个事件叫uevent,它和kobject密切关联。这样用户空间就可以铺货这些事件来自动完成某些操作,如自动加载驱动、自动创建和删除设备节点、修改权限、创建软连接修改网络设备的名字等。目前实现这个功能的工具就是udev(或者mdev),这是一个用户空间的应用程序,捕获来自内核空间发来的事件,然后根据其规则文件进行操作。udev的规则文件一般放在/etc/udev/rules.d目录下的后缀为.rules的文件。
二、udev规则文件基本语法
udev规则文件用# 来注释,除此之外就是一条一条的规则。每条规则至少包含一个键值对,建分为匹配和赋值两种类型。如果内核发来的事件匹配了规则中的所有匹配键的值,那么这条规则就可以得到应用,并且赋值建被赋予指定的值。一条规则包含了一个或多个键值对,这些键值对用逗号隔开,每个键由操作符规定一个操作,合法的操作符如下。
此外还有很多,这里列出比较常见的。更加详细的可以参考udev的man手册。
值还可以使用?、*和[]来进行匹配,这和正则表达式中的含义是一样的。
ACTION=="add", SUBSYSTEM=="scsi_device", RUN+="/sbin/modprobe sg"
它表示当向SCSI子系统添加任意设备后都要添加一个命令“/sbin/modprobe sg”到命令列表中,这个命令就是为相应的设备加载sg驱动模块。
在ubuntu中自动加载驱动的规则如下,请将这条规则添加到/etc/udev/rules.d/40-modprobe.rules文件中,如果没有这个文件请新建一个。
ENV{MODALIAS}=="?*",RUN+="/sbin/modprobe $env{MODALIAS}"
它表示根据模块的别名信息,用modprobe命令加载对应的内核模块。为此我们要给平台驱动一个别名,如pltdrv.c文件中代码的第49行。pdev要和驱动中用于匹配平台设备的名字保持一致。
$49 MODULE_ALIAS("platform : pdev");
添加这一条规则后,加载pltdev模块就可以自动加载pltdev驱动。