linux - PCI/PCIe 设备如何在 Linux 内核中初始化/注册自己?

标签 linux linux-kernel linux-device-driver pci pci-e

当内核启动时,PCI 子系统为每个物理 PCI 总线创建一个 pci_bus,然后将 pci_bus 添加到 pci_root_buses(与 PCI 配置)。而PCI设备驱动通过pci_register_driver来注册驱动,它把PCI驱动添加到pci_bus_type中。

我的问题:

  • pci_bus_type 如何知道 PCI 配置。
  • pci_bus_typepci_root_buses 之间的关系是什么。

最佳答案

由于问题部分不完整,但评论太少无法给出答案,我会尝试稍微混合一下。

因此内核试图从驱动程序开发人员那里抽象出 PCI(e) 总线的物理实现。因此,NVidia Tegra 上的 PCI 总线不同于 Freescale ARM 和 x86_64 PCI 总线上的 PCI 总线,但无论实际总线实现如何,都应该可以针对它们注册设备。

pci_root_buses 结构是抽象 PCI 总线的列表,其中的实现可能不同。

您可以在总线类型结构中看到这一点,其中定义了函数指针以允许每个实际总线具有不同的实现方式来处理设备。我认为最好阅读 PCI chapter in LDD3并特别查看启动时间

另请查看配置时间,了解内核如何将驱动程序与硬件相匹配。 PCI 的粗略想法是内核可以发现总线并将内存映射到每个物理 PCI 设备,从而允许访问设备的 PCI 配置空间。驱动程序开发人员通过调用 pci_register_driver 注册设备类,从而告诉内核哪些驱动程序函数用于某些供应商 ID。

再次查看 LDD3,您可能正在寻找的缺失映射似乎是探测函数:

int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);

指向 PCI 驱动程序中的探测函数的指针。当 PCI 内核具有它认为该驱动程序想要控制的 struct pci_dev 时,该函数将被调用。指向 PCI 核心用于做出此决定的 struct pci_device_id 的指针也传递给此函数。如果 PCI 驱动程序声明传递给它的 struct pci_dev,它应该正确初始化设备并返回 0。如果驱动程序不想认领设备,或者发生错误,它应该返回一个负错误值。本章稍后将详细介绍此功能。

内核数据结构

进一步阅读

关于linux - PCI/PCIe 设备如何在 Linux 内核中初始化/注册自己?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31445413/

相关文章:

linux - 使用 postfix 的 Google Cloud Computing 实例 VM 上的 amazon SES

linux - "git fetch"在 repo 上什么都不做

c - 通过 NetLink 发送的数据大小

linux - 如何向task_struct添加成员绕过 "compiletime_assert"

linux - LIDT的操作数是位移/绝对地址

c - 为什么要在驱动程序代码中注册 struct cdev

linux - 记录导致主要页面错误的内存访问

c - 用户空间和内核空间之间的共享信号量

c - 通过中断检测热插拔

camera - Raspberry Pi - Raspbian - 运动 - USB 摄像头 - 黑色图像