MODULE_DEVICE_TABLE(type, name)

//定义在linux/module.h
//@type:设备类型
//@name:驱动所支持的设备列表。这个设备表的最后一个元素是空的,用于表示结束。
#define MODULE_DEVICE_TABLE(type, name)
extern typeof(name) __mod_##type##__##name##_device_table
  __attribute__ ((unused, alias(__stringify(name))))


//在分析内核时,有些函数会添加__attribute__ ((unused))
//这个表示该函数或变量可能不使用,这个属性可以避免编译器产生警告信息
__attribute__ ((unused))

  1.功能      

        创建一个指向设备列表name(如hid_device_id)的局部变量(如__mod_hid_device_table)。内核构建的时候,depmod程序会在所有模块中搜索symbol如_mod_hid_device_table,如果搜索到,把数据(设备列表)从模块中抽出,添加到映射文件(如/lib/modules/KERNEL_VERSION/modules.hidmap)中,当depmod结束之后,所有的hid设备连同他们的模块名字都被该文件列出。当内核告知热插拔系统一个新的hid设备被发现,热插拔系统使用modules.hidmap匹配设备信息如PID、VID来寻找恰当的驱动程序。如果匹配到则使用对应的驱动操作此设备,若此时驱动未添加,系统会自动添加(insmod/modprobe)此驱动。

        也就是说MODULE_DEVICE_TABLE具有两个功能:

        一:将设备加入到外设队列中;

        二:告诉程序阅读者该设备是热插拔设备或者说该设备具备热插拔功能。

2.实现

        1.定义一个设备列表,例如hid_device_id;

        2.调用MODULE_DEVICE_TABLE宏创建一个指向设备列表的变量(因为depmod程序识别的是MODULE_DEVICE_TABLE宏创建出来的type##device_id格式的变量。

        3.内核构建过程(启动过程),自动调用depmod程序查找。调用depmod查找是每个内核自动加载模块都经历的,所以每个驱动模块支持的设备列表就会通过type##_device_id被查找到,并在映射文件中列出设备以及驱动的名字。

        4.热插拔事件会唤醒热插拔处理程序,热插拔处理程序会到/lib/modules/KERNEL_VERSION/下查找对应的文件,判断设备列表里面的数据与设备是匹配的,匹配则选择该驱动程序。

        例如:

        当一个设备接到集线器,热插拔系统就被唤醒,hid子系统就会检查插入设备的vendor id 和product id。

//inlude/mod_devicetable.h
struct hid_device_id {
    __u16 bus;
    __u16 group;
    __u32 vendor;
    __u32 product;
    kernel_ulong_t driver_data;
}

//hid-generic
static const struct  hid_device_id hid_table[] = {
    { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) },
    { }
};
MODULE_DEVICE_TABLE(hid, hid table);

3.热插拔

         MODULE_DEVICE_TABLE一般用于动态加载驱动也就是热插拔的时候使用。

        模块所支持的热插拔设备信息使用modinfo命令查看,如下:

        # modinfo hid-generic.ko | grep "alias"  (查看模块支持的热插拔设备)

        alias:                hid:b*g*v0000xxxxp0000xxxx

          # modinfo hid-generic.ko | head -n 50   (查看模块信息)

        这些alias存储在模块文件本身(hid-generic.ko)中。modinfo将他们打印出来,depmod将他们写到/lib/modules/VERISON/modules.aliases供modprobe读取,它不会在任何配置文件中读取。

4.模块常用命令

1.insmod xxx.ko   //将模块加进内核
2.rmmod xxx.ko   //将模块从内核中卸载
3.lsmod   //查看已经安装到内核的模块
4.modprobe   //载入指定的模块,或是载入一组相互依赖的模块,modprobe会根据depmod锁产生的依赖关系,   //决定要载入哪些模块。若在载入过程中发生错误,在modprobe会卸载整组的模块。依赖关系是通过
//读取/lib/modules/2.6.xx/modules.dep得到的。该文件是depmod建立的。
5.modinfo xxx.ko  //读取模块信息。
6.tree -a  //查看当前目录的整个树结构

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值