历史上的今天
返回首页

历史上的今天

今天是:2025年06月04日(星期三)

正在发生

2020年06月04日 | ARMv8(aarch64)页表建立过程详细分析

2020-06-04 来源:elecfans

1 ARMv8存储管理

1.1 Aarch64 Linux中的内存布局

ARMv8架构可以支持48位虚拟地址,并配置成4级页表(4K页),或者3级页表(64K页)。而本Linux系统只使用39位虚拟地址(512G内核,512G用户),配置成3级页表(4K页)或者2级页表(64K页)


用户空间的地址63:39位都置零,内核空间地址63:39都置一,虚拟地址的第63位可以用来选择TTBRx。swapper_pg_dir只包含内核全局映射,用户的pgd包含用户(非全局)映射。swapper_pg_dir地址在TTBR1中,不会写入TTBR0中。


AArch64Linux内存布局:


Start                                 End                             Size                     Use


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


0000000000000000         0000007fffffffff      512GB          user


 


ffffff8000000000             ffffffbbfffcffff           ~240GB       vmalloc


 


ffffffbbfffd0000               ffffffbcfffdffff         64KB            [guardpage]


 


ffffffbbfffe0000               ffffffbcfffeffff         64KB            PCII/O space


 


ffffffbbffff0000               ffffffbcffffffff          64KB            [guard page]


 


ffffffbc00000000             ffffffbdffffffff       8GB               vmemmap


 


ffffffbe00000000             ffffffbffbffffff         ~8GB           [guard,future vmmemap]


 


ffffffbffc000000                     ffffffbfffffffff            64MB           modules


 


ffffffc000000000             ffffffffffffffff                  256GB          memory


1.2 AArch64的虚拟地址格式

1.2.1 4K页时的虚拟地址

 


1.2.2 64K页时的虚拟地址


 



2 head.S页表建立过程分析

2.1 页表建立函数__create_page_tables

该函数用于在内核启动时,为FDT(设备树)、内核镜像创建启动所必须的页表。等内核正常运行后,还需运行create_mapping为所有的物理内存创建页表,这将覆盖__create_page_tables所创建的页表。


内核开始运行时创建页表源文件:arm64/kernel/head.Sline345


/*


 * Setup the initial page tables. We only setup the barest amount which is


 * required to get the kernel running. The following sections are required:


 *   -identity mapping to enable the MMU (low address, TTBR0)


 *   -first few MB of the kernel linear mapping to jump to once the MMU has


 *    been enabled, including the FDT blob (TTBR1)


 */


__create_page_tables:


          pgtbl     x25, x26,x24                         //idmap_pg_dir and swapper_pg_dir addresses


 


          /*


           * 清空新建的两个页表TTBR0,TTBR1


           */


          mov       x0,x25


          add       x6,x26, #SWAPPER_DIR_SIZE


1:        stp       xzr,xzr, [x0], #16


          stp       xzr,xzr, [x0], #16


          stp       xzr,xzr, [x0], #16


          stp       xzr,xzr, [x0], #16


          cmp       x0,x6


          b.lo      1b


 


          ldr       x7,=MM_MMUFLAGS


 


          /*


           * Create the identity mapping.


           */


          add       x0, x25,#PAGE_SIZE                   // sectiontable address


          adr       x3, __turn_mmu_on            // virtual/physical address


          create_pgd_entry x25, x0, x3, x5, x6  //展开见1.1.3


          create_block_map x0, x7, x3, x5, x5, idmap=1


 


          /*


           * Map the kernel image (starting withPHYS_OFFSET).


           */


          add       x0,x26, #PAGE_SIZE                   //section table address


          mov       x5,#PAGE_OFFSET


          create_pgd_entry x26, x0, x5, x3, x6


          ldr       x6,=KERNEL_END - 1


          mov       x3,x24                               // physoffset


          create_block_map x0, x7, x3, x5, x6


 


          /*


           * Map the FDT blob (maximum 2MB; must bewithin 512MB of


           * PHYS_OFFSET).


           */


          mov       x3,x21                               // FDTphys address


          and       x3,x3, #~((1 << 21) - 1)    // 2MBaligned


          mov       x6,#PAGE_OFFSET


          sub       x5,x3, x24                           //subtract PHYS_OFFSET


          tst       x5,#~((1 << 29) - 1)                 //within 512MB?


          csel      x21,xzr, x21, ne            // zero the FDTpointer


          b.ne      1f


          add       x5,x5, x6                            // __va(FDTblob)


          add       x6,x5, #1 << 21             // 2MB forthe FDT blob


          sub       x6,x6, #1                            //inclusive range


          create_block_map x0, x7, x3, x5, x6


1:


          ret


ENDPROC(__create_page_tables)


 


 


2.1.1  pgtbl   x25, x26, x24分析

pgtbl是个宏,定义如下:


arm64/kernel/head.S line55


          .macro    pgtbl,ttb0, ttb1, phys


          add       ttb1,phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE


          sub       ttb0,ttb1, #IDMAP_DIR_SIZE


          .endm


pgtbl               x25,x26, x24  //展开后如下


add                x26,x24, #TEXT_OFFSET -SWAPPER_DIR_SIZE


sub                x25,x26,#IDMAP_DIR_SIZE


 


其中各变量定义如下:


#defineSWAPPER_DIR_SIZE     (3 * PAGE_SIZE)


#defineIDMAP_DIR_SIZE                (2 *PAGE_SIZE)


说明:


1、关于TTBR0、TTBR1的介绍见ARM ARM 手册的Page B4-1708


2、x25中存TTBR0(TTBR0 holds the base address of translation table 0)的地址;


3、X26存TTBR1(TTBR1 holds the base address of translation table 1)地址;


4、X24 存PHYS_OFFSET,/* PHYS_OFFSET- the physical address of the start of memory. */


    #definePHYS_OFFSET      ({ memstart_addr; })


5、TEXT_OFFSET是Bootloader启动时传进来的参数,是内核Image加载时相对于RAM起始地址的偏移量


6、PAGE_OFFSEST:the virtual address of the start of the kernel image.


 


 


 



图1  pgtbl宏分析


 


2.1.2 MM_MMUFLAGS解释

在文件arm64/kernel/head.S line71:


/*


 * Initial memory map attributes.


 */


#ifndefCONFIG_SMP


#definePTE_FLAGS      PTE_TYPE_PAGE | PTE_AF


#definePMD_FLAGS     PMD_TYPE_SECT | PMD_SECT_AF


#else


#definePTE_FLAGS      PTE_TYPE_PAGE | PTE_AF |PTE_SHARED


#definePMD_FLAGS     PMD_TYPE_SECT | PMD_SECT_AF| PMD_SECT_S


#endif


 


#ifdefCONFIG_ARM64_64K_PAGES


#defineMM_MMUFLAGS   PTE_ATTRINDX(MT_NORMAL) |PTE_FLAGS


#defineIO_MMUFLAGS      PTE_ATTRINDX(MT_DEVICE_nGnRE)| PTE_XN | PTE_FLAGS


#else


#defineMM_MMUFLAGS   PMD_ATTRINDX(MT_NORMAL) |PMD_FLAGS


#defineIO_MMUFLAGS      PMD_ATTRINDX(MT_DEVICE_nGnRE)| PMD_SECT_XN | PMD_FLAGS


#endif


 


根据以上宏定义能明确,MM_MMUFLAGS就是根据你编译内核时选定的页大小(64K or 4K),设置MMU。


2.1.3 create_pgd_entry/create_block_map宏解释

1、create_pgd_entry


/*


 * Macro to populate the PGD for thecorresponding block entry in the next


 * level (tbl) for the given virtual address.


 *


 * Preserves:     pgd,tbl, virt


 * Corrupts:       tmp1,tmp2


 */


      .macro   create_pgd_entry,pgd, tbl, virt, tmp1, tmp2


      lsr   tmp1,virt, #PGDIR_SHIFT

推荐阅读

史海拾趣

Cableform Inc公司的发展小趣事

进入21世纪,电子行业迎来了快速发展的黄金时期。为了适应市场需求的变化,Cableform Inc不断加大研发投入,致力于技术创新。公司成功开发出了一系列具有自主知识产权的电磁控制产品,涵盖了从直流电机控制到高精度磁铁控制等多个领域。这些技术创新不仅提升了公司的核心竞争力,也为客户提供了更加高效、可靠的解决方案。

E-tec Interconnect Ltd公司的发展小趣事

随着全球对环境保护意识的提高,E-tec也积极响应这一趋势。他们投入资金进行环保设施的建设,采用环保材料和工艺进行生产。同时,E-tec还注重资源的循环利用和节能减排,通过一系列措施降低了生产过程中的能耗和排放。这些努力不仅为公司带来了良好的社会声誉,也促进了公司的可持续发展。

Cavium Networks公司的发展小趣事

在追求高性能与业务和谐的道路上,Cavium Networks 与 Wind River 公司展开了深度合作。两家公司共同制定了长期的产品研发路线,Wind River 为 Cavium 的 OCTEON II 等多核处理器提供了商业级支持。通过合作,双方共同调整和优化了领先的多核硬件和软件解决方案,为用户提供了世界领先的多核解决方案。这一合作不仅提升了 Cavium Networks 的技术实力和市场地位,也推动了整个电子行业的发展。

Chenmoun Enterprise Ltd公司的发展小趣事

Chenmoun Enterprise Ltd深知技术创新是企业发展的核心动力。因此,公司每年都会投入大量的资金用于研发新的电子产品和技术。通过不断的技术创新和产品升级,Chenmoun在行业内保持了领先地位,并实现了持续稳健的发展。

捷茂微(GATEMODE)公司的发展小趣事

随着公司业务的不断扩张,Chenmoun Enterprise Ltd开始实施全球化战略布局。公司在全球范围内设立了研发中心和生产基地,充分利用各地的资源优势和人才优势,提升产品的竞争力。同时,公司积极开拓国际市场,与多家国际知名企业建立了紧密的合作关系,实现了业务的快速增长。

DIALIGHT公司的发展小趣事

DIALIGHT公司的故事始于1938年的纽约布鲁克林,当时该公司专注于为飞机生产仪表板灯。随着技术的不断进步和市场的变化,公司在1971年,即LED推出仅一年后,推出了他们的第一个LED产品。这一举措标志着DIALIGHT正式从传统的飞机仪表板灯制造转向LED照明技术的研发和应用。从此,DIALIGHT彻底改变了LED的用途,将其广泛应用于世界各地的交通控制、指示灯、结构塔和工业场所,为全球提供了优质的照明解决方案。

问答坊 | AI 解惑

MC14433

老师,我需要一个MC14433,谢谢! 我是TSB11…

查看全部问答>

protel中PCB封装库时在那个文件夹下

如题,本人刚学菜鸟,不知道。哪位路过高手指点下 [ 本帖最后由 ttdatazx 于 2009-10-9 08:48 编辑 ]…

查看全部问答>

CMU200中文操作使用手册和GSM900的实际测量方法

replyreload += \',\' + 277674;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

DVR发展的必然结果,希望与各位探讨

初从业,纵观行业觉甚有可为。DVR在中国的历史刚刚开始但是不久的将来必然引起一场革命,这场革命将和每一位国人密切相关. 1. 网络化。DVR不应该仅仅作为一个本地视频存储管理设备,而应该能把一个系统、一个行业、一个城市、一个地区的DVR统一管 ...…

查看全部问答>

减少电子医疗设备EMI问题的设计方法

怎样减少电子医疗设备EMI解决方案: 使用基底噪声滤波器降低传导发射基底噪声滤波器被置于整体系统地和线滤波器地之间在设施接地系统内使用一个或多个基底噪声滤波器设备设计者一直要求获得具有更小封装的SMPS。更小的EMI滤波器不仅能够在电磁发射 ...…

查看全部问答>

关于 MPS32 CPU UART配置的问题

我现在在用MIPS32 4KSd内核的CPUUSIP做一个只能卡模块,用CF卡接口和WINCE5.0 的PDA相连,现在是用了usip的UART1给pda发数据,但UART1与其他三个uart不同,是一个标准的硬件控制流设备RX TX RTS CTS RI DTR DSR DCD 八个引脚 我现在只用到了RX和TX ...…

查看全部问答>

继电器有火花如果减小

最近做了个机器改造,有PID进行温度控制,但是发现交流继电器有火花。 有什么好的方法去掉火花,暂时不考虑更换交流继电器(无触电继电器)…

查看全部问答>

有谁用过编码器控制变频器进行定长???

我最近接了一个用编码器控制变频器进行定长的活。至今还没有想到可行的方案。定长的长度可以在触摸屏上设定。用的是三菱的PLC。。。…

查看全部问答>

不接32K晶振时,引脚XIN和XOUT可以悬空吗

不接32K晶振时,引脚XIN和XOUT可以悬空吗,如果不能悬空应该怎么接,还有,和JTAG口相连的引脚需不需要接上拉电阻到电源电压,如果不接,在不连接jtag时,会不会因为引脚是悬空的cmos口而引进干扰,谢了。…

查看全部问答>

POS套件的电源方案,大家可有考虑?

POS机套件中,TI给了一些有关电源的芯片,如TPS65910--电源管理、UCC28610--12~65W电源控制器、LMZ14203--3A易电源、TLV62130--3A降压电源、以用LI及镍氢电池充电芯片, 就其应用来说,大家讨论一下怎样利用这些芯片构建POS机的供电? …

查看全部问答>