所以有处理器,然后是 mmu,然后是 l1 缓存,然后是“处理器核心”的边缘,尽管埋藏在早期内存系统下的也是一个核心,但更深。
当“处理器”访问程序员直接操作的某个地址时(您在寄存器中用于保存加载或存储地址的值,加上您编码的任何偏移量)。
如果启用了 mmu,则 mmu 从地址中获取一些位,根据地址寄存器以及 mmu 的配置方式进行一些数学运算,然后在 mmu 的内存端生成自己的内存周期(有处理器端和内存端)。它查找用户编程的 mmu 表信息,这就是将虚拟地址更改为物理地址等事情的发生方式。一旦 mmu 完成了它需要收集的内存周期数,然后数据(注意 mmu 可能有一个小的先前查找缓存以保存实际内存周期),然后,只要没有故障(正在访问的地址在表中进行了描述并且权限匹配,以便您可以访问该内存,和/或 mmu 表查找本身不会导致错误)处理器想要执行的访问是使用物理地址执行的。
如果 mmu 被禁用,则处理器访问将直接进入 l1 缓存,然后通过 axi 或 amba 总线进入内存系统。如果有 l2,则 l2 缓存位于 amba/axi 上。
一旦您使用 amba/axi,您就会进入供应商逻辑,无论是谁制造了芯片(arm 不制造芯片,它制造处理器内核,一些供应商用自己的逻辑封装该内核,然后制造芯片并销售芯片) .你进入那个可能非常简单到非常复杂的供应商内存系统。例如,您可以具有可配置的设置,这样一些地址空间(例如零)可以在某个时间点(例如在上电时)指向 rom,然后如果您更改设置访问为零或接近零将导致它进入某个 ram .你可以有一些逻辑来操纵整个地址空间,例如地址的前两位进入一些具有四组控制寄存器的逻辑,并且对于地址空间的每个四分之一,这些控制寄存器可能会做一些事情地址或其他与 mmu 不同的东西。
最终,供应商逻辑将开始解码更多地址位,并确定您是否正在尝试访问实际的 ram、rom 或外围设备,然后当它接近最终目标时,外围设备中的 csr 等等地址位被进一步解码。任何处理器的地址空间都可以(并不总是),但可以像一棵树,树干是地址离开处理器的地方,但是随着地址的解析,它可以向不同的方向分支,最终它会找到您尝试的单个叶子地址,可以是 ram 中的内存位置、某个外围设备中的 csr 或某个 ram 或外围设备中的其他项目(这可能会导致其他总线上的其他事件链,例如 usb 或 pcie)。
所以在说了这么多之后,这里的简短回答是,首先你应该在没有 mmu 和缓存的情况下运行,了解芯片(供应商端)的“物理”地址空间,你必须理解或者没有mmu。这个地址空间非常特定于那个供应商,可能是那个芯片或芯片系列,所以你需要芯片供应商的文档。然后以后学习如何使用mmu,我首先建议尝试虚拟地址与物理地址相同,学习将ram标记为可缓存,将外围地址空间标记为不可缓存(然后打开数据缓存,看看是否有效)。然后学习添加指向不同物理地址的虚拟地址空间块,从那里你就可以开始在操作系统中使用 mmu。
arm 处理器本身不知道从 ram 到 rom 从墙上的孔中的外围设备。地址位只是位,它通常不关心的一些模式,在某些 arm 处理器架构上存在一些例外,其中 arm 本身内部有一些外围设备,它会解码并且不会让您将这些外围设备进一步降低,但是供应商外围设备、ram、rom 等 arm 不知道或不关心,因此这些地址空间的虚拟地址可能与物理地址不同。您不想做的是让外围设备地址空间(数据)可缓存。一些较新的 arm 内核有一些关于分支预测的规则以及您可能会获得一些获取的限制,因此,如果您在设置中具有微调的灵活性并且您有执行一些更改的外围设备(读取时清除,自动递增地址外围设备等)无论如何在现代系统中都是糟糕的设计选择,您可能希望避免出现分支预测指令获取可能导致读取其中一个位置的情况。
您可能面临的另一个问题,即 redboot 可能为您解决或未解决的问题是 dram,甚至 sram您购买 redboot 或 pre-redboot 引导加载程序,那么您真的希望让 redboot 执行此操作,然后加载 redboot 并启动您的 rtos。初始化物理内存可能(并不总是)是一种与从头开始编写自己的 rtos 相当的学习体验,因此在许多这些支持 linux 的系统上,您需要决定要重新发明多少东西以及为什么要重新发明。在没有 mmu 和基于平坦物理地址的内存空间的情况下,您将有足够的工作来完成某些事情,一次构建一个桥不要尝试一次构建它们,等到您遇到下一个障碍,然后再尝试解决它。