【PCI】初始化

本文详细解释了Linux内核中PCI设备初始化的四个关键阶段:BIOS枚举、系统级枚举、驱动初始化和配置空间管理。涉及PCI总线类创建、通用属性注册、PCIslot子系统和ACPI子系统的初始化,确保设备驱动正确加载和配置。
摘要由CSDN通过智能技术生成

前言

系统对于PCI的初始化大体分为4个阶段:
  1.BIOS 对PCI设备进行初次枚举:在系统启动时,BIOS 会扫描系统中的PCI总线,识别和枚举连接在总线上的所有PCI设备,并为它们分配资源(如IO端口、内存地址等)。
  2.PCI设备系统枚举的前期准备:在操作系统启动后,系统会进行更深入的PCI设备枚举工作。这个阶段会包括文件系统相关目录的建立(如/sys/bus/pci/devices/)、访问方法的初始化等准备工作。
  3.PCI设备的系统阶段枚举:在系统准备就绪后,会对PCI设备进行系统级别的枚举。这个阶段涉及到创建pci_dev结构体来表示每个PCI设备,并进行进一步的信息获取和管理。
  4.PCI设备驱动的初始化:最后一个阶段是PCI设备驱动的初始化。在此阶段,系统会加载适当的PCI设备驱动程序(driver),将其与相应的PCI设备关联起来,以实现设备的正常工作和通信。


一、“pci_bus” 类的创建

1.pcibus_class_init 函数
位置:/drivers/pci/probe.c
在这里插入图片描述
函数分析:该函数调用 clasee_register 接口来注册“pci_bus”这个类(class)。PCI设备和PCI桥设备在PCI子系统中都属于总线。因此,在PCI设备和PCI桥设备注册完成之后,需要注册一个总线类,用于管理这些设备的总线相关的属性和操作。如下:
在这里插入图片描述

二、注册 PCI 总线的通用属性和操作

1.pci_driver_init 函数
位置:/drivers/pci/pci-driver.c
在这里插入图片描述
函数分析:这个是第二个与PCI总线有关的启动函数,该函数与 pcibus_class_init 类似,也只完成了一个结构体的注册,启动等级为2,作用是在 /sys/bus下注册一个 pci 目录并且完成该目录下子目录的创建(device 目录和driver目录)
在这里插入图片描述
针对每一个具体的设备,都可以进行操作,包括移除,再扫描等
在这里插入图片描述

三、完成 PCI 总线、设备以及驱动程序的初始化和配置

1.pci_arch_init 函数
位置:/arch/x86/pci/init.c
在这里插入图片描述
函数分析:该函数内部通过条件编译来确定内部函数的执行,我们可以通过 .config 文件得到源码定义的所有宏定义,经查得出 CONFIG_PCI_DIRECT定义而 CONFIG_PCI_BIOS 未定义,该函数的功能是设置整个PCI配置空间的读写方法。
  通过执行这些操作,系统可以快速扫描PCI总线,并将PCI资源配置文件 /proc/bus/pci/resources 中记录PCI设备及其DTO地址和VIN号等信息,以便设备驱动程序正确建立并使PCi设备能充分发挥作用。

四、初始化 PCI slot 子系统

1.pci_slot_init 函数
位置:/drivers/pci/slot.c
在这里插入图片描述

函数分析:此函数的作用是在 /sys/bus/pci 目录下创建一个子目录 slots,表示插槽,该目录存放的主要是当前硬件板上的 PCI/PCIE 的插槽节点,当该板上无引出的 PCI/PCIE 插槽时,那么该文件夹为空。在本函数中,主要的核心调用函数为 kset_create_and_add,这个函数在 pci bus下创建了一个名字为 slots 的文件夹。
在这里插入图片描述
  通过这些操作,系统能够自动识别和管理PCI插槽设备及其配置信息。PCI插槽的对象将作为 kset 的一个子目录而贡献给系统,这也使得应用层代码可以方便地读取相关的PCI插槽配置信息(例如容量、可用性等)。

五、初始化 ACPI 子系统

1.acpi_init 函数
位置:/drivers/acpi/bus.c
删除掉注释
在这里插入图片描述
函数分析:在以前的X86架构的系统中,系统会调用 pcibios_scan_root 的方式来枚举PCI总线,所以在查阅资料的时候经常会遇见该函数,但现在ACPI机制在x86架构系统中的普及,所以,对于该枚举部分代码的实现也有了改变,该函数是ACPI的初始化函数,启动等级为4,抛开pci_mmcfg_late_init()不看(该函数为pci_mmcfg的第二次配置,由于之前我们已完成了该方法的相关配置,所以此函数并不执行什么操作就返回了,除非你前面的配置有问题),ACPI初始化工作第一个重要的工作就对设备的探测,而我们所最为关心的PCI设备的枚举操作,也是在此完成的。
  通过执行这些操作,ACPI子系统在Linux内核启动时被正确地初始化和配置,为系统中的ACPI设备和电源管理功能提供了基础支持。

六、初始化 PCI 配置空间

1.pci_subsys_init 函数
位置:/arch/x86/pci/legacy.c
在这里插入图片描述

看看配置空间配置函数 pcibios_init 在这里插入图片描述函数分析:本函数主要是调用 pcibios_init 中的 pcibios_resource_survey 函数去检查这些 pci_bus 结构中 resource 的合法性。并从上级总线的资源地址空间中分配出一些空间为我们当前的PCI设备。
  通过执行这些操作,PCI子系统能够管理PCI设备的相关驱动程序,并启动相应控制器(如pdev->bus->ops->add_device),以便用户与系统在PCI总线上快识别和配置PCI设备及其相应的驱动程序和绝缘物理单元。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值