Linux Kernel ---- PCI Driver 分析

时间:2021-05-13 16:55:44

自己笔记使用.

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 里面链表的数据,问题了,这个链表里面的数据在哪里放的呢?

    如果你知道,请告诉我,谢谢.