Skip to the content.

Linux Kernel 如何管理 PCIe 设备

File blank comment code explanation
pci.c 950 1955 3667 capability list 的封装
probe.c 543 631 2137  
setup-bus.c 333 373 1536  
pci-sysfs.c 244 150 1170  
pci-driver.c 283 331 1045  
msi.c 258 276 1045  
pci-acpi.c 205 175 989  
pcie/aer.c 214 229 961  
pcie/aspm.c 191 245 941  
iov.c 189 177 725  
p2pdma.c 164 240 601  
pci.h 97 64 532  
vpd.c 101 85 467  
pcie/aer_inject.c 67 18 460  
slot.c 0 0 379  
access.c       访问配置空间的函数封装
ecam.c       ecam 的支持

其实,内核中处理 PCIe 的代码并不多。

关键结构体

scan 的过程

probe 的过程

使用 e1000 的为例:

static struct pci_driver e1000_driver = {
	.name     = e1000_driver_name,
	.id_table = e1000_pci_tbl,
	.probe    = e1000_probe,
	.remove   = e1000_remove,
	.driver = {
		.pm = &e1000_pm_ops,
	},
	.shutdown = e1000_shutdown,
	.err_handler = &e1000_err_handler
};

Once the driver knows about a PCI device and takes ownership, the driver generally needs to perform the following initialization: 1

两个小教程可以玩玩

You will also learn a bit about how PCI handles some nifty kernel features such as probing and power management.

For an in-depth discussion of PCI, such as device driver design, PCI bus features, and implementation details, refer to Linux Device Drivers and Understanding the Linux Kernel, as well as PCI specifications.

什么,Understanding the Linux Kernel 中间 讲过 pci

pci_device_id Device identifier. This is not a local ID used by Linux, but an ID defined accordingly to the PCI standard.

pci_dev Each PCI device is assigned a pci_dev instance, just as network devices are assigned net_device instances. This is the structure used by the kernel to refer to a PCI device.

pci_driver Defines the interface between the PCI layer and the device drivers. This structure consists mostly of function pointers. All PCI devices use it.

PCI devices are uniquely identified by a combination of parameters, including vendor, model, etc.

Each device driver registers with the kernel a vector of pci_device_id instances that lists the IDs of the devices it can handle.

PCI device drivers register and unregister with the kernel with pci_register_driver and pci_unregister_driver, respectively.

One of the great advantages of PCI is its elegant support for probing to find the IRQ and other resources each device needs.

The Big Picture 的这一节可以细品

想法: pci 是基础架构,pci 的三层 (事务,路由,物理)内核并不会参与, 但是,哪一个设备 和 对应的驱动关联 (nvme) 资源的分配 需要 pci driver 处理,一旦这些搞定之后,pci driver 就可以退居幕后了

PCIe 配置空间中是存在

https://stackoverflow.com/questions/72993292/how-to-get-irq-pins-in-pci

看看 kernel 中的

static const struct pci_device_id

本来以为 reset 是 pcie 的接口,但是发现 virtio 设备都没有这个

➜  ~ find /sys -name reset
/sys/devices/pci0000:00/0000:00:0c.0/reset
/sys/devices/pci0000:00/0000:00:0b.0/reset
/sys/devices/pci0000:00/0000:00:0a.0/reset
/sys/devices/virtual/block/zram0/reset
/sys/module/i915/parameters/reset

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。

  1. https://www.kernel.org/doc/html/latest/PCI/index.html  2