linux驅(qū)動(dòng)probe被調(diào)用流程分析_第1頁
linux驅(qū)動(dòng)probe被調(diào)用流程分析_第2頁
linux驅(qū)動(dòng)probe被調(diào)用流程分析_第3頁
linux驅(qū)動(dòng)probe被調(diào)用流程分析_第4頁
linux驅(qū)動(dòng)probe被調(diào)用流程分析_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、linuxprobe被調(diào)流程分析前: 對(duì)于linux platform device 和driver,個(gè)driver可對(duì)應(yīng)多個(gè)device,通過名字進(jìn)匹配,調(diào)驅(qū)動(dòng)邊實(shí)現(xiàn)的probe函數(shù),本以個(gè)i2c設(shè)備為例,從驅(qū)動(dòng)的i2c_add_driver()開始看源碼以及較笨的打log的式分析如何步步調(diào)的probe()函數(shù)。分析的代碼基于linux kernel msm-4.9。/*/從module_init()開始看,定義位置:/源碼對(duì)該函數(shù)的說明:/* x: function to be run at kernel boot time or module insertion* be one per

2、module.*/作為每個(gè)驅(qū)動(dòng)的函數(shù),若代碼有編譯進(jìn)kernel的話在開機(jī)kernel啟動(dòng)(或模塊被動(dòng)態(tài)加載的時(shí)候)的時(shí)候被do_initcalls()調(diào),從kernel如何步步到do_initcalls()進(jìn)調(diào)module_init(),調(diào)鏈如下:start_kernel();/kernel的第個(gè)函數(shù)();();();();();/();/.module_init();/*/接著通過module_init()調(diào)你在驅(qū)動(dòng)邊實(shí)現(xiàn)的init函數(shù):對(duì)于個(gè)i2c設(shè)備來說,做法如下,static struct i2c_driver your_driver = .driver = .owner = THI

3、S_MODULE,.name = YOUR_DRIVER_NAME_UP,.of_match_table = your_driver_of_match,.probe = your_probe_func,.remove = your_i2c_drv_remove,.id_table = your_i2c_drv_id_table,/.suspend = your_i2c_drv_suspend,modul_init(your_init_func);將 your_probe_func()地址裝進(jìn)你實(shí)現(xiàn)的struct i2c_driver的.probe 成員,接下來,從i2c_add_driver(

4、)如何調(diào)到你的probe函數(shù),調(diào)鏈如下:i2c_register_driver();driver_register();bus_add_driver();driver_attach();really_probe();i2c_device_probe (this is what dev-bus-probe is for an i2c driver);your_probe_func();接下來個(gè)個(gè)函數(shù)分析他們到底了什么:先看i2c_register_driver(),定義位置:kernel/msm-4.9/drivers/i2c/i2c-core.c/* Cant register until a

5、fter driver model init */printk(unlikely(WARN_ON(!i2c_bus_type.p and return -EAGAIN.n);driver-driver.bus = &i2c_bus_type;/ bus typeINIT_LIST_HEAD(&driver-clients);*/res = driver_register(&driver-driver); / 這邊進(jìn)去printk(driver_register return res : %dn, res);printk(KERN_INFO =lkhlog %sn,driver-driver.n

6、ame);/* iWalk the adapters that are already present */i2c_for_each_dev(driver, _process_new_driver);type:struct bus_type i2c_bus_type = = i2c,= i2c_device_match,= i2c_device_probe,/ 后會(huì)回調(diào)這個(gè)函數(shù),在上的調(diào)鏈有提到.remove = i2c_device_remove,.shutdown = i2c_device_shutdown,;添加了bus_type,然后調(diào)driver_register(),接著看driv

7、er_register(),定義位置:kernel/msm-4.9/drivers/base/driver.c/* driver_register - register driver with bus 注冊(cè)總線驅(qū)動(dòng),和總線類型聯(lián)系起來* since most of the things we have to do deal with the bus* structures.*/int driver_register(struct device_driver *drv)other = driver_find(drv-name, drv-bus);/ 確認(rèn)該驅(qū)動(dòng)是否已經(jīng)注冊(cè)過ret = bus_a

8、dd_driver(drv);/ 主要從這進(jìn)去ret = driver_add_groups(drv, drv-groups);printk(KERN_WARNING =lkh bus_remove_driver);return ret;kobject_uevent(&drv-p-kobj, KOBJ_ADD);return ret;接著看 bus_add_driver(),定義位置:kernel/msm-4.9/drivers/base/bus.c/* bus_add_driver - Add a driver to the bus.*/bus = bus_get(drv-bus);/ bu

9、spr_debug(bus: %s: add driver %sn, bus-name, drv-name);priv = kzalloc(sizeof(*priv), GFP_KERNEL);if (error)goto out_unregister;klist_add_tail(&priv-knode_bus, &bus-p-klist_drivers);if (drv-bus-p-drivers_autoprobe) printk(KERN_ERR =lkh drv-bus-p-drivers_autoprobe = true, name : %sn, drv-name);if (dri

10、ver_allows_async_probing(drv) pr_debug(bus: %s: probing driver %s asynchronouslyn,drv-bus-name, drv-name);printk(KERN_ERR =lkh bus: %s: probing driver %s asynchronouslyn,drv-bus-name, drv-name);async_schedule(driver_attach_async, drv); else printk(KERN_ERR =lkh enter driver_attach, name : %sn, drv-n

11、ame);error = driver_attach(drv);/ 這邊進(jìn)去printk(KERN_ERR =lkh driver_attach, error : %dn, error);if (error)goto out_unregister;printk(KERN_ERR =lkh bus_add_driver 2, name : %s n, drv-name);/driver_attach()返回沒有錯(cuò)誤的話,/這邊會(huì)進(jìn)去創(chuàng)建相關(guān)節(jié)點(diǎn),鏈接module_add_driver(drv-owner, drv);/driver_attach(),直接看函數(shù)說明就能明了,kernel/msm-

12、4.9/drivers/base/dd.c* match the driver with each one. If driver_probe_device()* returns 0 and the dev-driver is set, weve found a*/return bus_for_each_dev(drv-bus, NULL, drv, _driver_attach);bus_for_each_dev()_driver_attach() 函數(shù),如下:kernel/msm-4.9/drivers/base/bus.c/* start: device to start iteratin

13、g from.* fn: function to be called for each device.* Iterate over buss list of devices, and call fn for each,* passing it data. If start is not NULL, we use that device to* begin iterating from.*/int bus_for_each_dev(struct bus_type *bus, struct device *start,void *data, int (*fn)(struct device *, v

14、oid *)/klist_iter_exit(&i);printk(KERN_WARNING =lkh bus_for_each_dev end n);return error;_driver_attach()繼續(xù)看,kernel/msm-4.9/drivers/base/dd.creturn 0;driver_match_device(),kernel/msm-4.9/drivers/base/base.hkernel/msm-4.9/drivers/i2c/i2c-core.cstruct device *dev)return drv-bus-match ? drv-bus-match(d

15、ev, drv) : 1;static int i2c_device_match(struct device *dev, struct device_driver *drv)struct i2c_client *client = i2c_verify_client(dev);struct i2c_driver *driver;/* Attempt an OF style match */在這匹配,三種匹配式:/Compatible match has highest priority/Matching type is better than matching name/Matching nam

16、e is a bit better than notif (i2c_of_match_device(drv-of_match_table, client)return 1;/* Then ACPI style match */if (acpi_driver_match_device(dev, drv)return 1;driver = to_i2c_driver(drv);return 0;i2c_device_match()i2c_register_driver()driver-driver.bus:.remove = i2c_device_remove,.shutdown = i2c_de

17、vice_shutdown,;driver_probe_device() 邊了,kernel/msm-4.9/drivers/base/dd.c/*/int driver_probe_device(struct device_driver *drv, struct device *dev)printk(KERN_DEBUG =lkh driver_probe_device entern);/pr_debug(bus: %s: %s: matched device %s with driver %sn,drv-bus-name, _func_, dev_name(dev), drv-name);

18、pm_runtime_barrier(dev);ret = really_probe(dev, drv);/ 這邊進(jìn)去/return ret;really_probe():kernel/msm-4.9/drivers/base/dd.c/devicedriverdriver/* Ensure devices are listed in devices_kset in correct order* Its important to move Dev to the end of devices_kset before* calling .probe, because it could be rec

19、ursive and parent Dev* should always go first*/ret = dev-bus-probe(dev);/ i2c_device_probe()/i2c_device_probe()your_probe_func(),: kernel/msm-4.9/drivers/i2c/i2c-core.cstatic int i2c_device_probe(struct device *dev)struct i2c_client *client = i2c_verify_client(dev);struct i2c_driver *driver;driver = to_i2c_driver(dev-driver);/ /*if (status)return 0;err_detach_pm_domain:dev_pm_domain_detach(&client-dev, true);err_clear_w

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論