美文网首页BB-black开发板[Linux arm-v8]
解决usb虚拟u盘无法probe驱动的问题--Apple的学习笔

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

作者: applecai | 来源:发表于2020-10-06 20:48 被阅读0次

    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盘,觉得好好玩,所以先用起来,之后会继续深入学习的。

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/opatpktx.html