当前位置: 首页 > news >正文

从零构建:基于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的关键。相比树莓派需要额外芯片支持OTG,RK3568原生支持让整个方案更加稳定可靠。

2. 内核配置:打好基础

2.1 编译前的准备工作

拿到开发板第一件事就是确认内核配置。我建议直接从官方SDK开始,避免自己从头编译的麻烦。Rockchip的Linux SDK已经包含了大部分我们需要的内容,但还需要确认几个关键配置:

cd ~/rk3568_linux_sdk make menuconfig

在图形界面中,我们需要确保以下选项被启用:

  • CONFIG_USB_CONFIGFS=y
  • CONFIG_USB_LIBCOMPOSITE=y
  • CONFIG_USB_CONFIGFS_F_HID=y
  • CONFIG_USB_CONFIGFS_MASS_STORAGE=y

这些配置项让内核支持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"的gadget:

cd /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/product

3.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_desc

3.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 bs=1M count=1024 mkfs.vfat /usbdisk.img echo /usbdisk.img > functions/mass_storage.0/lun.0/file

4. 功能整合与启动脚本

4.1 创建配置描述

现在我们需要把各个功能整合到一个USB配置中:

mkdir configs/c.1 mkdir configs/c.1/strings/0x409 echo "HID+UMS 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 "HID+UMS 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.sh

5. 功能测试与验证

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

常见问题包括:

  1. 内核配置不正确,缺少必要的模块
  2. USB线不支持数据传输(有些线只能充电)
  3. OTG模式未正确启用

6.2 HID功能不正常

如果键盘或鼠标工作不正常,检查:

  1. HID报告描述符是否正确
  2. /dev/hidg*设备节点是否存在
  3. 写入的数据格式是否符合报告描述符定义

6.3 UMS功能问题

U盘功能常见问题:

  1. 指定的存储设备或镜像文件不存在
  2. 文件系统不被Windows识别(建议使用FAT32)
  3. 分区被目标主机挂载(需要先卸载)

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方案。主要包括:

  1. 视频采集(通过HDMI采集卡)
  2. 网络服务(提供Web控制界面)
  3. 电源管理(控制目标主机开关机)

RK3568的强大性能完全可以胜任这些任务,而且成本远低于商业KVM解决方案。

http://www.cnnetsun.cn/news/1983073.html

相关文章:

  • RetDec解密:如何让机器码“开口说话”?重构二进制逆向分析的技术范式
  • 告别‘True’焦虑:TensorFlow-GPU安装后,用这5个测试方法彻底验证你的CUDA环境是否真的能用
  • UWB-DW1000初始化、发送和接收详解(一):从零构建双向测距通信链路
  • QT+OpenCV项目实战:给你的视觉软件装上‘快搜’引擎,基于NCC的模板匹配保姆级集成教程
  • CVE-2026-39808 PoC 公开:FortiSandbox 无需认证 root RCE,全网已遭大规模扫描
  • Agora RTM不只是发消息:5个你可能不知道的实时互动场景实战(含状态同步、呼叫邀请)
  • 产品路线图软件怎么选?7款适合产品团队的工具盘点
  • 终极指南:如何用 res-downloader 一站式搞定全网视频音频资源下载
  • 从实验室到野外:手把手教你用热乙醇法测水体叶绿素a(附721分光光度计操作避坑指南)
  • 防勒索病毒的最后一道防线:用Syncthing在Linux服务器搭建带版本历史的‘冷备份’
  • FTDI D2XX驱动在ARM开发板(如树莓派)上的交叉编译与部署避坑指南
  • 如何快速掌握Cats Blender插件:VRChat模型优化的完整实践指南
  • Windows Cleaner:免费高效的Windows系统清理工具终极指南
  • LVGL图片转换工具深度体验:除了转C数组,这些隐藏功能让你的UI开发效率翻倍
  • 新手避坑指南:Pspice仿真第一步,为什么必须要有GND且不能改名?
  • 告别盲调:在KEIL中精准监控与优化栈空间使用
  • 共享内存数据残留怎么办?深入理解shmget/shmctl的生命周期管理与清理实战
  • Jetson设备jtop版本冲突实战:宿主机与虚拟环境版本对齐与降级指南
  • 告别理论:用Mahout和MovieLens数据集,5步搭建你的第一个电影推荐Demo
  • Qwen3-TTS-12Hz-1.7B-VoiceDesign实战:语音克隆SaaS平台开发
  • G-Helper终极指南:如何用10MB开源工具彻底解放华硕笔记本性能
  • 别再用‘感觉’选线路了!手把手教你用FortiGate的SLA功能,给家里两条宽带做个‘体检’
  • 【USB】macOS内核态USB驱动实战:从零构建与调试
  • 告别LVDS布线噩梦:手把手教你用JESD204B协议搞定高速ADC/DAC接口(附Subclass1配置要点)
  • 告别卫星通信:实测用2.4GHz Wi-Fi搭建低成本船岸数据链路(含信号实测分析)
  • 企业级Java代码静态分析平台深度技术解析:架构设计与性能基准测试
  • 从LTE到5G NR:SSB时频结构设计演进背后的工程权衡与设计哲学
  • 从Mask ROM到Flash:一个嵌入式工程师的存储器选型避坑指南(含成本与可靠性分析)
  • 避坑指南:车载毫米波雷达研发中那些容易被忽略的‘非技术’细节(车规、测试、天线罩设计)
  • 实时情绪识别+动态话术生成,深度拆解头部银行AGI客服上线首月NPS提升37%的底层架构