You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通用Linux键盘驱动开发求助:拦截输入转发及扫描码获取遇阻

开发建议:Linux通用键盘拦截转发驱动

一、先解决usbhid编译失败问题

  • 直接复制内核源码的hid-core.c这类文件会依赖内核的其他模块和头文件,没法单独编译。正确的做法是基于当前系统的内核源码树来编译:
    1. 先安装当前内核的开发包,比如执行apt install linux-headers-$(uname -r)(Debian/Ubuntu系)或者对应发行版的内核头包。
    2. 要么把你的驱动代码放到内核源码树的drivers/hid/usbhid/目录下,要么写个极简Makefile指定内核源码路径:
      obj-m += mykbd.o
      mykbd-objs := hid-core.o [其他依赖的.c文件]
      KERNELDIR ?= /lib/modules/$(shell uname -r)/build
      PWD := $(shell pwd)
      default:
              $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
      
    3. 注意内核版本兼容性,不同内核版本的函数签名、宏定义可能有变化,别直接把高版本内核的代码拿到低版本环境编译。

二、修复无法接收扫描码的问题

  • 能匹配设备但收不到扫描码,大概率是没正确注册输入设备或者没处理USB中断传输:
    1. 检查probe函数逻辑:必须调用usb_alloc_intf_urb()分配中断URB,并且正确设置URB的回调函数来处理键盘输入数据,最后用usb_submit_urb()提交。
    2. 验证输入设备初始化:调用input_register_device()前,要把struct input_dev的位掩码配置正确——比如set_bit(EV_KEY, dev->evbit)开启按键事件,input_set_capability(dev, EV_KEY, KEY_XXX)覆盖所有按键码,不然系统不认这是键盘设备。
    3. 确认USB端点:用usb_find_int_endpoint()获取键盘的中断端点地址,别绑错成控制端点,这是常见的低级错误。
    4. 查内核日志:用dmesg或者journalctl -k看驱动加载后的日志,有没有URB提交失败、端点地址无效这类错误提示。

三、实现拦截记录+转发的核心逻辑

  • 没必要完全复制usbhid/usbkbd,基于现有驱动改更高效:
    1. 在URB的回调函数里,收到扫描码数据后,先把数据写到你指定的存储——比如内核环形缓冲区、sysfs节点,或者通过netlink发给用户态进程记录。
    2. 然后正常调用input_report_key()、input_sync()把扫描码转发给输入子系统,这样就能实现正常输入显示。
    3. 要支持任意键盘,别硬编码Vendor ID和Product ID,改成匹配HID类的键盘设备(HID_USAGE_KEYBOARD),这样所有USB键盘都会被驱动捕获。

四、实用调试技巧

  • 用cat /proc/bus/input/devices查看你的驱动是否正确注册了输入设备。
  • 安装evtest工具,直接测试对应输入设备的事件,确认有没有按键事件产生。
  • 内核里用pr_info()打印关键节点的调试信息,比如URB回调是否触发、扫描码数据是什么,一步步排查数据流是否正常。

内容的提问来源于stack exchange,提问作者kurtag1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:25:04