自己筆記使用.
Kernel 版本 4.15.0 (ubuntu 18.04,intel skylake)
最近想學習VGA驅動去了解 DDCCP / EDID 等協議,然后順便了解下驅動是如何工作的.
1. drivers/base/init.c –> driver_init() 這個函數比較重要,會創建驅動所需要的若干結構體,並且產生相應主目錄
- 比如 /sys/bus, /sys/devices, /sys/dev 等等目錄.
2. drivers/pci/pci-driver.c –> postcore_initcall(pci_driver_init) 這里是個關鍵.
PCI驅動所使用的結構體 struct pci_driver. struct device_driver.bus_type 都是引用 pci_driver_init 所初始化的
struct bus_type pci_bus_type,而 struct bus_type 引用的 kset 就是前面 1. 函數里面 buses_init 所創建
bus_register 里面有兩動作是
- klist_init(&priv->klist_devices,klist_devices_get,klist_devices_put);
- klist_init(&priv->klist_drivers,NULL,NULL);
- 從這里可以看出這里開始初始 bus->p->klist_devices,bus->p->klist_drivers
3. drivers/gpu/drm/i915/i915_pci.c -> module_init(i915_init) –>pci_register_driver(&i915_pci_driver)
static struct pci_driver i915_pci_driver{…} 這個是顯卡驅動的結構體.
上面調用最終會調用到 driver_register(struct device_driver *drv) ; //pci_driver.device_driver
- driver_find() 函數會先檢查驅動是否已經注冊,從這里可以看,注冊過的驅動都會放在
bus->p->driver_kset 鏈表里面,同時 kset.list.next prev 指向的是 struct kobject.entry
代碼里面經常會看到宏 Container_of, 當我們透過 kset.list做循環的時候,提到的next或者prev 都是
struct kobject.entry,那么我們如何得到 kobject的首地址呢,那我們就需要用到 Container_of
- bus_add_driver 創建驅動的私有成員 struct driver_private , priv->kobj.kset = bus->p->driver_kset
同時把 priv->kobj.entry 添加到 bus->p->driver_kset鏈表里面
創建目錄 /sys/bus/pci/driver/i195
- &priv->knodbus.node 添加到 bus.p->klist_drivers 鏈表里面
- 下面會繼續調用 driver_attach(drv)-> bus_for_each_dev(drv->bus,NULL,drv,__driver_attach)
4. bus_for_each_dev 函數.
struct klist_iter i; i.i_klist = bus->p>klist_devices ; i.i_cur = NULL;
下面會循環讀 bus->p->klist_devices 里面鏈表的數據,問題了,這個鏈表里面的數據在哪里放的呢?
如果你知道,請告訴我,謝謝.