FreeBSD驱动分析(01)---auto configure

一:入口

我们通过分析各个模块启动的先后顺序,猜测是在如下模块开始初始化的:
2010082323034678.png

 

通过查找引用到SI_SUB_CONFIGURE的地方:

2010082323064154.png

 

我们注意到首先添加了一个nexus0的设备,有关这个设备的描述如下:

At the top level resides the “root” device which is the parent to hang all other devices on. For each architecture, there is typically a single child of “root” which has such things as host-to-PCI bridges, etc. attached to it. For x86, this “root” device is the “nexus” device

 

源文档 <http://www.freebsd.org/doc/en_US.ISO8859-1/books/arch-handbook/book.html>

 

这个设备添加到rootbus,本身并没有什么值得研究的;

最关键的是在configure函数中会调用到root_bus_configure, 如下:

2010082323141666.png

 

 

此时root_bus上只有nexus这一个child,我们搜索nexus_probe, nexus_attach(), 如下:

2010082323251293.png

  

 

我们继续看bus_generic_probe()这个函数:

2010082323270446.png

  

devclass上的dirvers进行遍历,并进行DEVICE_IDENTIFY操作;我们需要了解此时nexus对应的devclass都有哪些drivers,并了解DEVICE_IDENTIFY的操作。

对于第一个问题,我们还是要从nexus的源文件找答案;我们先放下这个问题先看看宏定义

所以我们来看DEVICE_IDENTIFY的操作:

2010082323354167.png

  

我们可以从另外一个角度推测这段代码最后都做了些什么;我们使用kgdb对系统起来的内核进行分析。

先从root_bus开始分析,其上只有nuexus0这一个虚拟的设备,如下图所示:

2010082323383070.png

  

再看nexus0上挂载的子设备,共有五个:ram0, npx0, acpi0, legacy0, apic0.

2010082323450068.png

  

我们再来看nexus_devclass上的driver,一共有五个,分别是:apic, legacy, ram, npx, acpi,同上面那五个驱动是对应的:

2010082323473913.png

  

看到下面这几个驱动的声明就知道个大概了:都是挂在到nexus bus上,所以能在nexus_devclass上找到相关的driver;至于具体是如何挂在到该devclass的,要看DRIVER_MODULE宏的分析。

 

看到下面这几个驱动的声明就知道个大概了:都是挂在到nexus bus上,所以能在nexus_devclass上找到相关的driver;至于具体是如何挂在到该devclass的,要看DRIVER_MODULE宏的分析。

 

二:ACPI简介

我们猜测所有的设备都需要电源管理,所以所有的device都要挂载在ACPI设备下。

三: ACPI层的挂载

我们先来看挂载在nexus0下的acpi0这个虚拟驱动是如何添加上的,acpi_identify函数如下

2010082500232088.png


很简单,只是添加了一个acpi0设备在nexus0上;我们接下来跳过其他几个会挂载在nexus0的驱动设备的identify分析,接下来nexus0执行完bus_generic_probe(),接下来开始执行bus_generic_attach()函数:

2010082500380018.png


我们只关心nexus0上挂载的acpi0, 我们继续看device_probe_and_attach()函数的描述,这个描述很有意思,解释了很多FreeBSD驱动框架的细节:

2010082500462134.png

函数内容为:

2010082500492055.png


在device_probe_child中,调用parent上的devclass上的driver,并调用device_probe方法尝试去探测child这个设备;我们在这里略过,只需要知道其中会调用到的acpi_probe()函数中:接下来我们看device_attach函数(图片中只是函数的一部分,我们对略去的部分不关心):

2010082501134914.png

 

该函数中会调用到acpi_attach()函数:

2010082501181231.png

 

我们继续查看acpi_probe_children()这个函数,看在acpi0上都会挂载哪些设备;由于这个函数比较长,分成两部分,先看第一部分:

2010082501285771.png

 

我们继续看AcpiWalkNamespace函数定义在哪儿:

2010091119001046.png

整个函数略去分析,主要是把从BIOS读取到的设备添加到acpi0的children列表上;也就是说执行完之后再acpi0上挂载了许多需要探测到设备;

我们用devinfo命令可以查看探测完成后的树状结构:

nexus0

----acpi0

--------cpu0

------------p4tcc0

------------cpufreq0

--------pcib0

------------pci0

----------------hostb0

----------------pcib1

--------------------pci1

------------------------pcib2

----------------------------pci2

------------------------ioapic0

----------------pcib3

--------------------pci9

------------------------em0

----------------isab0

--------------------isa0

------------------------wdt0

------------------------sc0

------------------------vga0

------------------------orm0

--------acpi_sysresource0

----apic0

----ram0

 

我们看到大多数pci设备都是挂载到了pcib0这个节点下。我们开始分析这个节点:

四: PCI bus的挂载

在acpi_probe_children()函数中,pcib0通过AcpiWalkNamespace挂载到acpi0之后,就继续执行bus_generic_attach(),在这个函数中对每个children选择匹配的driver。

那pcib0选择的是那个driver呢?

我们先从dmesg查找线索:

2010091119153013.png

 

我们通过查找高亮的字符串,找到如下代码:

2010091119162918.png

 

probe之后就是attach,所以继续分析acpi_pcib_acpi_attach(FreeBSD的函数命名还是很规范的),略去acpi相关代码的分析,最后会执行到:

2010091119184286.png

 

注意黄色高亮部分的代码,这里主动添加了一个pci0设备,与我们在devinfo看到的树状结构项符合;

最后acpi_pcib_acpi_attach又调用了bus_generic_attach(),也就是去给pci0这个设备找匹配的driver;

pci0调用的probe函数是(略去从dmesg得到的分析过程):

2010091119223775.png

 

继续看acpi_pci_attach:

2010091119230947.png

 

我们感兴趣的是调用到的pci_add_children这个函数:

2010091119243795.png

 

这个函数探测挂载到pci0上的设备,其详细分析可以参考《linux源代码情景分析》中pci相关章节。

至此,我们应该对FreeBSD驱动的auto config有了一个整体的了解。


分析完之后有个问题:为什么是通过acpi0->pcib0->pci0之后才开始挂载pci总线上的设备,而不是直接通过acpi0->pci0就开始挂载pci总线上的设备?

也许是因为在acpi总线上可以挂载多个pci bridge设备。

 

这一节留给我们的问题是:

1 某个devclass上的driver是如何连接起来的,依据是什么(这个已经搞明白,在DRIVER_MODULE宏中会有分析);

2 kobj internel如何工作;

3 ACPICA的细节;

 

转载于:https://www.cnblogs.com/fuzhli/archive/2010/09/11/1806849.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值