ARM 64架构内存布局

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rikeyone/article/details/86496229

首先我们以最为常用的4KB page + 3 levels配置为例去介绍:

 AArch64 Linux memory layout with 4KB pages + 3 levels:

 

 Start           End         Size        Use

 -----------------------------------------------------------------------

 0000000000000000    0000007fffffffff     512GB      user

 ffffff8000000000    ffffffffffffffff     512GB      kernel

我们知道arm64架构最大支持48bit寻址,那么它的最大寻址空间是256TB,但是如果我们使用这种配置,虚拟内存划分为以上所示的两个区域,最大寻址空间是1TB,其中512GB属于用户空间,剩余512GB属于内核空间。下面我们着重介绍内核空间地址分布:

 Memory: 4293896K/4776612K available (16828K kernel code, 2654K rwdata, 7436K rodata, 7104K init, 11801K bss, 195996K reserved, 286720K cma-reserved)
 Virtual kernel memory layout:
     modules : 0xffffff8000000000 - 0xffffff8008000000   (   128 MB)
     vmalloc : 0xffffff8008000000 - 0xffffffbebfff0000   (   250 GB)
       .text : 0xffffff9688080000 - 0xffffff96890f0000   ( 16832 KB)
     .rodata : 0xffffff9689100000 - 0xffffff9689850000   (  7488 KB)
       .init : 0xffffff9689850000 - 0xffffff9689f40000   (  7104 KB)
       .data : 0xffffff9689f40000 - 0xffffff968a1d7a00   (  2655 KB)
        .bss : 0xffffff968a1d7a00 - 0xffffff968ad5e000   ( 11802 KB)
     fixed   : 0xffffffbefe7fd000 - 0xffffffbefec00000   (  4108 KB)
     PCI I/O : 0xffffffbefee00000 - 0xffffffbeffe00000   (    16 MB)
     vmemmap : 0xffffffbf00000000 - 0xffffffc000000000   (     4 GB maximum)
               0xffffffbf62000000 - 0xffffffbf67000000   (    80 MB actual)
     memory  : 0xffffffd880000000 - 0xffffffd9c0000000   (  5120 MB)

这个内存布局和arm 32的区别如下:

    1. 不存在highmem区域,在arm 32内存布局中,会有lowmem选项标识了低端内存直接映射区(DMA/NORMAL),而在arm 64架构中,只有一个memory用来映射可用内存(DMA/NORMAL/MOVABLE)
    1. 在arm 32架构中存在pkmap和fixmap两块区域,而arm 64架构中只有一个fixed区域,其实对应的就是fixmap区域,而不再有pkmap区域。
    1. 虽然内核可访问地址区域为512G,但是这里memory根据实际物理内存大小做了限制,所以memroy显示了实际能够访问的内存区。

memory区域的起始/结束地址如下:

pr_notice("    memory  : 0x%16lx - 0x%16lx   (%6ld MB)\n",
    MLM(__phys_to_virt(memblock_start_of_DRAM()),
        (unsigned long)high_memory));

而high_memory的赋值如下所示:

high_memory = __va(memblock_end_of_DRAM() - 1) + 1;

实际上这里的区域最终来源是memblock_start_of_DRAM()和memblock_end_of_DRAM()函数,进一步跟进可以看到具体获取的方式,实际是通过dts中配置的内存块来决定的。

猜你喜欢

转载自blog.csdn.net/rikeyone/article/details/86496229