这是来自 linux 源代码 arch/arm64/kernel/head.S 显示内核启动。代码首先调用preserve_boot_args
,然后el2_setup
使用bl
(分支和链接)调用。我也展示了程序preserve_boot_args
。
SYM_CODE_START(primary_entry)
bl preserve_boot_args
bl el2_setup // Drop to EL1, w0=cpu_boot_mode
adrp x23, __PHYS_OFFSET
and x23, x23, MIN_KIMG_ALIGN - 1 // KASLR offset, defaults to 0
bl set_cpu_boot_mode_flag
bl __create_page_tables
/*
* The following calls CPU setup code, see arch/arm64/mm/proc.S for
* details.
* On return, the CPU will be ready for the MMU to be turned on and
* the TCR will have been set.
*/
bl __cpu_setup // initialise processor
b __primary_switch
SYM_CODE_END(primary_entry)
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)
据我了解,bl
是用于调用过程(在过程之后,返回到保存在 lr - 链接寄存器,x30 中的地址)并且b
只是去标记的地址而不返回。但在上面的程序中preserve_boot_args
,就在最后,有一条b __inval_dcache_area
指令直接去__inval_dcache_area
而不返回。那么它如何返回到原始代码(在哪里bl el2_setup
)?一个程序如何结束自己?SYM_CODE_END 的定义是这样的:
#define SYM_END(name, sym_type) \
.type name sym_type ASM_NL \
.size name, .-name
#endif
我不明白这段代码如何使它返回到lr
. 我们不应该做类似的事情mv pc, lr
吗?