系统相关
首页 > 系统相关> > linux-aarch64-head.S-preserve_boot_args

linux-aarch64-head.S-preserve_boot_args

作者:互联网

 

preserve_boot_args 

在  arch/arm64/kernel/head.S 中实现。

作用就是保存 X0 X1 X2 X3 寄存器的值到 boot_args 这个数组中。

 

 1 /*
 2  * Preserve the arguments passed by the bootloader in x0 .. x3
 3  */
 4 SYM_CODE_START_LOCAL(preserve_boot_args)
 5     mov    x21, x0                // x21=FDT                                             (1)
 6 
 7     adr_l    x0, boot_args            // record the contents of
 8     stp    x21, x1, [x0]            // x0 .. x3 at kernel entry
 9     stp    x2, x3, [x0, #16]                                                              <2>
10 
11     dmb    sy                // needed before dc ivac with                                <3>
12                         // MMU off
13 
14     mov    x1, #0x20            // 4 x 8 bytes
15     b    __inval_dcache_area        // tail call                                           <4>
16 SYM_CODE_END(preserve_boot_args)

 

寄存器内容

X0 - fdt 的物理地址。 fdt:  flatten device tree physical address.

X1 ~ x3 都是 0.

 

(1)、mov x21, x0

将x0的值(flatten device tree的地址)放到 x21寄存器中。

后面  __primary_switched  中会用到X21 寄存器,__primary_switched 里面认为X21 里面的值就是 fdt 的物理地址, 将  X21 寄存器里面的值 放到  __fdt_pointer 这个全局变量中。

 

(2)、将X21 X1 X2 X3 内容保存在 boot_args 数组中

1、boot_args 数组 在 arch/arm64/kernel/setup.c

1 /*
2  * The recorded values of x0 .. x3 upon kernel entry.                                                                                                                                
3  */ 
4 u64 __cacheline_aligned boot_args[4];

2、adr_l x0, boot_args

adr_l 是一条 宏指令,定义在  arch/arm64/include/asm/assembler.h

 180/*
 181 * Pseudo-ops for PC-relative adr/ldr/str <reg>, <symbol> where
 182 * <symbol> is within the range +/- 4 GB of the PC.
 183 */
 184        /*
 185         * @dst: destination register (64 bit wide)
 186         * @sym: name of the symbol
 187         */
 188        .macro  adr_l, dst, sym
 189        adrp    \dst, \sym
 190        add     \dst, \dst, :lo12:\sym
 191        .endm
 192
 193        /*
 194         * @dst: destination register (32 or 64 bit wide)
 195         * @sym: name of the symbol
 196         * @tmp: optional 64-bit scratch register to be used if <dst> is a
 197         *       32-bit wide register, in which case it cannot be used to hold
 198         *       the address
 199         */
 200        .macro  ldr_l, dst, sym, tmp=
 201        .ifb    \tmp
 202        adrp    \dst, \sym
 203        ldr     \dst, [\dst, :lo12:\sym]
 204        .else
 205        adrp    \tmp, \sym
 206        ldr     \dst, [\tmp, :lo12:\sym]
 207        .endif
 208        .endm
 209
 210        /*
 211         * @src: source register (32 or 64 bit wide)
 212         * @sym: name of the symbol
 213         * @tmp: mandatory 64-bit scratch register to calculate the address
 214         *       while <src> needs to be preserved.
 215         */
 216        .macro  str_l, src, sym, tmp
 217        adrp    \tmp, \sym
 218        str     \src, [\tmp, :lo12:\sym]
 219        .endm
3、stp    x21, x1, [x0] 
aarch64 标准指令, store pair , 将一对 寄存器存放到 X0 指向的内存处。

(3) dmb sy

data memory barrier
aarch64 标准指令, memory barrier instruction  ,

 

(4)X0 X1 做参数,调用 __inval_dcache_area  函数,

 

__inval_dcache_area  函数 详解

https://www.cnblogs.com/zhangzhiwei122/p/15971010.html

 

标签:preserve,tmp,head,aarch64,dst,args,boot,sym,x0
来源: https://www.cnblogs.com/zhangzhiwei122/p/15971146.html