1. 程式人生 > 其它 >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