BigfootACA(讨论 | 贡献) (创建页面,内容为“<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 |} 也可以通过以下命令来查看 <code>mount | gre…”) |
BigfootACA(讨论 | 贡献) 无编辑摘要 |
||
(未显示同一用户的1个中间版本) | |||
第4行: | 第4行: | ||
== 概述 == | == 概述 == | ||
Linux在configfs中提供了usb_gadget用于支持USB设备模式。[[ | Linux在configfs中提供了usb_gadget用于支持USB设备模式。[[关于USB]] | ||
== 准备configfs == | == 准备configfs == | ||
第24行: | 第24行: | ||
也可以通过以下命令来查看 | 也可以通过以下命令来查看 | ||
< | <pre>mount | grep configfs</pre> | ||
<pre class="">configfs on /sys/kernel/config type configfs (rw,nosuid,nodev,noexec,relatime)</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>提供 | 注:usb_gadget的configfs接口由模块<code>libcomposite</code>提供 | ||
第35行: | 第35行: | ||
简单的使用mkdir即可创建一个gadget。如要创建一个名为my_gadget: | 简单的使用mkdir即可创建一个gadget。如要创建一个名为my_gadget: | ||
< | <pre>mkdir /sys/kernel/config/usb_gadget/my_gadget</pre> | ||
创建完成后,configfs会自动添加虚拟文件,以下是参照表 | 创建完成后,configfs会自动添加虚拟文件,以下是参照表 | ||
第93行: | 第93行: | ||
== 填写设备ID == | == 填写设备ID == | ||
< | <pre>echo 0x05F9 > /sys/kernel/config/usb_gadget/my_gadget/idVendor | ||
echo 0x1234 > /sys/kernel/config/usb_gadget/my_gadget/idProduct</ | echo 0x1234 > /sys/kernel/config/usb_gadget/my_gadget/idProduct</pre> | ||
== 填写设备字符串描述 == | == 填写设备字符串描述 == | ||
参考: [[#附注语言id|语言ID]] | 参考: [[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 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 "My Product" > /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409/product | ||
echo "123456789" > /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409/serialnumber</ | echo "123456789" > /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409/serialnumber</pre> | ||
== 创建功能 == | == 创建功能 == | ||
gadget子系统支持非常多的usb功能,也可以使用用户空间的functionfs和主机进行通信。这里演示大容量存储和RNDIS网络 | gadget子系统支持非常多的usb功能,也可以使用用户空间的functionfs和主机进行通信。这里演示大容量存储和RNDIS网络 | ||
格式:< | 格式:<pre>functions/%FUNC%.%NAME%</pre> | ||
{| class="wikitable" | {| class="wikitable" | ||
第125行: | 第125行: | ||
创建功能: | 创建功能: | ||
< | <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</ | 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的大容量存储兼容性不好,建议可以使用多个大容量存储功能替代) | Linux内核的mass_storage支持多个lun,默认会创建lun.0,也可以手动创建其它lun以映射多个设备(不推荐,多lun的大容量存储兼容性不好,建议可以使用多个大容量存储功能替代) | ||
第166行: | 第166行: | ||
创建功能: | 创建功能: | ||
< | <pre>mkdir /sys/kernel/config/usb_gadget/my_gadget/functions/rndis.my_net</pre> | ||
初始化成功后,将会创建一个usb0网卡,对端连接到主机 | 初始化成功后,将会创建一个usb0网卡,对端连接到主机 | ||
第227行: | 第227行: | ||
使用前,可以使用<code>modprobe usbfunc:功能</code>来加载所需模块。如: | 使用前,可以使用<code>modprobe usbfunc:功能</code>来加载所需模块。如: | ||
< | <pre>modprobe usbfunc:mass_storage</pre> | ||
== 创建配置 == | == 创建配置 == | ||
第248行: | 第248行: | ||
|} | |} | ||
< | <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</ | 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> | ||
=== 填写字符串描述 === | === 填写字符串描述 === | ||
参考: [[#附注语言id|语言ID]] | 参考: [[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</ | echo "MY MASS + RNDIS" > /sys/kernel/config/usb_gadget/my_gadget/configs/a.1/strings/0x0409/configuration</pre> | ||
== 启动设备 == | == 启动设备 == | ||
第265行: | 第265行: | ||
=== 查看可用 === | === 查看可用 === | ||
< | <pre>ls -l /sys/class/udc/</pre> | ||
<pre | <pre>ffff0000.usb</pre> | ||
=== 启动gadget === | === 启动gadget === | ||
< | <pre>echo ffff0000.usb > /sys/kernel/config/usb_gadget/my_gadget/UDC</pre> | ||
此时,主机会成功发现设备 | 此时,主机会成功发现设备 | ||
第294行: | 第294行: | ||
如果想要停止gadget,则直接写空即可 | 如果想要停止gadget,则直接写空即可 | ||
< | <pre>echo > /sys/kernel/config/usb_gadget/my_gadget/UDC</pre> | ||
<span id="附注语言id"></span> | <span id="附注语言id"></span> | ||
== 附注:语言ID == | == 附注:语言ID == |
2024年3月20日 (三) 12:06的最新版本
Linux USB Gadget
概述
Linux在configfs中提供了usb_gadget用于支持USB设备模式。关于USB
准备configfs
在默认情况下,系统会自动挂载configfs,根据发行版不同,可能会挂在到不同的目录:
系统 | 目录 |
---|---|
Android | /config |
GNU/Linux | /sys/kernel/config |
也可以通过以下命令来查看
mount | grep configfs
configfs on /sys/kernel/config type configfs (rw,nosuid,nodev,noexec,relatime)
如果没有挂载,也可以通过以下命令挂载
mount -t configfs configfs /sys/kernel/config
注:usb_gadget的configfs接口由模块libcomposite
提供
创建gadget
简单的使用mkdir即可创建一个gadget。如要创建一个名为my_gadget:
mkdir /sys/kernel/config/usb_gadget/my_gadget
创建完成后,configfs会自动添加虚拟文件,以下是参照表
文件/文件夹名称 | 描述 |
---|---|
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设备控制器,可以在/sys/class/udc 中选择
|
Vendor ID、Product ID列表:http://www.linux-usb.org/usb.ids
Class、SubClass、Protocol列表:https://www.usb.org/defined-class-codes
填写设备ID
echo 0x05F9 > /sys/kernel/config/usb_gadget/my_gadget/idVendor echo 0x1234 > /sys/kernel/config/usb_gadget/my_gadget/idProduct
填写设备字符串描述
参考: 语言ID
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
创建功能
gadget子系统支持非常多的usb功能,也可以使用用户空间的functionfs和主机进行通信。这里演示大容量存储和RNDIS网络
格式:
functions/%FUNC%.%NAME%
符号 | 描述 |
---|---|
FUNC | 要使用的功能名称 |
NAME | 创建的自定义名字 |
创建并配置大容量存储
创建功能:
mkdir /sys/kernel/config/usb_gadget/my_gadget/functions/mass_storage.my_img
选择设备或者镜像
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
Linux内核的mass_storage支持多个lun,默认会创建lun.0,也可以手动创建其它lun以映射多个设备(不推荐,多lun的大容量存储兼容性不好,建议可以使用多个大容量存储功能替代)
lun.X下有以下内容,可以根据情况填写
文件名 | 描述 |
---|---|
cdrom | 指示是否映射为虚拟光盘(0:普通磁盘,1:虚拟光盘) |
file | 映射的后端文件或设备绝对路径 |
forced_eject | 写入这个文件将导致lun被强制分离 |
inquiry_string | 设置显示在主机的设备名称 |
nofua | 指示是否使用SCSI FUA标志 |
removable | 指示是否可移除设备(0:不可移除设备,1:可移除设备) |
ro | 指示是否只读设备(0:可读写,1:只读) |
创建并配置RNDIS
创建功能:
mkdir /sys/kernel/config/usb_gadget/my_gadget/functions/rndis.my_net
初始化成功后,将会创建一个usb0网卡,对端连接到主机
其它功能列表
功能 | 描述 |
---|---|
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视频(摄像头) |
使用前,可以使用modprobe usbfunc:功能
来加载所需模块。如:
modprobe usbfunc:mass_storage
创建配置
创建完功能后,还需要将其链接到配置文件。默认不会创建任何配置文件,需要手动创建
创建一个配置
格式:configs/%NAME%.%INDEX%
符号 | 描述 |
---|---|
NAME | 创建的自定义名字 |
INDEX | 配置文件的序号 必须大于1,且不能重复 |
mkdir /sys/kernel/config/usb_gadget/my_gadget/configs/a.1
链接功能到配置
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
填写字符串描述
参考: 语言ID
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
启动设备
在/sys/class/udc
中有可用的USB设备器列表,将其名字写入UDC即可启动gadget
查看可用
ls -l /sys/class/udc/
ffff0000.usb
启动gadget
echo ffff0000.usb > /sys/kernel/config/usb_gadget/my_gadget/UDC
此时,主机会成功发现设备
[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
停止gadget
如果想要停止gadget,则直接写空即可
echo > /sys/kernel/config/usb_gadget/my_gadget/UDC
附注:语言ID
ID | 标识符 | 语言 |
---|---|---|
0x0409 | en-us | 英语(美国) |
0x0804 | zh-cn | 中文(中国) |
关于语言ID: https://learn.microsoft.com/en-us/windows/win32/intl/language-identifiers