【问题标题】:How this simple paging in ARMv8a worksARMv8a 中这个简单的分页是如何工作的
【发布时间】: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<<21r*PAGESIZE 是什么意思?

【问题讨论】:

    标签: c arm armv8


    【解决方案1】:

    有两个表,分别由 TTBR0 和 TTBR1 指向。

    第一个,TTBR0,直接指向 &paging[0],形成 L0,L1,L2 页面层次结构:

    Paging[0] points at &paging[512*2]
    Paging[512*2] points at &paging[512*3]
    Paging[512*3..512*3+511] contains page descriptors for physical memory at 0..200000.
    

    另外

    Paging[512*2+1..512*2+511] contains large descriptors for physical memory at 400000..40000000
    

    第二个(内核)TTBR1直接指向&paging[512],形成了类似的L0,L1,L2层次结构:

    Paging[512+511] points at &paging[512*4]
    Paging[512*4+511] points at &paging[512*5]
    Paging[512*5] contains a descriptor for MMIO_BASE+0x201000.
    

    第二组偏移到每个表的第 511 个描述符的原因是为了使它位于一个非常高的地址。

    虚拟地址解码由翻译控制寄存器的T1SZ选择;它被注释为 3 级,或 39 位虚拟寻址: 12位偏移量和 27 位表索引(9 位 * 3 级)。

    地址位 63..40 传统上必须具有相同的值——全零或全一。这可以在控制寄存器中放松,但无论如何,第 63 位选择 TTBR[01] 中的哪一个将用于选择两个 L0 页表集之一。

    传统上,每个进程都有自己的 TTBR0,内核有一个 TTBR1,用于所有进程[因此无需更改]。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 2013-10-11
      • 2020-12-30
      • 1970-01-01
      • 1970-01-01
      • 2018-01-19
      相关资源
      最近更新 更多