【发布时间】:2021-02-26 19:30:03
【问题描述】:
根据 ARM 手册:
在 4kB 颗粒的情况下,硬件可以使用 4 级查找 过程。 48 位地址每级有 9 个地址位 翻译后的(即每个 512 个条目),最后 12 位 在 4kB 中选择一个直接来自原始文件的字节 地址。
512 条目 L0 表中的虚拟地址索引的位 [47:39]。 这些表条目中的每一个都跨越 512GB 范围并指向 L1 桌子。在该 512 条目 L1 表中,位 [38:30] 用作索引 选择一个条目,每个条目指向一个 1GB 块或一个 L2 表。
Bits [29:21] 索引到一个 512 条目 L2 表,每个条目指向 2MB 块或下一个表级别。在最后一级,位 [20:12] 索引 进入一个 512 条目的 L2 表,每个条目指向一个 4kB 块
这对我来说 100% 有意义。 L0、L1、L2 表以及到达物理地址的最终偏移量。
不过,看这段代码:https://github.com/bztsrc/raspi3-tutorial/blob/abaf5a5b2bc1a9fdfe5a9d8191c061671555da3d/10_virtualmemory/mmu.c#L66,解释here:
因为我们选择 4k 作为页面大小,而一个翻译条目是 8 字节,这意味着我们在每页上有 512 个条目。因此不 0..511 属于第一页,512..1023 属于第二页,依此类推。换句话说,paging[0]的地址等于_end(第一个 page),并且 paging[512] 等于 _end + PAGESIZE(第二页)。
看起来它正在设置手册中提到的 L0、L1 和 L2。所以前 512 个条目是 L0 表的条目,513-1024 个条目是 L1 表,1025-1536 个条目是 L2 表。
但是在代码中它开始这样做:
paging[4*512+511]=(unsigned long)((unsigned char*)&_end+5*PAGESIZE) | // physical address
PT_PAGE | // we have area in it mapped by pages
PT_AF | // accessed flag
PT_KERNEL | // privileged
PT_ISH | // inner shareable
PT_MEM; // normal memory
索引4*512+511 = 2559 远远超出了我想象的 L2 表。我想我误解了一些非常错误的东西!
是否应该 paging[0] 和 paging[511] 跨越第一个表 (L0),然后 paging[512] 和 paging[2013] 跨越第二个表 (L1) 和 paging[1024] 和 paging[2559] 跨越最后一个表 (L2)?
r<<21 和 r*PAGESIZE 是什么意思?
【问题讨论】: