Evdev 字符设备、缓冲与 ioctl

Evdev 字符设备、缓冲与 ioctl

1. 定位

evdev是现代 Linux/Android主要输入 ABI:

1
2
/dev/input/eventN
major 13, minor 64+

evdev_handler 按能力匹配几乎所有 input device。

2. Connect

1
2
3
4
5
evdev_connect()
-> allocate evdev + input_handle
-> input_register_handle()
-> allocate input minor
-> cdev/device_add

每个 open file创建独立 evdev_client和 ring buffer。

3. Open

首次 evdev client使 handle input_open_device(),进而可能启动真实硬件。close移除 client、释放 grab并在最后用户时关闭 device。

4. 输入路径

1
2
3
4
5
handler->events()
-> evdev_pass_values()
-> each client buffer
-> wake_up_interruptible/poll async
-> userspace read()

每个 reader有独立消费速度,慢 reader不会阻塞 IRQ和其它 reader。

5. 溢出

client buffer满时 evdev标记 packet丢失并插入 SYN_DROPPED恢复协议。应用必须实现状态重同步,不能只记录日志后继续解释增量。

6. Read/poll

  • blocking/nonblocking read;
  • poll/epoll;
  • async SIGIO;
  • 每次读取完整 struct input_event
  • device断开后返回相应 EOF/errno并唤醒等待者。

7. 常用 ioctl

  • EVIOCGVERSION
  • EVIOCGID/NAME/PHYS/UNIQ
  • EVIOCGBIT
  • EVIOCGABS/EVIOCSABS
  • EVIOCGKEY/LED/SW
  • EVIOCGKEYCODE/EVIOCSKEYCODE
  • EVIOCGREP/EVIOCSREP
  • EVIOCSCLOCKID
  • EVIOCGRAB
  • EVIOCREVOKE
  • FF upload/erase。

8. Grab/revoke

EVIOCGRAB 让该 evdev handle独占整个 input device,其他 handler也不再接收事件。EVIOCREVOKE 撤销当前 client后续访问,适合会话切换。

9. Compat

32位用户态在64位内核上由 input-compat.c 和 evdev compat ioctl转换时间与结构。不能直接假设 native struct布局。

10. 权限

读取键盘 event可窃取密码,写/uinput可伪造输入。通常由 udev设置 input group和 seat ACL;服务只授权所需节点,不应开放整个 /dev/input

文章互动

阅读 --

留言

0 条留言

正在加载留言…