内存如何映射到某个硬件?MMIO 究竟是如何实现的?

内存如何映射到某个硬件?MMIO 究竟是如何实现的?

请注意,我不是在问如何设置 MMIO(内存映射输入/输出),而是在问如何映射,即究竟是什么映射了它?不是将什么映射到什么,我可以在 Google 上查找内存映射。

我想知道的是,例如,第一次打开计算机时,究竟是什么“映射”了内存,或者它是如何工作的?

基本上,什么设置了记忆或将其“映射”用于某些目的?

我原本以为它是启动固件,如 BIOS 或 EFI/UEFI,但另一个网站上的另一位用户告诉我它与内存控制器有关。这是真的吗?

但是,如果要求不太多,如何更详细地说明呢?非常感谢任何澄清的人!

答案1

有几个步骤。首先,BIOS 发现系统上的所有设备。然后它询问每个设备以决定 BIOS 是否要设置该设备,如果要设置,则确定该设备需要多少内存地址空间(如果有的话)。然后 BIOS 为每个设备分配空间,并通过写入其 BAR(基址寄存器)来编程地址解码器。

总而言之,BIOS:

  1. 发现设备的 BAR(基址寄存器)。每个设备最多可以有 6 个 BAR。

  2. 对于每个 BAR,询问 BAR 需要多少地址空间。

  3. 为 BAR 分配一块地址空间。

  4. 使用所选内存地址空间块的基地址对 BAR 进行编程。

设备的地址解码器现在响应该地址空间块内的读取和写入。从那时起,当 CPU(或系统中任何支持 DMA 的设备)从该范围内的任何地址读取或写入时,设备都会响应请求。

请注意记忆分配给设备。内存是设备。它是分配给设备的内存地址空间。

当然,你可以在维基百科上找到详细的流程PCI 配置空间页。

答案2

(以下是几乎简单的话语。

每个设备都有一些资源。有人需要访问这些资源。这某人可以是 CPU 或其他设备。

CPU通过发送地址来向外界请求资源。这些地址通常分为不同的类别。例如内存地址或IO地址。不同的类别称为不同的地址空间,这意味着不同的指令。

内存地址用于加载-存储指令,如mov.IO 地址输入输出in或等指令out。不同类型的 CPU 使用不同的分类模式。有些公司喜欢使用内存地址来寻址所有内容,例如某些 Motorola CPU。有些公司喜欢使用单独的内存和 IO 地址,例如 Intel。有句俗话说,程序员喜欢 Motorola,因为他们只需要关心加载存储指令。但电子工程师喜欢 Intel,因为内存/IO 地址的分离简化了硬件实现。

无论如何,在地址被放到地址总线上之后,某些设备应该通过将数据放到数据总线上来响应该地址。硬件部件都以某种方式连接在一起。沿途有许多开关/解码器。不同的地址,不同的请求被路由到不同的地方.有点像网络。

系统中的每个设备都必须知道它应该响应哪些请求。设备通过地址映射来告知这一点,即设备记住它应该响应哪些地址。这通常以地址范围的形式出现。

必须有人告诉设备此类信息。而这个人可以是 OS/BIOS/固件。当他们进行这种安排时,他们正在做地址映射

对于 PCI/PCIe,我们需要对设备的 BAR 解码器/寄存器进行编程,以告诉它到达它的地址的基地址。并且 PCIe 设备隐式/固有地知道每个 BAR 使用的地址范围大小。并且 OS/FW/BIOS 可以通过将所有 1 写入 BAR 寄存器来知道这一点。有了这个基座/尺寸info,PCIe 设备可以准确识别到达地址属于哪个 BAR。然后正确计算与到达地址的偏移量。最后访问 RAM/寄存器在 PCIe 设备上实现

相关内容