1.platform device是怎么"自動"關聯到platform driver上的?
轉向linux driver有些時間了,前段時間碰到個問題,在Linux kernel 3.10的drivers/tty/serial/imx.c中,注冊driver的時候調用platform_driver_register(&serial_imx_driver),serial_imx_driver類型為platform_driver, serial_imx_driver中有個成員變量probe,在driver注冊時會調用這個函數,但是probe這個函數的參數是platform_device,而在imx.c中沒有出現platform_device類型的任何變量,問題就此產生了,platform_device這個參數到底是從什么地方傳進來的,內容又是什么,什么時候賦值的?
2.設備、總線、驅動三者如何關聯起來?
后來查閱了相關資料,大體上的意思是,在linux2.6內核以后,設備和驅動的結構划分為設備、總線、驅動,設備和驅動分別掛在總線上,而他們可以通過name來進行匹配(還有其他的方式),二者綁定有兩種方式:一種是先安裝driver,后掛載設備;另一種則是先掛載設備,然后安裝driver。但二者都是后面動作的會在總線上搜索與自己name項相同的設備或者driver進行匹配,也即完成綁定。
3.代碼中的實現
在imx.c中,由於平台是3.10,所以使用DTS,設備都是預先掛載了如串口0/1/2/3..., 后面安裝驅動時,會調用上述說到的platform_driver_register(&serial_imx_driver),在驅動注冊過程中會對進行匹配設備,一旦匹配到某個device,就會調用probe進行初始化,這個probe的參量platform_device也就有來源了。具體可以參考下面的調用過程:
do_basic_setup()->driver_init()->platform_bus_init()->...初始化platform bus(虛擬總線)
設備向內核注冊的時候platform_device_register()->platform_device_add()->...內核把設備掛在虛擬的platform bus下
驅動注冊的時候platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev()對每個掛在虛擬的platform bus的設備作__driver_attach()->driver_probe_device()->drv->bus->match()==platform_match()->比較strncmp(pdev->name, drv->name, BUS_ID_SIZE),如果相符就調用platform_drv_probe()->driver->probe(),如果probe成功則設備與驅動成功綁定.
代碼如下:在執行到driver_attach的時候platform_device還沒出現:
int driver_attach(struct device_driver *drv) { return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); } EXPORT_SYMBOL_GPL(driver_attach);
這一步開始出現了,縣初始化device list,然后通過next_device來遍歷節點的屬性,調用fn也即__driver_attach,dev也是從next_device中獲取device指針。
int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, int (*fn)(struct device *, void *)) { struct klist_iter i; struct device *dev; int error = 0; if (!bus || !bus->p) return -EINVAL; klist_iter_init_node(&bus->p->klist_devices, &i, (start ? &start->p->knode_bus : NULL)); while ((dev = next_device(&i)) && !error) error = fn(dev, data); klist_iter_exit(&i); return error; } EXPORT_SYMBOL_GPL(bus_for_each_dev);
以上只是簡單理解,還是沒有深入進去,所以很多原理說不清楚,希望能有時間靜下心好好研究研究,如:
1. 設備、驅動、總線三者設計理念,結構模式
2. 設備、驅動先后掛到總線上的機制
3. linux2.6之前、linux2.6、linux2.6之后,驅動、設備在這些版本中的變遷,如platform的出現,dts的出現等