1.前言:
一開始想使用usb gadget來虛擬網(wǎng)卡的福青,結(jié)果按網(wǎng)上的簡單配置后旦签,無法使用拾稳,Document中貌似沒看到什么特別有幫助的颊乘,所以先降低難度使用usb gadget來虛擬一個u盤参淹。其它的之后再慢慢深入。先進(jìn)入Kernel驅(qū)動實(shí)戰(zhàn)
2.在使用modprobe時候思考如何用insmod
modprob比insmod好用疲牵,但是需要知道原理
linux設(shè)備驅(qū)動有兩種加載方式insmod和modprobe承二,下面談?wù)勊鼈冇梅ㄉ系膮^(qū)別
1、insmod一次只能加載特定的一個設(shè)備驅(qū)動纲爸,且需要驅(qū)動的具體地址亥鸠。
2. modprobe則可以一次將有依賴關(guān)系的驅(qū)動全部加載到內(nèi)核。不加驅(qū)動的具體地址识啦,但需要在安裝文件系統(tǒng)時是按照make modues_install的方式安裝驅(qū)動模塊的负蚊。驅(qū)動被安裝在/lib/modules/$(uname -r)/...下。寫法為:
modprob drv
modprobe 和insmod一樣都是用來加載內(nèi)核module的
不過modprobe比較智能颓哮,它可以根據(jù)module的依賴性來自動為你加載家妆;而insmod就做不到這點(diǎn)。智能識別的原理是什么呢!
手工又應(yīng)該如何加載模塊呢冕茅!隨意加載就會報錯伤极。
方法一
在編譯后,modinfo xx.ko可以查看詳細(xì)信息姨伤。其中depends 一項(xiàng)我們可以看到該模塊依賴 x模塊哨坪。
方法二
modules.dep文件是一個依賴關(guān)系圖,在此文件的目錄中乍楚,通過搜索命令可以知道依賴關(guān)系当编。
grep -nr phy-am335x.ko modules.dep
- 添加模塊后不成功,需要調(diào)試
常用的就是打印信息徒溪,為了輸出pr_debug和dev_debug驅(qū)動加載的調(diào)試信息配置kernel
其它方法
驅(qū)動文件定義#define DEBUG忿偷,如果需要調(diào)試的文件很多金顿,或者調(diào)試初期無法確定問題是在哪個文件時,如何處理鲤桥?這里提供一個參考揍拆,kernel頂層Makefile中KBUILD_CFLAGS+=DDEBUG可實(shí)現(xiàn),但又會引入更多問題芜壁,比如DVFS的大量日志等等礁凡。
打印信息過多高氮,導(dǎo)致printk messages dropped
解決方法config LOG_BUF_SHIFT int"Kernel log buffer size (16 => 64KB, 17 => 128KB)設(shè)置內(nèi)核日志緩沖區(qū)的最小尺寸(合理的設(shè)置應(yīng)該等于CONFIG_LOG_CPU_MAX_BUF_SHIFT*最大CPU數(shù)量): 12(最小值)=4KB,...,16=64KB,17=128KB,18=256KB,...,25(最大值)
3.通過調(diào)試信息找到突破口
之前modprobe g_multi加載虛擬網(wǎng)卡或者modprobe usb_f_mass_storage加載模塊的時候都會報錯
udc-core: couldn't find an available UDC - added [g_mass_storage] to list of pending drivers
找到對應(yīng)模塊的c文件為core.c
udc-core-y := core.o trace.o
#
# USB peripheral controller drivers
#
obj-$(CONFIG_USB_GADGET) += udc-core.o
搜索打印的關(guān)鍵字慧妄,找到usb_gadget_probe_driver函數(shù)報錯。for循環(huán)沒有在udc_list中找到所以報錯剪芍,繼續(xù)搜索udc_list塞淹,通過代碼搜索發(fā)現(xiàn)usb文件夾只有一個list_add_tail(&udc->list, &udc_list);那么理解為必須先添加到list中才能找到。所以看誰調(diào)用usb_add_gadget_udc_release罪裹。
4.對比tisdk來驗(yàn)證我分析代碼的正確性
usb_add_gadget_udc_release應(yīng)該是在musb_init_controller中調(diào)用的饱普。
所以我認(rèn)為在musb_core.c中musb_probe必須被調(diào)用。而且需要加載模塊musb_hdrc.ko状共。結(jié)果我的理解正確套耕。
[ 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成功。
將其編譯到內(nèi)核后碾牌,發(fā)現(xiàn)如下add driver musb-hdrc但是沒有輸出我在probe添加的調(diào)試信息康愤。并且之前對比發(fā)現(xiàn)/sys/class/udc下面沒有創(chuàng)建設(shè)備musb-hdrc.0。但是通過modprobe musb_hdrc是可以在/sys/bus下面創(chuàng)建usb的舶吗。
所以征冷,有了tisdk我就找到捷徑了。這幾個KO文件對應(yīng)的宏開關(guān)我把他打開誓琼。配置了CONFIG_USB_MUSB_HDRC和CONFIG_USB_MUSB_DSPS检激,然后bb black能虛擬一個u盤連接到主機(jī)PC咯~
6.進(jìn)一步解決bus下沒有usb總線的問題
已經(jīng)可以虛擬出u盤,為什么bus下沒有usb總線腹侣。難道都是通過/sys/class/udc來連接的嗎叔收?這一點(diǎn)我暫時先放放。先解決為什么usb總線沒有創(chuàng)建問題筐带。通過調(diào)試信息真是沒有看到usb bus的創(chuàng)建呀今穿!
調(diào)查步驟:
- 通過搜索': registered。沒有搜索到bus usb被register伦籍。
- 通過代碼搜索usb子系統(tǒng)初始化函數(shù)usb_init蓝晒。是屬于subsys_initcall腮出,那么在do_initcalls中應(yīng)該被調(diào)用的呀。
- 然后我去System.map里看看usb_init函數(shù)是否編譯入芝薇。通過命令grep -nr usb_init System.map發(fā)現(xiàn)找不到胚嘲。
- 此bus初始化函數(shù)在core文件夾,在Makefile查看洛二,需要配置CONFIG_USB馋劈。另外,它對應(yīng)的usbcore.o
- 難道是沒有配置晾嘶,不會吧妓雾!然后去看.config文件CONFIG_USB=m。
至此已經(jīng)知道原因垒迂,若我希望在/sys/bus下面看到usb總線械姻,只要重新配置kernel或者手工加載usbcore.ko即可。
7.總結(jié)
通過如下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.后記
關(guān)于此次解決問題突破口采用了捷徑楷拳,就是去查tisdk的調(diào)試信息來反推需要填寫哪些模塊。這是不對的吏奸,若遇到?jīng)]有參考的情況下欢揖,我該怎么辦。所以后續(xù)要對這些c代碼的功能進(jìn)一步了解奋蔚。我需要知道哪些c模塊代碼擁有這些功能她混,這是我本次的敗筆,本次比較好的就是能充分利用調(diào)試信息及設(shè)備模型匹配框架還有Makefile這張地圖旺拉。自己虛擬一個u盤产上,覺得好好玩垂涯,所以先用起來驶臊,之后會繼續(xù)深入學(xué)習(xí)的宴杀。