按照上一篇文章对gadget_configfs.txt的翻译,以imx8qxp mek的板子做为验证,配置为mass storage进行验证。
内核打开对应的宏
1、必须打开CONFIG_CONFIGFS_FS
和CONFIG_USB_LIBCOMPOSITE
的宏,前者为用户空间提供访问配置内核驱动的configfs文件系统,后者提供usb gadget composite框架;
2、必须打开UDC(USB Device Controller)的配置,这个是配置硬件控制器。我这里使用CONFIG_USB_CHIPIDEA
和CONFIG_USB_CHIPIDEA_UDC
;
3、如果使用mass storage功能,需要打开USB_CONFIGFS_MASS_STORAGE
和USB_F_MASS_STORAGE
,对应于usb_f_mass_storage.ko
驱动。
配置步骤
- 挂载configfs:
mount -t configfs none /config/
,在这之后,/configfs/
目录下就会生成usb_gadget/
目录; 创建gadget:
mkdir usb_gadget/g1
,创建g1/
目录之后,该目录下会生成很多配置目录,这里的g1
表示gadget 1,一个UDC对应一个gadget,如果你的SOC上有多个gadget,可以创建多个gx
目录。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# ll usb_gadget/g1/
total 0
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 UDC
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 bDeviceClass
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 bDeviceProtocol
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 bDeviceSubClass
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 bMaxPacketSize0
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 bcdDevice
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 bcdUSB
drwxr-xr-x 2 root root 0 1999-11-30 00:02 configs
drwxr-xr-x 2 root root 0 1999-11-30 00:02 functions
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 idProduct
-rw-r--r-- 1 root root 4096 1999-11-30 00:02 idVendor
drwxr-xr-x 2 root root 0 1999-11-30 00:02 os_desc
drwxr-xr-x 2 root root 0 1999-11-30 00:02 strings配置PID和VID
1
2# echo 0x18d1 > usb_gadget/g1/idVendor
# echo 0x4ee2 > usb_gadget/g1/idProduct创建并配置string字目录
1
2
3
4# mkdir usb_gadget/g1/strings/0x409
# echo "123456789" > usb_gadget/g1/strings/0x409/serialnumber
# echo "xxx" > usb_gadget/g1/strings/0x409/manufacturer
# echo "xxx_product" > usb_gadget/g1/strings/0x409/product创建configuration和字符串
1
2
3# mkdir usb_gadget/g1/configs/c.1
# mkdir usb_gadget/g1/configs/c.1/strings/0x409
# echo "mass_storage" > usb_gadget/g1/configs/c.1/strings/0x409/configuration创建functions
1
2
3# mkdir usb_gadget/g1/functions/mass_storage.0
[ 108.582976] [1: mkdir: 1976] Mass Storage Function, version: 2009/09/11
[ 108.592679] [1: mkdir: 1976] LUN: removable file: (no medium)
这里的mass_storage
的名字不能随便起,需要根据insmod的function驱动usb_f_mass_storage.ko
来决定。否则会出现如下错误:
1 | 1|@android:/config # mkdir usb_gadget/g1/functions/msg.0 |
- 将functions和configuration关联起来
1
# ln -s usb_gadget/g1/functions/mass_storage.0 usb_gadget/g1/configs/c.1
上述配置之后,得到的结果为:
1 | 127|@android:/config # find . |
查看当前的UDC
可见当前的板子上有两个UDC,ci_hdrc.0
和gadget-cdns3
。1
2
3
4130|@android:/config # ll /sys/class/udc/
total 0
lrwxrwxrwx 1 root root 0 1999-11-30 00:09 ci_hdrc.0 -> ../../devices/platform/5b0d0000.usb/ci_hdrc.0/udc/ci_hdrc.0
lrwxrwxrwx 1 root root 0 1999-11-30 00:09 gadget-cdns3 -> ../../devices/platform/5b110000.usb3/gadget-cdns3/udc/gadget-cdns3绑定到UDC,使能gadget
将UDC切换至device模式,这里使用OTG ID pin来实现切换。1
2# echo ci_hdrc.0 > usb_gadget/g1/UDC
# echo 1 > /sys/class/gpio/gpio358/value
验证结果
将配置好的开发板与ubuntu连接,从ubuntu上的串口可以看到如下信息,表示已将开发板配置成一个mass storage的设备了。
1 | [95705.390004] usb 1-11: USB disconnect, device number 28 |
当然,上述的结果是ubuntu只识别到一个mass storage的设备,但是没有识别看分区表,所以没有看到相应的磁盘信息。想要看到磁盘信息,可以更进一步的设置mass_storage的backen file
属性。
定制分区
在上面创建functions
步骤之后,执行以下的命令,为mass storage创建2个分区,分区的backing file是开发板上的/dev/block/mmcblk0p1
和/dev/block/mmcblk0p2
,也就是开发板上的system分区和data分区。
1 | mkdir usb_gadget/g1/functions/mass_storage.0/partition.2 |
所有配置完成之后,插入到ubuntu后,可以看到能识别去新的分区信息:
1 | 130 victor@victor-HP:/mnt⟫ sudo dmesg -c |
参考
上述的配置过程太繁琐了,在Android上,基于configfs有专门的init.rc
在启动过程中去配置对应的configuration
和function
,比如说init.usb.rc
,里面包含了一系列gadget的配置方法。在后面的文章中,将详细讲述每条命令背后的实现原理。
1 | on boot |
参考资料
drivers/usb/gadget/function/f_mass_storage.c
https://wiki.tizen.org/USB/Linux_USB_Layers/Configfs_Composite_Gadget