Linux 驱动程序如何调用 UEFI 固件提供的功能?

Linux 驱动程序如何调用 UEFI 固件提供的功能?

为了工作,我正在学习更多有关计算机体系结构的知识,并且刚刚学完 ACPI。通过与其他一些工程师的交谈,我对 NVMe 之类的东西的理解是,OEM 将拥有 UEFI NVMe 驱动程序,但操作系统的驱动程序将在启动后接管该功能。

在引导过程中,Linux 利用 UEFI 的驱动程序,然后一旦加载了自己的驱动程序,就会与之交换。

我的问题是源代码是什么样的?例如,我正在看NVMe源代码

我假设固件必须暴露一些基于标准的接口,Linux 驱动程序必须调用这些接口? (ACPI?)

答案1

当今世界,外部设备通常是 PCIe。每个 PCIe 设备都有自己的 PCIe 配置空间,对于非桥接设备,该空间的标头如下所示:

PCIe配置空间

BIOS(或 UEFI)的主要任务之一是询问每个 PCIe 设备Base Address Registers(=BAR)需要多少内存,在 CPU 内存中的某个位置保留该区域,并写回这些区域的起始地址。

当操作系统启动时,它会检查每个设备的 PCIe 配置空间中的Vendor IDDevice ID,并根据该信息设置适当的驱动程序。驱动程序从 BIOS (UEFI) 写入的 BAR 寄存器中读取值,并使用该内存(或 io)。

因此,如您所见,主要信息写入设备本身,无需在设备驱动程序中询问任何 UEFI 服务。

至于 Linux API,有几个函数可以与这些 BAR 一起使用,例如您可能想查看:

unsigned long pci_resource_start(struct pci_dev *dev, int bar);
unsigned long pci_resource_end(struct pci_dev *dev, int bar);
unsigned long pci_resource_flags(struct pci_dev *dev, int bar);

或者

int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)

如需更完整的文档,请参阅Linux Device Drivers书籍: https://www.xml.com/ldd/chapter/book/ch15.html

或者 PCI 上的内核文档:

https://www.kernel.org/doc/html/latest/driver-api/pci/pci.html#c.pci_request_region

https://www.kernel.org/doc/html/latest/PCI/pci.html

相关内容