谁分配 I/O 内存地址范围?
我有点困惑,我不知道这个地址范围是由 Bios、驱动程序还是操作系统分配的。
我对设备的地址范围有疑问,我不得不限制我的调查范围。I
/O 问题如下所述(参见大错误 I/O 范围):
重要信息:
该设备不工作,设备管理器显示以下错误:此设备无法找到足够的可用资源。如果您要使用此设备,则需要禁用此系统上的其他设备之一。我禁用了 90% 的其他设备,但仍然出现同样的错误。
答案1
我不知道这个地址范围是由 Bios、驱动程序还是操作系统分配的。
要么通过 BIOS,要么通过操作系统。设计良好的操作系统不应该要求设备驱动程序执行此操作(尽管我认为它不能阻止它们执行此操作)。
这是由配置空间PCI 设备,定义所有基址寄存器(BAR)。BIOS 或 OS(或两者)都会检查这些内容,并可以更改分配。
去引用维基百科:
要寻址 PCI 设备,必须将其映射到系统的 I/O 端口地址空间或内存映射地址空间中才能启用它。系统的固件、设备驱动程序或操作系统对基地址寄存器(通常称为 BAR)进行编程,以通过向 PCI 控制器写入配置命令来通知设备其地址映射。由于系统重置时所有 PCI 设备都处于非活动状态,因此它们没有分配地址,操作系统或设备驱动程序无法通过这些地址与它们通信。BIOS 或操作系统通过 PCI 控制器使用每个插槽的 IDSEL(初始化设备选择)信号在地理上寻址 PCI 插槽(例如,主板上的第一个 PCI 插槽、第二个 PCI 插槽或第三个 PCI 插槽等)。
由于 BIOS 或操作系统无法直接确定哪些 PCI 插槽安装了设备(也无法确定设备实现哪些功能),因此必须枚举 PCI 总线。总线枚举是通过尝试读取设备功能 #0 处总线号和设备号的每个组合的供应商 ID 和设备 ID (VID/DID) 寄存器来执行的。
[...]
当成功读取供应商 ID 寄存器的指定 B/D/F 组合时,设备驱动程序便知道该寄存器存在;它会将所有 1 写入其 BAR,并以编码形式读回设备请求的内存大小。该设计意味着所有地址空间大小都是 2 的幂,并且自然对齐。[1]
此时,BIOS 或操作系统会将内存映射和 I/O 端口地址编程到设备的 BAR 配置寄存器中。只要系统保持开启状态,这些地址就一直有效。断电后,所有这些设置都会丢失,下次系统重新通电时会重复该过程。
对于您的实际问题:
“此设备无法找到足够的可用资源。如果您想使用此设备,则需要禁用此系统上的其他设备之一。”
除非查看系统中所有设备的完整分配情况,否则无法回答这个问题。此外,某些设备对 BAR 的最终位置有限制。
您的特定 I/O 范围看起来4200FFFF
非常可疑,因此我猜测这是出现故障的硬件,其中一些 BAR 位被卡住了,因此它被分配了一个您的机器上不可用的 I/O 范围。
如果是这种情况,您可以禁用其他设备,直到您筋疲力尽,但什么也不会改变。 解决这个问题的唯一方法是修复或更换硬件,即使您有设备来拆焊和更换芯片,修复也非常困难。