kernel启动流程-head.S的执行_3.preserve_boot_args

本文基于《arm64_linux head.S的执行流程》系列文章,针对内核5.10,分析head.S的preserve_boot_args执行过程。介绍了相关指令操作,如将寄存器值保存到boot_args数组,写入操作略过data cache直接写入RAM,还说明了保存寄存器的原因及后续操作。

1.前言

kernel版本:5.10
平台:arm64

本专题主要基于《arm64_linux head.S的执行流程》系列文章,前者是基于3.18,本专题针对的是内核5.10。主要分析head.S的执行过程。本文主要记录head.S的preserve_boot_args执行过程。

2.preserve_boot_args

/*                                                                                                                                                                                   
 * Preserve the arguments passed by the bootloader in x0 .. x3                                                                                                                       
 */                                                                                                                                                                                  
SYM_CODE_START_LOCAL(preserve_boot_args)                                                                                                                                           
        mov     x21, x0                         // x21=FDT                                                                                                                           
                                                                                                                                                                             
        adr_l   x0, boot_args                   // record the contents of
                                                                                                          
        stp     x21, x1, [x0]                   // x0 .. x3 at kernel entry                                                                                                          
        stp     x2, x3, [x0, #16]                                                                                                                                                    
                                                                                                                                                                                     
        dmb     sy                              // needed before dc ivac with                                                                                                        
                                                // MMU off                                                                                                                           
                                                                                                                                                                                     
        mov     x1, #0x20                       // 4 x 8 bytes                                                                                                                       
        b       __inval_dcache_area             // tail call                                                                                                                         
SYM_CODE_END(preserve_boot_args)

mov x21, x0

将x0的值(device tree的地址)暂存在x21寄存器中

adr_l x0, boot_args

将boot_args地址保存到x0

#arch/arm64/kernel/setup.c
/*
 * The recorded values of x0 .. x3 upon kernel entry.                                                                                                                                
 */ 
u64 __cacheline_aligned boot_args[4];

在没有开启mmu的情况下,也没有创建页表,如何才能访问到boot_args,这里adr_l宏的定义如下:

/*
 * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where
 * <symbol> is within the range +/- 4 GB of the PC.
 */
        /*  
         * @dst: destination register (64 bit wide)
         * @sym: name of the symbol
         */
        .macro  adr_l, dst, sym 
        adrp    \dst, \sym
        add     \dst, \dst, :lo12:\sym
        .endm

此宏主要是通过adrp来实现,adrp得到一个大小为4KB的页的基址,而且在该页中有全局变量sym的地址;ADRP就是讲该页的基址存到寄存器dst中;
add指令会算出sym的地址,:lo12:\sym是一个偏移量;这样就得到了sym的地址dst;

引自:http://www.wowotech.net/215.html
由于MMU = off, D-cache = off,因此写入boot_args变量的操作都是略过data cache的,直接写入了RAM中

stp x21, x1, [x0]

stp x2, x3, [x0, #16]

将x21,x1,x2,x3保存到boot_args数组。

引自:http://www.wowotech.net/215.html
为何要保存x0~x3这四个寄存器呢?因为ARM64 boot protocol对启动时候的x0~x3这四个寄存器有严格的限制:x0是dtb的物理地址,x1~x3必须是0(非零值是保留将来使用)。在后续setup_arch函数执行的时候会访问boot_args并进行校验。

dmb sy

确保数据写入内存

b __inval_dcache_area

跳转到__inval_dcache_area执行无效cache操作

3. 总结

preserve_boot_args最主要的是将x21,x1,x2,x3保存到boot_args数组,x21保存着FDT的地址,x1,x2,x3保存bootloader传递的其它信息。由于MMU = off, D-cache = off,因此写入boot_args变量的操作都是略过data cache的,直接写入了RAM

参考文档

  1. http://www.wowotech.net/215.html
    ARM64的启动过程之(一):内核第一个脚印
  2. Documentation/arm64/booting.txt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值