zerons's Blog

For The Dream

chanllenge 05 usb keyboard

zerons posted @ 2014年12月20日 14:57 in chanllenge , 559 阅读

在内核模块中使用MODULE_DEVICE_TABLE即可在编译模块的时候在modules.alias中写入相关信息, 用于在对应的device_id插入拔出时采取对应的动作, 如果模块未被载入, 则被注明的模块会被自动加载

相关文档:

                Documentation/usb/hotplug.txt

                LDD linux device driver

 

使用MODULE_DEVICE_TABLE需要一个id_table, 这里只用到usb keyboard

static const struct usb_device_id usb_id_table[] = {
        { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,
                           USB_INTERFACE_SUBCLASS_BOOT,
                           USB_INTERFACE_PROTOCOL_KEYBOARD)},
        {},
};

将编译的ko文件移入/lib/modules/`uname -r`/

首先移除usbhid模块, #rmmod usbhid

这样编译的文件在USB keyboard插入电脑时会载入

 

在hotplug.txt文件中提到了usb_driver结构, 于是在模块中加入

static struct usb_driver mydriver = {
        .name = "usbhid", /* important */
        .id_table = usb_id_table,
        .probe = my_probe, 
        .disconnect = my_disconnect,
};

probe是在设备接入时被调用, disconnect在设备取出时调用

关键是name域, 这个域应该和device name匹配成功时, 才会调用probe函数

因为当前系统中用了一个usbhid的模块, 所以把这个模块改名, 并且rmmod usbhid

此时, 在模块初始化函数中应该调用 usb_register函数, 退出函数中调用usb_deregister函数

注意, usb_register函数调用不成功的时候, 不应该再调用usb_deregister

#include <linux/module.h>
#include <linux/device.h>
#include <linux/usb.h>
#include <linux/hid.h>

static int reg_false = 0;

static int usb_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{
	dev_info(&intf->dev, "usb probe routine\n");
	return 0;
}

static void usb_disconnect(struct usb_interface *intf)
{
	dev_info(&intf->dev, "usb disconnect routine\n");
	return;
}

static const struct usb_device_id usb_id_table[] = {
	{USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,
			USB_INTERFACE_SUBCLASS_BOOT,
			USB_INTERFACE_PROTOCOL_KEYBOARD)},
	{},
};
MODULE_DEVICE_TABLE(usb, usb_id_table);

static struct usb_driver usb_driver = {
	.name		= "usbhid",
	.id_table	= usb_id_table,
	.probe		= usb_probe,
	.disconnect	= usb_disconnect,
};

static int usb_init(void)
{
	pr_info("Hello World\n");
	if (usb_register(&usb_driver)) {
		reg_false = 1;
		return 0;
	}
	pr_info("usb_driver registered\n");
	return 0;
}

static void usb_exit(void)
{
	pr_info("exit...\n");
	if (reg_false == 0)
		usb_deregister(&usb_driver);
}

module_init(usb_init);
module_exit(usb_exit);

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter