3.2 虚拟地址空间布局
3.2.1 虚拟地址空间划分
因为目前应用程序没有那么大的内存需求,所以ARM64处理器不支持完全的64位虚拟地址,实际支持情况如下。
(1)虚拟地址的最大宽度是48位,如图3.2所示。内核虚拟地址在64位地址空间的顶部,高16位是全1,范围是[0xFFFF 0000 0000 0000,0xFFFF FFFF FFFF FFFF];用户虚拟地址在64位地址空间的底部,高16位是全0,范围是[0x0000 0000 0000 0000,0x0000 FFFF FFFF FFFF];高16位是全1或全0的地址称为规范的地址,两者之间是不规范的地址,不允许使用。
图3.2 ARM64内核/用户虚拟地址空间划分
(2)如果处理器实现了ARMv8.2标准的大虚拟地址(Large Virtual Address, LVA)支持,并且页长度是64KB,那么虚拟地址的最大宽度是52位。
(3)可以为虚拟地址配置比最大宽度小的宽度,并且可以为内核虚拟地址和用户虚拟地址配置不同的宽度。转换控制寄存器(Translation Control Register)TCR_EL1的字段T0SZ定义了必须是全0的最高位的数量,字段T1SZ定义了必须是全1的最高位的数量,用户虚拟地址的宽度是(64-TCR_EL1.T0SZ),内核虚拟地址的宽度是(64-TCR_EL1.T1SZ)。
在编译ARM64架构的Linux内核时,可以选择虚拟地址宽度。
(1)如果选择页长度4KB,默认的虚拟地址宽度是39位。
(2)如果选择页长度16KB,默认的虚拟地址宽度是47位。
(3)如果选择页长度64KB,默认的虚拟地址宽度是42位。
(4)可以选择48位虚拟地址。
在ARM64架构的Linux内核中,内核虚拟地址和用户虚拟地址的宽度相同。
所有进程共享内核虚拟地址空间,每个进程有独立的用户虚拟地址空间,同一个线程组的用户线程共享用户虚拟地址空间,内核线程没有用户虚拟地址空间。