从零构建:基于RK3568 USB Gadget的IP-KVM核心功能实现

张开发
2026/4/19 19:31:30 15 分钟阅读

分享文章

从零构建:基于RK3568 USB Gadget的IP-KVM核心功能实现
1. RK3568与IP-KVM的奇妙组合第一次听说IP-KVM这个概念时我正为远程管理机房服务器发愁。传统的KVM切换器价格昂贵而基于树莓派的PiKVM项目让我眼前一亮。不过树莓派现在价格飞涨我开始寻找替代方案RK3568开发板就这样进入了我的视野。RK3568是瑞芯微推出的一款中高端ARM处理器四核Cortex-A55架构主频可达2GHz性能完全碾压树莓派4。更重要的是它原生支持USB Gadget功能这意味着我们可以把它变成一个USB外设模拟键盘、鼠标甚至U盘。想象一下把开发板通过USB线连接到目标主机就能通过网络远程控制这台主机这就是IP-KVM的核心魔法。我手头的这块RK3568开发板是Firefly的ROC-RK3568-PC带有一个USB3.0 OTG接口。OTG(On-The-Go)技术让这个接口可以在主机(host)和设备(device)模式间切换这正是实现USB Gadget的关键。相比树莓派需要额外芯片支持OTGRK3568原生支持让整个方案更加稳定可靠。2. 内核配置打好基础2.1 编译前的准备工作拿到开发板第一件事就是确认内核配置。我建议直接从官方SDK开始避免自己从头编译的麻烦。Rockchip的Linux SDK已经包含了大部分我们需要的内容但还需要确认几个关键配置cd ~/rk3568_linux_sdk make menuconfig在图形界面中我们需要确保以下选项被启用CONFIG_USB_CONFIGFSyCONFIG_USB_LIBCOMPOSITEyCONFIG_USB_CONFIGFS_F_HIDyCONFIG_USB_CONFIGFS_MASS_STORAGEy这些配置项让内核支持USB Gadget功能框架和具体的HID(人机接口设备)、UMS(USB大容量存储)功能。如果你像我一样喜欢直接修改配置文件可以编辑kernel/arch/arm64/configs/rockchip_linux_defconfig确保这些选项都是y。2.2 编译与烧录配置完成后编译内核就很简单了./build.sh kernel这个命令会在kernel目录下生成新的内核镜像。我建议先备份原来的boot.img然后再用新的内核替换cp out/target/product/rk3568/boot.img boot.img.bak ./mkimage.sh烧录新固件到开发板时记得让开发板进入loader模式通常是通过按住某个按键再上电。我用的工具是RKDevTool界面虽然复古但很稳定。烧录完成后重启开发板我们可以通过以下命令确认HID模块是否加载成功ls /dev/hid*如果看到/dev/hidg0和/dev/hidg1这样的设备节点说明内核配置已经正确生效了。3. USB Gadget配置实战3.1 理解configfs机制Linux内核通过configfs来动态配置USB Gadget功能这比传统的静态编译灵活多了。简单来说configfs提供了一个虚拟文件系统我们可以通过创建目录和写入文件来定义USB设备的功能。在RK3568上相关操作都在/sys/kernel/config/usb_gadget/目录下进行。我习惯先创建一个名为rockchip的gadgetcd /sys/kernel/config/usb_gadget/ mkdir rockchip cd rockchip接下来需要定义这个USB设备的基本信息包括厂商ID、产品ID等。Rockchip的默认脚本会处理这些但了解原理很重要echo 0x2207 idVendor # Rockchip的厂商ID echo 0x310c idProduct # 自定义产品ID mkdir strings/0x409 # 英文语言支持 echo 123456789 strings/0x409/serialnumber echo Rockchip strings/0x409/manufacturer echo RK3568 HID Gadget strings/0x409/product3.2 配置HID功能现在来到最核心的部分——配置键盘和鼠标功能。我们需要创建两个HID功能实例mkdir functions/hid.usb0 # 键盘 mkdir functions/hid.usb1 # 鼠标键盘的配置相对复杂需要定义HID报告描述符。这个描述符告诉主机如何解析我们发送的数据。下面是我调试多次后确定的最佳配置# 键盘配置 echo 1 functions/hid.usb0/protocol # 键盘协议 echo 1 functions/hid.usb0/subclass # Boot接口子类 echo 8 functions/hid.usb0/report_length # 报告长度8字节 # 键盘HID描述符 echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 functions/hid.usb0/report_desc鼠标的配置稍微简单些# 鼠标配置 echo 2 functions/hid.usb1/protocol # 鼠标协议 echo 1 functions/hid.usb1/subclass echo 3 functions/hid.usb1/report_length # 3字节报告 # 鼠标HID描述符 echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0 functions/hid.usb1/report_desc3.3 集成UMS功能一个完整的IP-KVM还需要模拟U盘功能用于远程安装系统等场景。添加UMS功能很简单mkdir functions/mass_storage.0 echo /dev/mmcblk1p4 functions/mass_storage.0/lun.0/file # 使用SD卡的第四个分区这里我使用的是SD卡的一个分区作为虚拟U盘的内容。你也可以使用镜像文件dd if/dev/zero of/usbdisk.img bs1M count1024 mkfs.vfat /usbdisk.img echo /usbdisk.img functions/mass_storage.0/lun.0/file4. 功能整合与启动脚本4.1 创建配置描述现在我们需要把各个功能整合到一个USB配置中mkdir configs/c.1 mkdir configs/c.1/strings/0x409 echo HIDUMS Config configs/c.1/strings/0x409/configuration # 将功能添加到配置 ln -s functions/hid.usb0 configs/c.1/ ln -s functions/hid.usb1 configs/c.1/ ln -s functions/mass_storage.0 configs/c.1/4.2 自动化脚本手动输入这么多命令太麻烦了我创建了一个启动脚本/usr/local/bin/start_gadget.sh#!/bin/bash cd /sys/kernel/config/usb_gadget/ mkdir -p rockchip cd rockchip echo 0x2207 idVendor echo 0x310c idProduct mkdir -p strings/0x409 echo 123456789 strings/0x409/serialnumber echo Rockchip strings/0x409/manufacturer echo RK3568 HID Gadget strings/0x409/product mkdir -p functions/hid.usb0 echo 1 functions/hid.usb0/protocol echo 1 functions/hid.usb0/subclass echo 8 functions/hid.usb0/report_length echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 functions/hid.usb0/report_desc mkdir -p functions/hid.usb1 echo 2 functions/hid.usb1/protocol echo 1 functions/hid.usb1/subclass echo 3 functions/hid.usb1/report_length echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0 functions/hid.usb1/report_desc mkdir -p functions/mass_storage.0 echo /dev/mmcblk1p4 functions/mass_storage.0/lun.0/file mkdir -p configs/c.1 mkdir -p configs/c.1/strings/0x409 echo HIDUMS Config configs/c.1/strings/0x409/configuration ln -s functions/hid.usb0 configs/c.1/ ln -s functions/hid.usb1 configs/c.1/ ln -s functions/mass_storage.0 configs/c.1/ udevadm settle -t 5 || : ls /sys/class/udc UDC记得给脚本执行权限chmod x /usr/local/bin/start_gadget.sh5. 功能测试与验证5.1 基本功能测试配置完成后把开发板通过USB线连接到一台电脑上。在Linux主机上可以运行lsusb查看设备lsusb -d 2207:310c应该能看到类似这样的输出Bus 003 Device 007: ID 2207:310c Rockchip RK3568 HID Gadget在Windows设备管理器中应该能看到新添加的HID键盘和鼠标设备。5.2 发送键盘鼠标事件测试键盘功能我们可以直接向/dev/hidg0写入数据。我找到了一个很好的测试工具hid_gadget_test// hid_gadget_test.c #include linux/input.h #include linux/uinput.h #include fcntl.h #include stdio.h #include string.h #include unistd.h int main(int argc, char *argv[]) { int fd open(/dev/hidg0, O_RDWR); if (fd 0) { perror(Unable to open device); return 1; } char buf[8] {0}; buf[0] 0x02; // Left Shift buf[2] 0x04; // a键 write(fd, buf, 8); memset(buf, 0, 8); write(fd, buf, 8); // 释放所有键 close(fd); return 0; }编译并运行这个程序连接的电脑上应该能看到输入了一个大写的A。5.3 鼠标移动测试测试鼠标功能类似向/dev/hidg1写入数据int fd open(/dev/hidg1, O_RDWR); char buf[3] {0x00, 0x10, 0x10}; // 鼠标右下方移动 write(fd, buf, 3); close(fd);这段代码会让鼠标指针向右下方移动。实际项目中我们需要将这些操作与网络接口对接实现真正的远程控制。6. 常见问题排查6.1 USB设备未被识别如果电脑没有识别到USB设备首先检查内核日志dmesg | grep gadget常见问题包括内核配置不正确缺少必要的模块USB线不支持数据传输有些线只能充电OTG模式未正确启用6.2 HID功能不正常如果键盘或鼠标工作不正常检查HID报告描述符是否正确/dev/hidg*设备节点是否存在写入的数据格式是否符合报告描述符定义6.3 UMS功能问题U盘功能常见问题指定的存储设备或镜像文件不存在文件系统不被Windows识别建议使用FAT32分区被目标主机挂载需要先卸载7. 进阶优化方向7.1 性能优化默认配置可能无法满足高频率的鼠标移动需求。我们可以调整USB配置提高性能echo 512 configs/c.1/MaxPower # 提高供电需求 echo high configs/c.1/bmAttributes # 启用远程唤醒7.2 多配置支持有时候我们需要不同的功能组合可以创建多个配置mkdir configs/c.2 echo HID Only configs/c.2/strings/0x409/configuration ln -s functions/hid.usb0 configs/c.2/ ln -s functions/hid.usb1 configs/c.2/然后通过脚本切换活动配置。7.3 与PiKVM项目集成完成这些基础工作后我们可以考虑集成PiKVM的软件部分实现完整的IP-KVM方案。主要包括视频采集通过HDMI采集卡网络服务提供Web控制界面电源管理控制目标主机开关机RK3568的强大性能完全可以胜任这些任务而且成本远低于商业KVM解决方案。

更多文章