1. 介绍¶
- 版权:
© 1999-2001 Vojtech Pavlik <vojtech@ucw.cz> - 由 SuSE 赞助
1.1. 架构¶
输入子系统是驱动程序的集合,旨在支持Linux下的所有输入设备。大多数驱动程序位于 drivers/input 中,尽管也有一些位于 drivers/hid 和 drivers/platform 中。
输入子系统的核心是输入模块,它必须在任何其他输入模块之前加载 - 它充当两组模块之间的通信方式
1.1.1. 设备驱动程序¶
这些模块与硬件(例如通过USB)通信,并将事件(按键、鼠标移动)提供给输入模块。
1.1.2. 事件处理程序¶
这些模块从输入核心获取事件,并通过各种接口将它们传递到需要的地方 - 将按键传递到内核,将鼠标移动通过模拟的 PS/2 接口传递到 GPM 和 X,等等。
1.2. 简单用法¶
对于最常见的配置,使用一个 USB 鼠标和一个 USB 键盘,您必须加载以下模块(或将它们内置到内核中)
input
mousedev
usbcore
uhci_hcd or ohci_hcd or ehci_hcd
usbhid
hid_generic
之后,USB 键盘将立即工作,USB 鼠标将作为主设备号为 13,次设备号为 63 的字符设备可用
crw-r--r-- 1 root root 13, 63 Mar 28 22:45 mice
该设备通常由系统自动创建。手动创建它的命令是
cd /dev
mkdir input
mknod input/mice c 13 63
之后,您必须将 GPM(文本模式鼠标剪切粘贴工具)和 XFree 指向此设备才能使用它 - GPM 应该像这样调用
gpm -t ps2 -m /dev/input/mice
在 X 中
Section "Pointer"
Protocol "ImPS/2"
Device "/dev/input/mice"
ZAxisMapping 4 5
EndSection
当您完成以上所有操作后,您就可以使用您的 USB 鼠标和键盘了。
1.3. 详细描述¶
1.3.1. 事件处理程序¶
事件处理程序根据需要将设备中的事件分发给用户空间和内核中的使用者。
1.3.1.1. evdev¶
evdev
是通用的输入事件接口。它将内核中生成的事件直接传递给程序,并带有时间戳。事件代码在所有架构上都相同,并且与硬件无关。
这是用户空间消耗用户输入的首选接口,鼓励所有客户端使用它。
有关 API 的注释,请参阅 事件接口。
设备位于 /dev/input 中
crw-r--r-- 1 root root 13, 64 Apr 1 10:49 event0
crw-r--r-- 1 root root 13, 65 Apr 1 10:50 event1
crw-r--r-- 1 root root 13, 66 Apr 1 10:50 event2
crw-r--r-- 1 root root 13, 67 Apr 1 10:50 event3
...
次设备号有两个范围:64 到 95 是静态的传统范围。如果系统中存在超过 32 个输入设备,则会创建次设备号从 256 开始的其他 evdev 节点。
1.3.1.2. keyboard¶
keyboard
是内核中的输入处理程序,是 VT 代码的一部分。它消耗键盘按键并处理 VT 控制台的用户输入。
1.3.1.3. mousedev¶
mousedev
是一种使使用鼠标输入的旧程序工作的技巧。它从鼠标或数字化仪/平板电脑获取事件,并向用户空间提供 PS/2 样式(类似于 /dev/psaux)的鼠标设备。
/dev/input 中的 Mousedev 设备(如上所示)是
crw-r--r-- 1 root root 13, 32 Mar 28 22:45 mouse0
crw-r--r-- 1 root root 13, 33 Mar 29 00:41 mouse1
crw-r--r-- 1 root root 13, 34 Mar 29 00:41 mouse2
crw-r--r-- 1 root root 13, 35 Apr 1 10:50 mouse3
...
...
crw-r--r-- 1 root root 13, 62 Apr 1 10:50 mouse30
crw-r--r-- 1 root root 13, 63 Apr 1 10:50 mice
每个 mouse
设备都分配给一个鼠标或数字化仪,除了最后一个 - mice
。这个单独的字符设备由所有鼠标和数字化仪共享,即使没有连接任何设备,该设备也存在。这对于热插拔 USB 鼠标很有用,这样即使没有鼠标,不处理热插拔的旧程序也可以打开设备。
内核配置中的 CONFIG_INPUT_MOUSEDEV_SCREEN_[XY] 是 XFree86 中屏幕的大小(以像素为单位)。如果您想在 X 中使用您的数字化仪,则需要此设置,因为它的移动是通过虚拟 PS/2 鼠标发送到 X 的,因此需要相应地进行缩放。如果仅使用鼠标,则不会使用这些值。
Mousedev 将生成 PS/2、ImPS/2(Microsoft IntelliMouse)或 ExplorerPS/2(IntelliMouse Explorer)协议,具体取决于读取数据的程序希望使用哪种协议。您可以将 GPM 和 X 设置为其中任何一个。如果您想使用 USB 鼠标上的滚轮,则需要 ImPS/2;如果您想使用额外的(最多 5 个)按钮,则需要 ExplorerPS/2。
1.3.1.4. joydev¶
joydev
实现 v0.x 和 v1.x Linux 操纵杆 API。 有关详细信息,请参阅 编程接口。
一旦连接了任何操纵杆,就可以在 /dev/input 中访问它,地址如下:
crw-r--r-- 1 root root 13, 0 Apr 1 10:50 js0
crw-r--r-- 1 root root 13, 1 Apr 1 10:50 js1
crw-r--r-- 1 root root 13, 2 Apr 1 10:50 js2
crw-r--r-- 1 root root 13, 3 Apr 1 10:50 js3
...
等等,直到传统范围内的 js31,如果存在更多操纵杆设备,则会添加次设备号大于 256 的其他节点。
1.3.2. 设备驱动程序¶
设备驱动程序是生成事件的模块。
1.3.2.1. hid-generic¶
hid-generic
是整个套件中最大、最复杂的驱动程序之一。它处理所有 HID 设备,并且由于它们的种类繁多,并且由于 USB HID 规范并不简单,因此它需要这么大。
目前,它处理 USB 鼠标、操纵杆、游戏手柄、方向盘、键盘、轨迹球和数字化仪。
但是,USB 也将 HID 用于显示器控制、扬声器控制、UPS、LCD 和许多其他用途。
显示器和扬声器控制应该很容易添加到 hid/input 接口中,但对于 UPS 和 LCD 来说意义不大。为此,设计了 hiddev 接口。有关更多信息,请参阅 人机接口设备的维护和使用。
usbhid 模块的使用非常简单,它不带任何参数,会自动检测所有内容,并且在插入 HID 设备时,它会正确检测到它。
但是,由于设备差异很大,您可能会遇到运行不佳的设备。在这种情况下,请在 hid-core.c 的开头 #define DEBUG 并将 syslog 跟踪发送给我。
1.3.2.2. usbmouse¶
对于嵌入式系统,对于 HID 描述符损坏的鼠标,以及任何其他不适合使用大型 usbhid 的情况,可以使用 usbmouse 驱动程序。它仅处理 USB 鼠标。它使用更简单的 HIDBP 协议。这也意味着鼠标必须支持此更简单的协议。并非所有鼠标都支持。如果您没有使用此模块的充分理由,请改用 usbhid。
1.3.2.3. usbkbd¶
与 usbmouse 非常相似,此模块使用简化的 HIDBP 协议与键盘通信。它更小,但不支持任何额外的特殊按键。如果没有使用它的特殊原因,请改用 usbhid。
1.3.2.4. psmouse¶
这是使用 PS/2 协议的所有类型的指点设备的驱动程序,包括 Synaptics 和 ALPS 触摸板、Intellimouse Explorer 设备、Logitech PS/2 鼠标等等。
1.3.2.5. atkbd¶
这是 PS/2 (AT) 键盘的驱动程序。
1.3.2.6. iforce¶
用于 I-Force 操纵杆和方向盘的驱动程序,包括 USB 和 RS232。它现在包括力反馈支持,即使 Immersion Corp. 认为该协议是商业秘密,也不会透露一个字。
1.4. 验证它是否工作¶
在键盘上输入几个按键应该足以检查键盘是否正常工作并且已正确连接到内核键盘驱动程序。
执行 cat /dev/input/mouse0
(c, 13, 32) 将验证鼠标是否也被模拟;如果移动它,应该会出现字符。
您可以使用操纵杆包中提供的 jstest
实用程序测试操纵杆模拟(请参阅 介绍)。
您可以使用 evtest
实用程序测试事件设备。
1.5. 事件接口¶
您可以使用阻塞和非阻塞读取,也可以在 /dev/input/eventX 设备上使用 select(),并且在读取时始终会获得整数个输入事件。它们的布局是
struct input_event {
struct timeval time;
unsigned short type;
unsigned short code;
int value;
};
time
是时间戳,它返回事件发生的时间。Type 例如是相对移动的 EV_REL,或按键或释放的 EV_KEY。更多类型在 include/uapi/linux/input-event-codes.h 中定义。
code
是事件代码,例如 REL_X 或 KEY_BACKSPACE,完整的列表也在 include/uapi/linux/input-event-codes.h 中。
value
是事件携带的值。对于 EV_REL,它表示相对变化;对于 EV_ABS (操纵杆等),它表示绝对新值;对于 EV_KEY,0 表示释放,1 表示按下,2 表示自动重复。
有关各种事件代码的更多信息,请参阅 输入事件代码。