BB-black开发板[Linux arm-v8]

解决usb虚拟u盘无法probe驱动的问题--Apple的学习笔

2020-10-06  本文已影响0人  applecai

1.前言:

一开始想使用usb gadget来虚拟网卡的,结果按网上的简单配置后,无法使用,Document中貌似没看到什么特别有帮助的,所以先降低难度使用usb gadget来虚拟一个u盘。其它的之后再慢慢深入。先进入Kernel驱动实战

2.在使用modprobe时候思考如何用insmod

modprob比insmod好用,但是需要知道原理
linux设备驱动有两种加载方式insmod和modprobe,下面谈谈它们用法上的区别
1、insmod一次只能加载特定的一个设备驱动,且需要驱动的具体地址。
2. modprobe则可以一次将有依赖关系的驱动全部加载到内核。不加驱动的具体地址,但需要在安装文件系统时是按照make modues_install的方式安装驱动模块的。驱动被安装在/lib/modules/$(uname -r)/...下。写法为:
modprob drv
modprobe 和insmod一样都是用来加载内核module的
不过modprobe比较智能,它可以根据module的依赖性来自动为你加载;而insmod就做不到这点。智能识别的原理是什么呢!

手工又应该如何加载模块呢!随意加载就会报错。
方法一
在编译后,modinfo xx.ko可以查看详细信息。其中depends 一项我们可以看到该模块依赖 x模块。
方法二
modules.dep文件是一个依赖关系图,在此文件的目录中,通过搜索命令可以知道依赖关系。
grep -nr phy-am335x.ko modules.dep

  1. 添加模块后不成功,需要调试
    常用的就是打印信息,为了输出pr_debug和dev_debug驱动加载的调试信息配置kernel
    image.png
    image.png
    其它方法
    驱动文件定义#define DEBUG,如果需要调试的文件很多,或者调试初期无法确定问题是在哪个文件时,如何处理?这里提供一个参考,kernel顶层Makefile中KBUILD_CFLAGS+=DDEBUG可实现,但又会引入更多问题,比如DVFS的大量日志等等。
    打印信息过多,导致printk messages dropped
    解决方法config LOG_BUF_SHIFT int"Kernel log buffer size (16 => 64KB, 17 => 128KB)设置内核日志缓冲区的最小尺寸(合理的设置应该等于CONFIG_LOG_CPU_MAX_BUF_SHIFT*最大CPU数量): 12(最小值)=4KB,...,16=64KB,17=128KB,18=256KB,...,25(最大值)

3.通过调试信息找到突破口

之前modprobe g_multi加载虚拟网卡或者modprobe usb_f_mass_storage加载模块的时候都会报错
udc-core: couldn't find an available UDC - added [g_mass_storage] to list of pending drivers
找到对应模块的c文件为core.c

udc-core-y          := core.o trace.o
#
# USB peripheral controller drivers
#
obj-$(CONFIG_USB_GADGET)    += udc-core.o

搜索打印的关键字,找到usb_gadget_probe_driver函数报错。for循环没有在udc_list中找到所以报错,继续搜索udc_list,通过代码搜索发现usb文件夹只有一个list_add_tail(&udc->list, &udc_list);那么理解为必须先添加到list中才能找到。所以看谁调用usb_add_gadget_udc_release。

4.对比tisdk来验证我分析代码的正确性

usb_add_gadget_udc_release应该是在musb_init_controller中调用的。
所以我认为在musb_core.c中musb_probe必须被调用。而且需要加载模块musb_hdrc.ko。结果我的理解正确。

[   38.760443] bus: 'platform': add driver musb-dsps
[   38.760713] bus: 'platform': driver_probe_device: matched device 47401400.usb with driver musb-dsps
[   38.760788] bus: 'platform': really_probe: probing driver musb-dsps with device 47401400.usb
[   38.760842] musb-dsps 47401400.usb: no pinctrl handle
[   38.761038] irq: a:virq=61,type=0
[   38.761043] irq: b
[   38.765453] Registering platform device 'musb-hdrc.0'. Parent at 47401400.usb
[   38.765467] device: 'musb-hdrc.0': device_add
[   38.765528] bus: 'platform': add device musb-hdrc.0
[   38.765573] PM: Adding info for platform:musb-hdrc.0
[   38.766259] bus: 'platform': driver_probe_device: matched device musb-hdrc.0 with driver musb-hdrc
[   38.766274] bus: 'platform': really_probe: probing driver musb-hdrc with device musb-hdrc.0
[   38.766369] irq: a:virq=63,type=0
[   38.766373] irq: b
[   38.766377] musb_probe
[   38.766453] musb_init_controller
[   38.769207] musb->port_mode is 2
[   38.769214] go musb_gadget_setup
[   38.769252] go usb_add_gadget_udc
[   38.769257] go usb_add_gadget_udc_release
[   38.769272] device: 'gadget': device_add

5.分析我的kernel代码

果然,自己在5.4.61kernel中做的zImage的CONFIG_USB_MUSB_HDRC为y,但是没有信息打印出啦,说明没有probe成功。
将其编译到内核后,发现如下add driver musb-hdrc但是没有输出我在probe添加的调试信息。并且之前对比发现/sys/class/uds下面没有创建设备musb-hdrc.0。但是通过modprobe musb_hdrc是可以在/sys/bus下面创建usb的。
所以,有了tisdk我就找到捷径了。这几个KO文件对应的宏开关我把他打开。配置了CONFIG_USB_MUSB_HDRC和CONFIG_USB_MUSB_DSPS,然后bb black能虚拟一个u盘连接到主机PC咯~

6.进一步解决bus下没有usb总线的问题

已经可以虚拟出u盘,为什么bus下没有usb总线。难道都是通过/sys/class/udc来连接的吗?这一点我暂时先放放。先解决为什么usb总线没有创建问题。通过调试信息真是没有看到usb bus的创建呀!

image.png
调查步骤:
  1. 通过搜索': registered。没有搜索到bus usb被register。
  2. 通过代码搜索usb子系统初始化函数usb_init。是属于subsys_initcall,那么在do_initcalls中应该被调用的呀。
  3. 然后我去System.map里看看usb_init函数是否编译入。通过命令grep -nr usb_init System.map发现找不到。
  4. 此bus初始化函数在core文件夹,在Makefile查看,需要配置CONFIG_USB。另外,它对应的usbcore.o
  5. 难道是没有配置,不会吧!然后去看.config文件CONFIG_USB=m。
    至此已经知道原因,若我希望在/sys/bus下面看到usb总线,只要重新配置kernel或者手工加载usbcore.ko即可。

7.总结

通过如下3个步骤,完成bb black虚拟u盘的操作
modprobe usbcore
modprobe usb_f_mass_storage
modprobe g_mass_storage file=/dev/mmcblk0p1 removable=1

Welcome to Buildroot
buildroot login: root
# cd /sys/bus
# ls
clockevents   gpio          mmc_rpmb      scsi          virtio
clocksource   hid           nvmem         sdio          workqueue
container     i2c           pci           serial
cpu           mdio_bus      pci-epf       soc
event_source  mmc           platform      spi
# modprobe usbcore
[   71.089616] bus: 'usb': registered
[   71.093291] bus: 'usb': add driver usbfs
[   71.097310] usbcore: registered new interface driver usbfs
[   71.102893] bus: 'usb': add driver hub
[   71.106705] usbcore: registered new interface driver hub
[   71.112118] bus: 'usb': add driver usb
[   71.115924] usbcore: registered new device driver usb
# cd /sys/bus/usb
# ls
devices            drivers_autoprobe  uevent
drivers            drivers_probe
# cd devices/
# ls
# cd ..
# ls
devices            drivers_autoprobe  uevent
drivers            drivers_probe
# cd /sys/class/udc
# ls
musb-hdrc.0
# cd musb-hdrc.0/
# ls
a_alt_hnp_support  device             is_selfpowered     srp
a_hnp_support      function           maximum_speed      state
b_hnp_enable       is_a_peripheral    power              subsystem
current_speed      is_otg             soft_connect       uevent
# cd ..
# cd ..
# cd /sys/bus/usb
# ls
devices            drivers_autoprobe  uevent
drivers            drivers_probe
# cd devices/
# modprobe usb_f_mass_storage
# [  167.200445] random: crng init done

# modprobe g_mass_storage file=/dev/mmcblk0p1 removable=1
[  173.939807] driver_name is g_mass_storage
[  173.939818] go 2
[  173.945862] myUDC is found
[  173.948592] udc musb-hdrc.0: registering UDC driver [g_mass_storage]
[  173.955089] Mass Storage Function, version: 2009/09/11
[  173.960261] LUN: removable file: (no medium)
[  173.964622] device: 'lun0': device_add
[  173.968444] PM: Adding info for No Bus:lun0
[  173.972823] lun0: open backing file: /dev/mmcblk0p1
[  173.977734] LUN: removable file: /dev/mmcblk0p1
[  173.982322] Number of LUNs=1
[  173.985233] g_mass_storage gadget: adding config #1 'Linux File-Backed Storage'/c7b2a844
[  173.993389] g_mass_storage gadget: adding 'Mass Storage Function'/d03f0dd3 to config 'Linux File-Backed Storage'/c7b2a844
[  174.006354] g_mass_storage gadget: I/O thread pid: 116
[  174.011679] g_mass_storage gadget: cfg 1/c7b2a844 speeds: high full
[  174.017980] g_mass_storage gadget:   interface 0 = Mass Storage Function/d03f0dd3
[  174.025557] g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11
[  174.032579] g_mass_storage gadget: userspace failed to provide iSerialNumber
[  174.039657] g_mass_storage gadget: g_mass_storage ready
# [  174.481041] g_mass_storage gadget: high-speed config #1: Linux File-Backed Storage
[  174.488703] g_mass_storage gadget: set_config: interface 0 (Mass Storage Function) requested delayed status
[  174.498487] g_mass_storage gadget: delayed_status count 1
[  174.503977] g_mass_storage gadget: usb_composite_setup_continue
[  174.509925] g_mass_storage gadget: usb_composite_setup_continue: Completing delayed status
[  175.534012] g_mass_storage gadget: sending command-failure status
[  175.541790] g_mass_storage gadget: bulk-in set halt
[  175.547398] g_mass_storage gadget: bulk-in set halt
[  175.574254] g_mass_storage gadget: bulk-in set halt
[  175.579798] g_mass_storage gadget: bulk-in set halt
[  175.589653] g_mass_storage gadget: bulk-in set halt
[  175.595534] g_mass_storage gadget: bulk-in set halt

8.后记

关于此次解决问题突破口采用了捷径,就是去查tisdk的调试信息来反推需要填写哪些模块。这是不对的,若遇到没有参考的情况下,我该怎么办。所以后续要对这些c代码的功能进一步了解。我需要知道哪些c模块代码拥有这些功能,这是我本次的败笔,本次比较好的就是能充分利用调试信息及设备模型匹配框架还有Makefile这张地图。自己虚拟一个u盘,觉得好好玩,所以先用起来,之后会继续深入学习的。

上一篇下一篇

猜你喜欢

热点阅读