memory-management - PCIe 端点设备内存如何映射到系统内存映射 (MMIO)?
问题描述
Linux 内核或BIOS如何将PCIe 端点设备内存映射到系统MMIO空间?有什么API可以实现吗?假设在为 PCIe 端点设备编写 Linux 设备驱动程序时,我们如何将PCIe设备内存映射到 MMIO 空间?或者在枚举期间设备是否已经被 BIOS 映射到 MMIO 中,我需要做的只是使用ioremap () 将设备MMIO重新映射到内核虚拟地址空间?
平台:x86 上的 Linux
解决方案
这个答案有两个部分
BIOS 的作用
BIOS(通常基于 UEFI)将执行某种深度优先搜索 (DFS) 并枚举所有子节点,因为 PCIe 是自枚举总线。由于它具有世界观(设备、总线、处理器),它会将地址写入 BAR 寄存器(可能是 BAR0 和/或多个)。这将是系统将使用的地址,它实际上会将这些请求从主机代理(x86/Intel 平台上的 HA)路由到根端口,再到 PCIe 交换机,一直到端点。
这些元素中的每一个都跟踪哪些地址范围属于它们自己或它们的子设备之一(例如,交换机可能是根端口的子设备)
设备驱动程序的作用
操作系统/内核将提供一个帮助程序工具包,驱动程序作者将使用它来访问设备寄存器。通常,驾驶员可能会遵循以下程序
这是一些示例驱动程序伪代码,只是为了帮助说明这个想法
1. pci_resource_flags(pdev, 0) & IORESOURCE_MEM
检查资源区域是否有效,此处检查 BAR 0
2. pci_request_regions(pdev, "区域")
获得资源/区域的所有权
3. drv->registers = pci_iomap(pdev, 0, SIZE_YOU_WANT_TO_MAP)
这将为您提供内核虚拟地址到设备寄存器的映射
注意:如果 BIOS 没有枚举,可以通过 Linux 重新扫描 PCIe 树以查看是否可以看到设备。
推荐阅读
- php - Laravel & VueJS CORS 尝试对用户进行身份验证时出现问题,即使使用 Cors 中间件也是如此
- ios - 从 iOS Biometrics 身份验证中捕获用户照片
- openid-connect - OIDC - at_hash 验证
- css - CSS无序列表,带点全块宽度下划线
- python - 如果从另一列的同一行看到新值,则重复前一行的值然后求和,然后在 Python 中重复当前行
- docker - 当我尝试在 Docker 上附加 Rails 容器时,“您无法附加到已停止的容器,请先启动它”
- python - 将这种将列附加到多个 dfs 的低效代码变成 for 循环?
- python - 我如何使用网络爬行提取 class = main-bullet 的链接
- reactjs - 具有大写函数名称的组件在 React Hooks 中被多次渲染
- go - 在 Azure DevOps 中为 Go 设置代码覆盖率