USB Gadget:修订间差异

来自Uotan Wiki · 刷机百科
(创建页面,内容为“<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…”)
 
无编辑摘要
第24行: 第24行:
也可以通过以下命令来查看
也可以通过以下命令来查看


<code>mount | grep configfs</code>
<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>
如果没有挂载,也可以通过以下命令挂载
如果没有挂载,也可以通过以下命令挂载


<code>mount -t configfs configfs /sys/kernel/config</code>
<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:


<code>mkdir /sys/kernel/config/usb_gadget/my_gadget</code>
<pre>mkdir /sys/kernel/config/usb_gadget/my_gadget</pre>
创建完成后,configfs会自动添加虚拟文件,以下是参照表
创建完成后,configfs会自动添加虚拟文件,以下是参照表


第93行: 第93行:
== 填写设备ID ==
== 填写设备ID ==


<code>echo 0x05F9 > /sys/kernel/config/usb_gadget/my_gadget/idVendor
<pre>echo 0x05F9 > /sys/kernel/config/usb_gadget/my_gadget/idVendor
echo 0x1234 > /sys/kernel/config/usb_gadget/my_gadget/idProduct</code>
echo 0x1234 > /sys/kernel/config/usb_gadget/my_gadget/idProduct</pre>
== 填写设备字符串描述 ==
== 填写设备字符串描述 ==


参考: [[#附注语言id|语言ID]]
参考: [[#附注语言id|语言ID]]


<code>mkdir /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409
<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</code>
echo "123456789" > /sys/kernel/config/usb_gadget/my_gadget/strings/0x0409/serialnumber</pre>
== 创建功能 ==
== 创建功能 ==


gadget子系统支持非常多的usb功能,也可以使用用户空间的functionfs和主机进行通信。这里演示大容量存储和RNDIS网络
gadget子系统支持非常多的usb功能,也可以使用用户空间的functionfs和主机进行通信。这里演示大容量存储和RNDIS网络


格式:<code>functions/%FUNC%.%NAME%</code>
格式:<pre>functions/%FUNC%.%NAME%</pre>


{| class="wikitable"
{| class="wikitable"
第125行: 第125行:
创建功能:
创建功能:


<code>mkdir /sys/kernel/config/usb_gadget/my_gadget/functions/mass_storage.my_img</code>
<pre>mkdir /sys/kernel/config/usb_gadget/my_gadget/functions/mass_storage.my_img</pre>
选择设备或者镜像
选择设备或者镜像


<code>echo /mnt/a_virtual_disk.img > /sys/kernel/config/usb_gadget/my_gadget/functions/mass_storage.my_img/lun.0/file
<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</code>
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行:
创建功能:
创建功能:


<code>mkdir /sys/kernel/config/usb_gadget/my_gadget/functions/rndis.my_net</code>
<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>来加载所需模块。如:


<code>modprobe usbfunc:mass_storage</code>
<pre>modprobe usbfunc:mass_storage</pre>
== 创建配置 ==
== 创建配置 ==


第248行: 第248行:
|}
|}


<code>mkdir /sys/kernel/config/usb_gadget/my_gadget/configs/a.1</code>
<pre>mkdir /sys/kernel/config/usb_gadget/my_gadget/configs/a.1</pre>
=== 链接功能到配置 ===
=== 链接功能到配置 ===


<code>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
<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</code>
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]]
参考: [[#附注语言id|语言ID]]


<code>mkdir /sys/kernel/config/usb_gadget/my_gadget/configs/a.1/strings/0x0409
<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</code>
echo "MY MASS + RNDIS" > /sys/kernel/config/usb_gadget/my_gadget/configs/a.1/strings/0x0409/configuration</pre>
== 启动设备 ==
== 启动设备 ==


第265行: 第265行:
=== 查看可用 ===
=== 查看可用 ===


<code>ls -l /sys/class/udc/</code>
<pre>ls -l /sys/class/udc/</pre>
<pre class="">ffff0000.usb</pre>
<pre>ffff0000.usb</pre>
=== 启动gadget ===
=== 启动gadget ===


<code>echo ffff0000.usb > /sys/kernel/config/usb_gadget/my_gadget/UDC</code>
<pre>echo ffff0000.usb > /sys/kernel/config/usb_gadget/my_gadget/UDC</pre>
此时,主机会成功发现设备
此时,主机会成功发现设备


第294行: 第294行:
如果想要停止gadget,则直接写空即可
如果想要停止gadget,则直接写空即可


<code>echo > /sys/kernel/config/usb_gadget/my_gadget/UDC</code>
<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