gpt4 book ai didi

linux - 通过玩具内核访问pci空间

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:31:23 25 4
gpt4 key购买 nike

我正在 x86_64 平台上编写玩具内核。我计划提升我的内核以使用 VGA 和其他设备。到目前为止,我只是将我的玩具内核与键盘和 UART 连接起来。现在我认为它已经足够成熟,可以开始使用一些基本设备了。

但是,我发现很难在早期启动时找到有关 PCI 接口(interface)的文档。我正在寻找关于 linux PCI 驱动程序的文档,但不是我真正需要的东西。我必须自己走。如果 BIOS 将 PCI 空间映射到某个地方,我仍然感到困惑。

谁能解释一下它或指出一些文档。

谢谢

最佳答案

您要做的第一件事是执行 PCI 枚举。基本上有两种方法可以进行 PCI 枚举,基于端口或基于内存映射。基于端口的是较旧的方式,内存映射 PCI 配置空间是随 PCI Express 引入的。基于端口的方法仍然适用于较新的机器,也适用于模拟器/虚拟机以实现向后兼容性。因此,我将在接下来的解释中使用这种方法。这也有效,因为它有点复杂,如果您了解如何进行基于端口的枚举,内存映射枚举将非常简单。我应该补充一点,一些非 PC 兼容的 x86 板不支持基于端口的 PCI 枚举。

要通过端口访问 PCI 配置空间(以执行枚举),您需要了解两个特定端口:

  1. CONFIG_ADDRESS - 端口 0xCF8

  2. CONFIG_DATA - 端口 0xCFC

基本上,您要做的是将地址写入 CONFIG_ADDRESS,然后使用 CONFIG_DATA 读取或写入该地址的值。写入 CONFIG_ADDRESS 的地址格式如下:

31          30 - 24     23 - 16     15 - 11         10 - 8          7 - 2           1 - 0
Enable Bit Reserved Bus Number Device Number Function Number Register Number 00

假设您要使用 CONFIG_DATA 读取或写入值,启用位基本上应始终设置为 1。

假设您希望读取配置中第一个设备的第一个寄存器,您可以执行如下操作:

outl(CONFIG_ADDRESS, 1 << 31);
uint32_t result = inl(CONFIG_DATA)

要确定每个寄存器是什么,您可以查看此表:

PCI Configuration Space Table

因此在前面的示例中,第一个寄存器包含设备 ID 和供应商 ID。

现在您已经知道如何从 PCI 配置空间读取寄存器,您需要知道何时找到设备。基本上,如果第一个寄存器是 0xFFFFFFFF,则没有设备连接到该设备号处的总线。蛮力方法是扫描所有总线和设备,如果找到设备则扫描功能。更复杂的方法将查看第一条总线上第一个设备的 header 类型,以确定需要检查哪些总线。您可以找到有关如何进行更复杂枚举的更多信息 here .

要执行基于内存映射的方法,您需要找到 ACPI 中指定的 MCFG 表(也包含在更简单的 SFI 中)。这将为您提供可用于 PCI 枚举的物理地址。所有内存地址都将是该地址的偏移量。关键区别之一是配置空间已扩展,因此地址位字段与基于端口的枚举位字段不匹配。 PCI Express 的地址使用以下格式:

31 - 28   27 - 20     19 - 15        14 - 12          11 - 8                    7 - 2            1 - 0
ZEROS bus number device number function number extended register number register number offset

这是从 MCFG 表中获得的物理地址的偏移量。您可以找到有关 PCI express here 的更多信息.

最后,虽然它是特定于设备的,但您可以从 PCI 配置空间获得的最有用的信息通常是基地址寄存器。这些通常是设备内存映射到的物理地址,假设它是内存映射的,或者是端口地址,假设它是基于端口的。当然中断pin和线也是有用的。

关于linux - 通过玩具内核访问pci空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26808895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com