linux - linux内核中usb鼠标使用了哪些驱动?

标签 linux linux-kernel usb kernel mouse

我从 LDD3 第 14 章读到关于热插拔驱动程序。我需要编写一个 USB 鼠标驱动程序,当我插入硬件时加载。现在,做一些实验,我开始知道有一个名为“hid-generic”的驱动程序,它在插拔时被调用。

[ 6654.232046] usb 3-1: new low-speed USB device number 3 using uhci_hcd
[ 6654.462061] usb 3-1: New USB device found, idVendor=093a, idProduct=2510
[ 6654.462067] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 6654.462071] usb 3-1: Product: USB OPTICAL MOUSE
[ 6654.462074] usb 3-1: Manufacturer: PIXART
[ 6654.489316] input: PIXART USB OPTICAL MOUSE as /devices/pci0000:00/0000:00:1d.1/usb3/3-1/3-1:1.0/input/input12
[ 6654.489445] hid-generic 0003:093A:2510.0004: input,hidraw0: USB HID v1.10 Mouse [PIXART USB OPTICAL MOUSE] on usb-0000:00:1d.1-1/input0

还有 lsmod 显示,

Module                  Size  Used by
hid_generic            12541  0 
usbhid                 47259  0 
hid                   105241  2 hid_generic,usbhid
psmouse               102541  0 

我的疑惑如下,

1) 为了在插入此鼠标时加载我的模块(热插拔),我必须在内核中禁用这 3 个驱动程序,并使用我的驱动程序构建整个内核,并在 id_table 中提供供应商和设备 ID。对吧?

2) 我还阅读了 USB 核心驱动程序和 USB 设备驱动程序。那么这些HID驱动是核心驱动还是设备驱动?

3) USB 鼠标的核心驱动和设备驱动是什么?我在哪里可以在内核源代码中找到它们?

谢谢, 苏尼尔。

最佳答案

我会尽量一一回答你的问题:

1) 要在插入此鼠标时加载我的模块(热插拔),我必须在内核中禁用这 3 个驱动程序,并使用我的驱动程序构建整个内核,并在 id_table 中提供供应商和设备 ID。对吧?

是的,但是您还需要注意一些其他事项。首先了解特定模块(驱动程序)是如何加载的。关键是MODULE_DEVICE_TABLE(usb, &my_id_table);每当一个特定的模块被“安装”(使用 make modules_install ),一个条目,根据在 MODULE_DEVICE_TABLE 中传递的 id 表在 /lib/modules/<your_kernel>/modules.usbmap 中创建和 /lib/modules/<your_kernel>/modules.dep文件(在文件中搜索字符串“usbhid”)。每当检测到新的 USB 设备时,内核都会读取这些文件以找到匹配的参数。如果找到,则从/lib/modules/<your_kernel>/modules.dep中找到的相应路径加载以下模块其中包含信息。关于驱动程序所在的路径及其依赖项。

所以,现在即使你卸载(rmmod)usbhid从内核中,当您重新插入鼠标时,它将再次加载。为避免这种情况发生,您需要修改这些文件,即从文件中删除条目。为此,“移动”usbhid驱动程序从其原始路径(通常位于 /lib/modules/<your_kernel>/kernel/drivers/hid/usbhid/usbhid.ko 到一个安全的地方。现在重建依赖项,以便从依赖文件中删除条目。

现在您需要创建驱动程序条目。只需安装您的驱动程序即可!

所以,总结一下:

$ sudo rmmod usbhid                                      # Unload the usb mouse driver
$ cd /lib/modules/$(uname -r)/                           # Move to your current kernel
$ vim modules.usbmap                                     # Check for the "usbhid" string
$ vim modules.dep                                        # Check for "usbhid.ko:" string
$ sudo mv kernel/drivers/hid/usbhid/usbhid.ko ~/Desktop  # Take backup of your current 
                                                           usb mouse driver
$ sudo depmod -a                                         # Rebuild the dependency files

现在再次检查字符串“usbhid”的依赖文件。它不应该在那里!

$ cd /path/to/your/driver
$ sudo make modules_install  # Install your driver into /lib/modules/$(uname -r)/extra
$ sudo depmod -a             # Rebuild the dependency files

这一步之后,在依赖文件中搜索你的模块对应的字符串,应该是有的!从这一刻起,无论何时插入鼠标(或从引导本身),都会加载您的驱动程序,而不是原来的驱动程序。

一旦你玩完你的驱动程序,你可以复制回原来的usbhid文件到其原始目的地并重建依赖文件(sudo depmod -a)

现在我还看到您正在尝试使用供应商和设备 ID 来匹配您的设备,在这种情况下,驱动程序将仅适用于您的 鼠标。推荐的方法是使用类 ID,这使您的驱动程序适用于任何 usb 鼠标。


2) 我还阅读了 USB 核心驱动程序和 USB 设备驱动程序。那么这些 HID 驱动程序是核心驱动程序还是设备驱动程序?

usbhid基本上是一个“设备驱动程序”。驱动程序的分类可以概括为:核心驱动程序、主机 Controller 驱动程序和设备驱动程序:

设备驱动程序: 这是用于控制设备的软件。例如 USB 鼠标、基于 pci 的以太网卡、USB 随身碟、基于 i2c 的加速度计。

主机 Controller 驱动程序: 这是为控制总线 Controller 而编写的软件。例如 USB 主机 Controller (EHCI、UHCI、OHCI 等)、PCI 主机 Controller 、I2C 主 Controller 等。

核心驱动程序: 这些实际上粘合了上面讨论的驱动程序。例如 USB 核心、PCI 核心等。核心驱动程序提供辅助例程 (API),以便设备和主机 Controller 驱动程序可以使用它们(模块堆栈的概念!)。这些是将正确的设备绑定(bind)到其驱动程序的那些。核心驱动程序还提供许多其他服务。

USB 设备驱动程序示例代码:

http://lxr.free-electrons.com/source/drivers/hid/usbhid/usbmouse.c

您可以在以下位置找到 USB 主机 Controller 驱动程序:

http://lxr.free-electrons.com/source/drivers/usb/host/

USB 核心位于此处:http://lxr.free-electrons.com/source/drivers/usb/core/

我想这也回答了你的第三个问题!

希望这对您有所帮助。

关于linux - linux内核中usb鼠标使用了哪些驱动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25175960/

相关文章:

linux - 从 PowerShell 运行 Linux 命令

linux - 仅当 B、C、D、E 和 G 中的任何一个包含 Failed using Linux shell 时才打印列 A

linux-kernel - pci_enable_device 和 pcim_enable_device 有什么区别?

作为附件的 Android 设备

android - 无法通过 adb 在 Ubuntu 9.10 上访问 Motorola Milestone(HTC Magic 工作得很好)

linux - 更改 SCHED_OTHER 调度程序的时间量

linux - 是否可以在终端中搜索单词?

linux-kernel - 除了内核定时器,有没有办法在设定的时间间隔内重复执行一个功能?

c - 是否有 linux (gcc) 上使用的所有用户数据结构的引用

c++ - 使用鼠标进行非鼠标输入