c - Linux 内核如何设置 PCI BAR 以保证没有地址冲突?
问题描述
据我了解,(这很可能是错误的)每个 PCI 设备都知道它想要声明多少(大小)iomem/ioport 地址空间,但它不知道在哪里(偏移量)。只有 BIOS 或 OS 可以告诉设备该位置应该在哪里,因为有人必须与所有 PCI 设备通信并协调它们的 iomem/ioport 地址分配请求,以便分配的地址不会重叠,并且这种协调发生在启动时,或热插拔事件,或在pci 重新扫描期间。但是,在 Linux 内核代码中,我只找到了一个函数 ( pci_read_bases
),它读取 BAR 信息,并相应地设置pci_dev
& iomem_resource
/ ioport_resource
,而不是更改 BAR。所以问题是:
- 操作系统(Linux 内核)可以更改 BAR 吗?还是只有 BIOS 才能在加载操作系统之前做到这一点?
- 如果内核可以更改 BAR,那么协调地址分配的逻辑在哪里?(我确实看到了类似的函数
pbus_assign_resources_sorted
,但在我看来,该函数仅将现有的 BAR 映射到内核对象,例如iomem_resource
,而不是更改 BAR)
解决方案
对于正常的静态分配,BIOS 写入 BAR,内核在启动时读取它们。有趣的是动态分配的设备,例如 NVMe 卡的热插拔。在这种情况下,BIOS 必须保留一个范围,以防插入的设备在启动时不存在或大于移除的设备。内核收到一个中断,必须读取新的 BAR 值并将它们添加到地址空间。参见例如nvme_remap_bar
https://elixir.bootlin.com/linux/v5.4/source/drivers/nvme/host/pci.c#L1649
推荐阅读
- php - 虚拟主机在 ubuntu LAMP 堆栈中无法正常工作
- node.js - module.exports 找不到模块
- javascript - pdf.js 的问题不下载文件和打印
- reactjs - 无法在其他表单域上输入
- java - Spring boot security Authentication [This localhost page can't be found: HTTP ERROR 404] 错误
- reactjs - 如何修复 React:字符串与预期的模式错误不匹配
- angular - Angular TestBed.inject
- .net - 如何使用谷歌身份验证在.net核心中刷新令牌或增加到期时间
- hive - 复制 impala 表的最佳方法
- python - Python进程没有延迟启动