打开/关闭搜索
搜索
打开/关闭菜单
通知
打开/关闭个人菜单
查看“USB Gadget”的源代码
来自Uotan Wiki · 刷机百科
查看
阅读
查看源代码
查看历史
associated-pages
页面
讨论
更多操作
←
USB Gadget
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
<span id="linux-usb-gadget"></span> = Linux USB Gadget = == 概述 == Linux在configfs中提供了usb_gadget用于支持USB设备模式。[[关于USB]] == 准备configfs == 在默认情况下,系统会自动挂载configfs,根据发行版不同,可能会挂在到不同的目录: {| class="wikitable" |- ! 系统 ! 目录 |- | Android | /config |- | GNU/Linux | /sys/kernel/config |} 也可以通过以下命令来查看 <pre>mount | grep configfs</pre> <pre class="">configfs on /sys/kernel/config type configfs (rw,nosuid,nodev,noexec,relatime)</pre> 如果没有挂载,也可以通过以下命令挂载 <pre>mount -t configfs configfs /sys/kernel/config</pre> 注:usb_gadget的configfs接口由模块<code>libcomposite</code>提供 == 创建gadget == 简单的使用mkdir即可创建一个gadget。如要创建一个名为my_gadget: <pre>mkdir /sys/kernel/config/usb_gadget/my_gadget</pre> 创建完成后,configfs会自动添加虚拟文件,以下是参照表 {| class="wikitable" |- ! 文件/文件夹名称 ! 描述 |- | bcdDevice | 设备版本,使用带0x前缀的四个十六进制数字(0x1234,0x89AB) |- | bcdUSB | USB的协议版本,使用带0x前缀的四个十六进制数字(0x0200,0x0301) |- | idProduct | USB设备的产品ID,使用带0x前缀的四个十六进制数字(0x1234,0x89AB) |- | idVendor | USB设备的制造商ID,使用带0x前缀的四个十六进制数字(0x1234,0x89AB) |- | bDeviceClass | USB设备识别的设备类,使用带0x前缀的两个十六进制数字(0x34,0x9A) |- | bDeviceSubClass | USB设备识别的设备子类,使用带0x前缀的两个十六进制数字(0x34,0x9A) |- | bDeviceProtocol | USB设备识别的设备协议,使用带0x前缀的两个十六进制数字(0x34,0x9A) |- | bMaxPacketSize0 | 单次包最大传输大小 |- | configs/ | gadget的配置文件 |- | functions/ | gadget的子功能 |- | strings/ | 向主机上报的设备名称 |- | max_speed | 支持的最大速度 |- | os_desc | 向主机展示的操作系统相关的描述 |- | UDC | 使用的USB设备控制器,可以在<code>/sys/class/udc</code>中选择 |} Vendor ID、Product ID列表:http://www.linux-usb.org/usb.ids Class、SubClass、Protocol列表:https://www.usb.org/defined-class-codes <span id="填写设备id"></span> == 填写设备ID == <pre>echo 0x05F9 > /sys/kernel/config/usb_gadget/my_gadget/idVendor echo 0x1234 > /sys/kernel/config/usb_gadget/my_gadget/idProduct</pre> == 填写设备字符串描述 == 参考: [[USB Gadget#附注语言id|语言ID]] <pre>mkdir /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409 echo "My Vendor" > /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409/manufacturer echo "My Product" > /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409/product echo "123456789" > /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409/serialnumber</pre> == 创建功能 == gadget子系统支持非常多的usb功能,也可以使用用户空间的functionfs和主机进行通信。这里演示大容量存储和RNDIS网络 格式:<pre>functions/%FUNC%.%NAME%</pre> {| class="wikitable" |- ! 符号 ! 描述 |- | FUNC | 要使用的功能名称 |- | NAME | 创建的自定义名字 |} ==== 创建并配置大容量存储 ==== 创建功能: <pre>mkdir /sys/kernel/config/usb_gadget/my_gadget/functions/mass_storage.my_img</pre> 选择设备或者镜像 <pre>echo /mnt/a_virtual_disk.img > /sys/kernel/config/usb_gadget/my_gadget/functions/mass_storage.my_img/lun.0/file echo 1 > /sys/kernel/config/usb_gadget/my_gadget/functions/mass_storage.my_img/lun.0/removable</pre> Linux内核的mass_storage支持多个lun,默认会创建lun.0,也可以手动创建其它lun以映射多个设备(不推荐,多lun的大容量存储兼容性不好,建议可以使用多个大容量存储功能替代) lun.X下有以下内容,可以根据情况填写 {| class="wikitable" |- ! 文件名 ! 描述 |- | cdrom | 指示是否映射为虚拟光盘(0:普通磁盘,1:虚拟光盘) |- | file | 映射的后端文件或设备绝对路径 |- | forced_eject | 写入这个文件将导致lun被强制分离 |- | inquiry_string | 设置显示在主机的设备名称 |- | nofua | 指示是否使用SCSI FUA标志 |- | removable | 指示是否可移除设备(0:不可移除设备,1:可移除设备) |- | ro | 指示是否只读设备(0:可读写,1:只读) |} <span id="创建并配置rndis"></span> ==== 创建并配置RNDIS ==== 创建功能: <pre>mkdir /sys/kernel/config/usb_gadget/my_gadget/functions/rndis.my_net</pre> 初始化成功后,将会创建一个usb0网卡,对端连接到主机 ==== 其它功能列表 ==== {| class="wikitable" |- ! 功能 ! 描述 |- | mass_storage | 大容量存储(BOT协议) |- | rndis | RNDIS虚拟网卡 |- | ffs | FunctionFS 用户空间设备 |- | acm | CDC ACM虚拟串口 |- | obex | CDC OBEX对象交换 |- | ecm | CDC ECM虚拟网卡 |- | eem | CDC EEM虚拟网卡 |- | ncm | CDC NCM虚拟网卡 |- | geth | CDC Subset虚拟网卡 |- | gser | USB串口 |- | hid | HID 人类输入设备(鼠标/键盘等) |- | printer | 模拟打印机 |- | tcm | SCSI目标映射大容量存储 (UASP协议) |- | uac1 | USB音频1.0 |- | uac2 | USB音频2.0 |- | uvc | USB视频(摄像头) |} 使用前,可以使用<code>modprobe usbfunc:功能</code>来加载所需模块。如: <pre>modprobe usbfunc:mass_storage</pre> == 创建配置 == 创建完功能后,还需要将其链接到配置文件。默认不会创建任何配置文件,需要手动创建 === 创建一个配置 === 格式:<code>configs/%NAME%.%INDEX%</code> {| class="wikitable" |- ! 符号 ! 描述 |- | NAME | 创建的自定义名字 |- | INDEX | 配置文件的序号 必须大于1,且不能重复 |} <pre>mkdir /sys/kernel/config/usb_gadget/my_gadget/configs/a.1</pre> === 链接功能到配置 === <pre>ln -s /sys/kernel/config/usb_gadget/my_gadget/functions/mass_storage.my_img /sys/kernel/config/usb_gadget/my_gadget/configs/a.1/my_func.1 ln -s /sys/kernel/config/usb_gadget/my_gadget/functions/rndis.my_net /sys/kernel/config/usb_gadget/my_gadget/configs/a.1/my_func.2</pre> === 填写字符串描述 === 参考: [[USB Gadget#附注语言id|语言ID]] <pre>mkdir /sys/kernel/config/usb_gadget/my_gadget/configs/a.1/strings/0x0409 echo "MY MASS + RNDIS" > /sys/kernel/config/usb_gadget/my_gadget/configs/a.1/strings/0x0409/configuration</pre> == 启动设备 == 在<code>/sys/class/udc</code>中有可用的USB设备器列表,将其名字写入UDC即可启动gadget === 查看可用 === <pre>ls -l /sys/class/udc/</pre> <pre>ffff0000.usb</pre> === 启动gadget === <pre>echo ffff0000.usb > /sys/kernel/config/usb_gadget/my_gadget/UDC</pre> 此时,主机会成功发现设备 <pre class="">[12345.000000] usb 1-1.1: new high-speed USB device number 1 using xhci_hcd [12345.000015] usb 1-1.1: New USB device found, idVendor=05f9, idProduct=1234, bcdDevice= 6.08 [12345.000030] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [12345.000045] usb 1-1.1: Product: My Product [12345.000060] usb 1-1.1: Manufacturer: My Vendor [12345.000075] usb 1-1.1: SerialNumber: 123456789 [12345.000100] usb-storage 1-1.1:1.0: USB Mass Storage device detected [12345.000115] scsi host0: usb-storage 1-1.1:1.0 [12345.000130] scsi 0:0:0:0: Direct-Access Linux UMS disk 0 ffff PQ: 0 ANSI: 2 [12345.000145] sd 0:0:0:0: Attached scsi generic sg0 type 0 [12345.000160] sd 0:0:0:0: [sda] 61071360 512-byte logical blocks: (31.3 GB/29.1 GiB) [12345.000175] sd 0:0:0:0: [sda] Write Protect is off [12345.000190] sd 0:0:0:0: [sda] Mode Sense: 0f 00 00 00 [12345.000205] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA [12345.000220] sda: sda1 [12345.000235] sd 0:0:0:0: [sda] Attached SCSI removable disk [12345.000300] rndis_host 1-1.1:1.1 usb0: register 'rndis_host' at usb-0000:01:00.0-1.1, RNDIS device, 1a:2b:3c:4d:5e:6f [12345.000315] rndis_host 1-1.1:1.1 enp1s0u1u1: renamed from usb0</pre> === 停止gadget === 如果想要停止gadget,则直接写空即可 <pre>echo > /sys/kernel/config/usb_gadget/my_gadget/UDC</pre> <span id="附注语言id"></span> == 附注:语言ID == {| class="wikitable" |- ! ID ! 标识符 ! 语言 |- | 0x0409 | en-us | 英语(美国) |- | 0x0804 | zh-cn | 中文(中国) |} 关于语言ID: https://learn.microsoft.com/en-us/windows/win32/intl/language-identifiers
返回
USB Gadget
。