目录
本专栏文章将有70篇左右,欢迎+关注,查看后续文章。
7.4 自动化与热插拔
7.4.1 kmod 自动加载
一个模块的安装方法:
1. 用户层命令。
2. 内核调用用户空间的安装程序。
方法2的步骤:
1. 内核检测到热插拔的外设时,调用 request_module 函数。
2. request_module 函数调用用户空间命令 /sbin/modprobe。安装对应模块。
7.4.2 热插拔
/sbin/modprobe 不会读取设备号。
新设备插入后,需要 /sbin/udevd 进程读取设备标识,以加载正确的驱动。
/sbin/hotplug 过时。默认使用 /sbin/udevd。
举例:插入USB存储设备。
1. USB controller 检查到新设备后,调用 usb_new_device 注册新设备。
2. usb_new_device -> device_add -> kobject_uevent(&dev->kobj, KOBJ_ADD);
3. kobject_uevent 调用 usb_uevent,准备热插拔信息。
4. 将热插拔消息作为参数传递给用户空间 /sbin/udevd 守护进程。
5. udevd读取热插拔消息中关键信息,加载对应模块。
热插拔消息的格式:key=value,如下图:
根据热插拔消息,可知设备信息:
ACTION=add:插入了新设备,而不是拔出设备。
INTERFACE=8/6/80:该设备为大容量存储设备。
#define USB_CLASS_MASS_STORAGE 8
MODALIAS:udev可对比模块别名,匹配模块。
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.uevent = usb_uevent,
};
usb_uevent:发送插入的USB设备特定的热插拔信息,包括:
1. PRODUCT:
idVendor,idProduct,bcdDevice。
2. TYPE:
bDeviceClass,bDeviceSubClass,bDeviceProtocol。
kobject_uevent:
生成通用热插拔消息后,调用各自kset->uevent函数,追加该设备特有热插拔消息。
7.5 版本控制
版本控制:
含义:
检查一个模块是否和当前内核的版本匹配。
作用:
防止加载一个使用被废弃的接口的模块。
7.5.1 校验和方法
对一个模块中使用的每个函数,生成一个CRC校验。
校验工具:
genksym。
使用举例:
生成的校验和:
如何将校验和保存到模块和内核?
__EXPORT_SYMBOL 内部调用__CRC_SYMBOL,将校验和保存到模块 __kcrctab 段。
7.5.2 版本控制函数
check_version:
检查模块所需版本和当前内核版本是否匹配。