Linux USB gadget 驱动复合设备


简介

一般来说,USB 设备有两种,一种是 Host,比如电脑,可以去读取其他 USB 设备的数据,另外一种是 Device,比如键盘鼠标U盘智能手机。

配置脚本

#!/bin/bash
# 卸载现有 gadget
echo "" > /sys/kernel/config/usb_gadget/g1/UDC 2>/dev/null || true
sleep 1
cd /sys/kernel/config/usb_gadget/
rm -rf g1
mkdir g1
cd g1
# ✅ 关键修复 1: 使用复合设备标准 VID/PID
echo 0x1d6b > idVendor   # Linux Foundation
echo 0x0104 > idProduct  # Multifunction Composite Gadget (必须!)
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB    # USB 2.0
# 字符串描述符
mkdir strings/0x409
echo "fedcba9876543210" > strings/0x409/serialnumber
echo "MyCompany"        > strings/0x409/manufacturer
echo "Composite Gadget" > strings/0x409/product
# 配置
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "Multifunction" > configs/c.1/strings/0x409/configuration
echo 500 > configs/c.1/MaxPower # 1000mA
# ========== Mass Storage ==========
mkdir functions/mass_storage.usb0
# 判断是否有usb.img文件 如果不存在则创建一个500MB的文件
if [ ! -f /user/local/bin/usb.img ]; then
    echo "usb.img 文件不存在"
    dd if=/dev/zero of=/user/local/bin/usb.img bs=1M count=500
    mkfs.vfat /user/local/bin/usb.img
fi
echo /user/local/bin/usb.img > functions/mass_storage.usb0/lun.0/file
echo 1 > functions/mass_storage.usb0/lun.0/removable
# ========== HID Keyboard ==========
mkdir 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
# =========== Serial ===========
mkdir -p functions/acm.usb0
# ========== RNDIS ==========
# mkdir functions/rndis.usb0
# echo 48:6f:73:74:50:43 > functions/rndis.usb0/host_addr
# echo 42:61:64:55:53:42 > functions/rndis.usb0/dev_addr
# ✅ 关键修复 2: 启用 Microsoft OS Descriptors
mkdir -p os_desc
echo "MSFT100" > os_desc/qw_sign
echo 0xcd      > os_desc/b_vendor_code
echo 1         > os_desc/use
# ✅ 关键修复 3: 确保目录名完全匹配(建议用绝对路径)
# 注意:有些内核要求 function 名不含点号,但 .usb0 通常是允许的
echo "RNDIS"    > os_desc/rndis.usb0/compatible_id
echo "57524d41" > os_desc/rndis.usb0/sub_compatible_id  # "WRMA"
# 链接所有功能
ln -s functions/mass_storage.usb0 configs/c.1/
ln -s functions/hid.usb0          configs/c.1/
ln -s functions/acm.usb0 configs/c.1/
# ln -s functions/rndis.usb0        configs/c.1/
# 启用 gadget
echo fe980000.usb > UDC
echo "✅ 复合设备已启用:MSD + HID + RNDIS"
# 调整键盘权限以避免键盘服务出错
chmod -R 777 /dev/hidg0

参考资料

https://linuxkernel.org.cn/doc/html/latest/usb/gadget_configfs.html
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/?redirectedfrom=MSDN
https://irq5.io/2016/12/22/raspberry-pi-zero-as-multiple-usb-gadgets/
https://raspberrypi.stackexchange.com/questions/77059/what-does-dtoverlay-dwc2-really-do]
https://www.raspberrypi.com/documentation/computers/os.html#usb-device-mode
https://trac.gateworks.com/wiki/linux/OTG
https://whycan.com/t_2903.html
https://docs.linuxkernel.org.cn/usb/gadget_hid.html
https://linux-sunxi.org/USB_Gadget/Ethernet#Mainline_kernel_.28via_configfs.29
https://whycan.com/t_5149.html
https://www.cnblogs.com/liqinghan/p/10005677.html
https://whycan.com/t_4195.html
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842272/Zynq+Linux+USB+Device+Driver
https://github.com/STMicroelectronics/meta-st-openstlinux/blob/openstlinux-5.4-dunfell-mp1-20-06-24/recipes-bsp/tools/usbotg-gadget-config/stm32_usbotg_eth_config.sh
https://www.kernel.org/doc/html/latest/usb/gadget_configfs.html
https://www.kernel.org/doc/Documentation/usb/gadget_configfs.txt
https://ghfast.top/raw.githubusercontent.com/8680/GOODBYEADS/master/data/rules/adblock.txt

驱动参考资料

https://wiki.sipeed.com/hardware/zh/maixsense/maixsense-a075v/install_drivers.html#%E4%B8%8B%E8%BD%BD%E9%A9%B1%E5%8A%A8

声明:一代明君的小屋|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Linux USB gadget 驱动复合设备


欢迎来到我的小屋