Evdev 字符设备、缓冲与 ioctl
1. 定位
evdev是现代 Linux/Android主要输入 ABI:
1 | /dev/input/eventN |
evdev_handler 按能力匹配几乎所有 input device。
2. Connect
1 | evdev_connect() |
每个 open file创建独立 evdev_client和 ring buffer。
3. Open
首次 evdev client使 handle input_open_device(),进而可能启动真实硬件。close移除 client、释放 grab并在最后用户时关闭 device。
4. 输入路径
1 | handler->events() |
每个 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。
正在加载留言…