PCI BAR 内存地址

PCI BAR 内存地址

一个快速的问题,我正在阅读 OSDev Wiki 页面上有关 PCI 的内容,上面有以下内容 -

基地址寄存器(或 BAR)可用于保存设备使用的内存地址或端口地址的偏移量。通常,内存地址 BAR 需要位于物理 RAM 中,而 I/O 空间 BAR 可以驻留在任何内存地址(甚至超出物理内存)。`

我不明白它说了什么memory address BARs need to be located in physical ram。MMIO 的重点是它被分配了一个内存地址,这样它就会被路由到设备而不是物理 RAM。它需要位于物理 RAM 中是什么意思?

无论安装了多少物理 RAM,它难道不只是 3GB - 4GB 地址空间之间的一个地址吗?

这是 OSDev 网站的错误还是我误解了?

关联 -大约在中间位置,在标题“基地址寄存器”下

答案1

我相信这里存在一些混淆,因为 I/O 设备和非 I/O 设备之间存在差异。
摘自维基百科内存映射 I/O (MMIO)

内存映射 I/O 使用相同的地址总线来寻址内存和 I/O 设备 - I/O 设备的内存和寄存器被映射到(与)地址值相关联。因此,当 CPU 访问某个地址时,它可能指的是物理 RAM 的一部分,但也可能指的是 I/O 设备的内存。因此,用于访问内存的 CPU 指令也可用于访问设备。每个 I/O 设备都会监视 CPU 的地址总线,并响应任何 CPU 对分配给该设备的地址的访问,将数据总线连接到所需设备的硬件寄存器。为了容纳 I/O 设备,CPU 使用的地址区域必须为 I/O 保留,并且不能用于普通物理内存。

来自你的文章:

基地址寄存器(或 BAR)可用于保存设备使用的内存地址或端口地址的偏移量。通常,内存地址 BAR 需要位于物理 RAM 中而I/O空间BAR可以驻留在任何内存地址(甚至超出物理内存)。

图像

内存空间 BAR 布局的类型字段指定基址寄存器的大小以及它可以映射到内存中的位置。如果它的值为 0x00,则基址寄存器为 32 位宽,并且可以映射到32位内存空间的任意位置。0x02 表示基址寄存器为 64 位宽,可以映射到 64 位内存空间的任意位置(64 位基址寄存器占用 2 个可用的基址寄存器)。

因此两者之间没有冲突,因为一切都取决于设备。如果设备拦截总线上的内存引用,则地址是虚拟的。如果没有,则它是用于与设备(例如 NVRAM)通信的真实物理地址。

但是,在所有情况下,I/O 设备都使用真实物理地址,因为引用它的计算机指令只能使用真实地址。如果设备拦截对该内存的引用,则可能会浪费该内存。为了避免这种浪费,操作系统通常会将其分配到真实物理内存之外(这不会导致内存访问错误,因为设备将拦截所有引用)。

这就是众所周知的 32 位 Windows 计算机似乎无法使用全部 4 GB 内存的问题的原因。原因是 Windows 是 32 位的,它使用真实地址分配设备内存,而这些内存在以下两种情况下都不可用:寻址内存是否真正被使用,或因被设备拦截而未被使用。

另一篇有用的维基百科文章是:PCI 配置空间

答案2

地址总线宽度决定了物理地址空间. 但并非这个空间内的所有值都是声称由内存控制器声明。有些由其他类型的设备声明。BAR 寄存器隐式编码了 PCIe 设备/功能请求的地址范围大小。但必须正确配置此范围的基数。然后,设备可以自动声明地址在其范围内的请求。这种安排在系统初始化/启动阶段都是可配置的。

一个有用的例子:

在此处输入图片描述

从软件工程师的角度来看,我认为最重要的事情不是了解所有这些管道是如何为计算架构实现的。而是硬件资源通过什么方式暴露给软件。对于 x86 架构,它可以是内存地址或 IO 地址。

相关内容