1. 简介

版权所有:

© 1999-2001 Vojtech Pavlik <vojtech@ucw.cz> - 由SuSE赞助

1.1. 架构

输入子系统是一个驱动程序的集合,旨在支持Linux下的所有输入设备。 大部分驱动程序位于drivers/input中,但也有一些位于drivers/hid和drivers/platform中。

输入子系统的核心是input模块,它必须在任何其他输入模块之前加载 - 它充当两组模块之间的通信方式

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个输入设备,则将创建额外的evdev节点,其次设备号从256开始。

1.3.1.2. keyboard

keyboard是内核中的输入处理程序,是VT代码的一部分。 它使用键盘击键并处理VT控制台的用户输入。

1.3.1.3. mousedev

mousedev是一种黑客手段,用于使使用鼠标输入的旧程序能够工作。 它从鼠标或数字化仪/平板电脑获取事件,并向用户空间提供PS/2风格(类似于/dev/psaux)的鼠标设备。

Mousedev设备位于/dev/input中(如上所示)

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设备,并且由于HID设备种类繁多,并且USB HID规范并不简单,因此需要这么大。

当前,它处理USB鼠标,游戏杆,游戏手柄,方向盘,键盘,轨迹球和数字化仪。

但是,USB也使用HID进行显示器控制,扬声器控制,UPS,LCD和许多其他目的。

显示器和扬声器控件应该很容易添加到hid/input接口,但是对于UPS和LCD,这没有多大意义。 为此,设计了hiddev接口。 有关更多信息,请参见Care and feeding of your Human Interface Devices

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。 现在它包括Force Feedback支持,即使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表示自动重复。

有关各种事件代码的更多信息,请参见输入事件代码