目录
硬件环境及目标
配置脚本
问题1 ,创建g1 目录失败
问题1 的解决
问题2 ,目录不存在
访问存储卡
综述
网上很多资料介绍通过configfs将OTG 口配置为U盘的资料,本文记录实际操作及遇到的问题。
硬件环境及目标
硬件基本结构如下图。
期望PC可以访问 存储卡。
配置脚本
#!/bin/sh
mount -t configfs none /sys/kernel/config
cd /sys/kernel/config/usb_gadget
mkdir g1
cd g1
echo 0x18d1 > idVendor
echo 0x4ee2 > idProduct
mkdir strings/0x409
#echo "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" > strings/0x409/serialnumber
echo "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" > strings/0x409/serialnumber
echo "shoniba" > strings/0x409/manufacturer
echo "Mass Storage" > strings/0x409/product
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "mass_storage" > configs/c.1/strings/0x409/configuration
mkdir functions/mass_storage.0
echo "/dev/mmcblk2p7" > functions/mass_storage.0/lun.0/file
#echo "/oem/vfat.img" > functions/mass_storage.0/lun.0/file
ln -s functions/mass_storage.0 configs/c.1
ls /sys/class/udc > UDC
第一行 mount configfs,即通过configfs完成对OTG功能的配置,挂载此文件系统后,在/sys/kernel/config目录下就会出现 usb_gadget目录。
问题1 ,创建g1 目录失败
在usb_gadget目录下已经存在一个目录的情况下,不能再次创建目录。
[root@rk1808:/sys/kernel/config/usb_gadget]# mkdir -m 0770 g1 (报错,抛栈异常)
[ 1193.993072] sysfs: cannot create duplicate filename '/devices/virtual/android_usb/android0'
[ 1193.993166] ------------[ cut here ]------------
[ 1193.993200] WARNING: at fs/sysfs/dir.c:31
[ 1193.993218] Modmkdir: cannot create directory 'g1': Cannot allocate memory
ules link[root@rk1808:/sys/kernel/config/usb_gadget]# ed in: bcmdhd galcore(O)
[ 1193.993262]
[ 1193.993295] CPU: 0 PID: 696 Comm: mkdir Tainted: G W O 4.4.194 #19
[ 1193.993315] Hardware name: Rockchip RK1808 EVB V10 Board (DT)
[ 1193.993341] task: ffffffc075afe0c0 task.stack: ffffffc07c034000
[ 1193.993376] PC is at sysfs_warn_dup+0x58/0x7c
[ 1193.993412] LR is at sysfs_warn_dup+0x58/0x7c
[ 1193.993436] pc : [<ffffff800819f10c>] lr : [<ffffff800819f10c>] pstate: 00000145
[ 1193.993455] sp : ffffffc07c037ac0
[ 1193.993474] x29: ffffffc07c037ac0 x28: 0000000000000000
而我们的确看到在 usb_gadget目录下存在一个目录: rockchip
问题1 的解决
在/etc/init.d目录下存在 USB configfs的配置文件,分别为:
.usb_config和S50usbdevices
- 其中第一个文件控制OTG接口作为什么功能,例如UMS,即U盘,ADB、UVC等等。
- 第二个文件 功能类似本节开始处的脚本,即通过configfs配置各种具体的功能。各个功能是互斥的。
对于问题1的解决,由于前期我们猜测是由于 usb_gadget已经存在一个目录,因而我们将.usb_config中的usb_adb_en改成一个不存在的功能,例如usb_xxx_en。然后重启。
此时再查看 mount信息,configfs已经没有被挂载。于是手动挂载后,通过 mkdir g1可以创建目录了。
由此实验证实了我们的猜想: 即在usb_gadget目录下不能创建多个目录。
问题2 ,目录不存在
当脚本运行到 mkdir functions/mass_storage.0 时,一直提示:
mkdir: cannot create directory 'mass_massage.0': No such file or directory
重新编译内核,增加内核选项
cat .config |grep -i mass
CONFIG_USB_F_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_MASS_STORAGE is not set
采用新内核后,可以正常创建mass_storage.0目录了。
此时脚本全部运行完毕,我们在PC上可以看到一个盘符了!
访问存储卡
lsscsi
[3:0:0:0] disk ATA 2.5" SATA SSD 3M 225 /dev/sda
[4:0:0:0] disk Linux File-Stor Gadget 0404 /dev/sdb
运行完第二章的脚本后,在PC上通过lsscsi命令可以看到多了一个盘符/dev/sdb,类型是file-stor gadget。这个就是我们要访问的存储卡。
但是此/dev/sdb设备即不能被mount 也不能发disk分区,导致不能使用。
究其原因,因为我们脚本中 对于/dev/sdb的分区 mmcblk2p7,文件系统格式为ext2导致,将此分区重新格式化成ext4 或者vfat,则可以被PC正常访问了。
mkfs.ext3 /dev/mmcblk2p7
mke2fs 1.43.9 (8-Feb-2018)
/dev/mmcblk2p7 contains a ext2 file system labelled 'oem'
last mounted on /oem on Sat Aug 5 12:25:21 2017
Proceed anyway? (y,N) y
Discarding device blocks: done
Creating filesystem with 65536 1k blocks and 16384 inodes
Filesystem UUID: 2a1152f9-4ffe-4040-abf5-49aca7b9fe7c
Superblock backups stored on blocks:
8193, 24577, 40961, 57345
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
格式化成vfat
mkfs.vfat /dev/mmcblk2p7
mkfs.fat 4.1 (2017-01-24)
综述
configfs的强大及灵活显而易见,而在应用过程中遇到的问题,需要对内核进一步了解才更容易解决。