linux内核启动流程(基于arm)——head.S

源码路径:

https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/compressed/head.S

 

start:
		.type	start,#function
		mov	r7, r1			@ save architecture ID
		mov	r8, r2			@ save atags pointer


#ifndef CONFIG_CPU_V7M
		/*
		 * Booting from Angel - need to enter SVC mode and disable
		 * FIQs/IRQs (numeric definitions from angel arm.h source).
		 * We only do this if we were in user mode on entry.
		 */
		mrs	r2, cpsr		@ get current mode
		tst	r2, #3			@ not user?,如果是0x11 Z=0
		bne	not_angel       @ 非0跳转,0不跳转(中断位为1不跳转)
		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
 ARM(		swi	0x123456	)	@ angel_SWI_ARM
 THUMB(		svc	0xab		)	@ angel_SWI_THUMB
not_angel:
		safe_svcmode_maskall r0
		msr	spsr_cxsf, r9		@ Save the CPU boot mode in
						@ SPSR
#endif
 

MRS: 状态寄存器传送至通用寄存器类指令

首先cpsr状态寄存器的状态传送到r2

linux内核启动流程(基于arm)——head.S_第1张图片

linux内核启动流程(基于arm)——head.S_第2张图片

linux内核启动流程(基于arm)——head.S_第3张图片

safe_svcmode_maskall 是一个宏:

https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/assembler.h

https://elixir.bootlin.com/linux/latest/source/arch/arm/include/uapi/asm/ptrace.h#L63

宏展开

/*
 * Helper macro to enter SVC mode cleanly and mask interrupts. reg is
 * a scratch register for the macro to overwrite.
 *
 * This macro is intended for forcing the CPU into SVC mode at boot time.
 * you cannot return to the original mode.
 */
.macro safe_svcmode_maskall reg:req
#if __LINUX_ARM_ARCH__ >= 6 && !defined(CONFIG_CPU_V7M)
	mrs	\reg , cpsr
	eor	\reg, \reg, #HYP_MODE
	tst	\reg, #MODE_MASK
	bic	\reg , \reg , #MODE_MASK
	orr	\reg , \reg , #PSR_I_BIT | PSR_F_BIT | SVC_MODE
THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
	bne	1f
	orr	\reg, \reg, #PSR_A_BIT
	badr	lr, 2f
	msr	spsr_cxsf, \reg
	__MSR_ELR_HYP(14)
	__ERET
1:	msr	cpsr_c, \reg
2:
#else
/*
 * workaround for possibly broken pre-v6 hardware
 * (akita, Sharp Zaurus C-1000, PXA270-based)
 */
	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, \reg
#endif
.endm

    orr    \reg , \reg , #PSR_I_BIT | PSR_F_BIT | SVC_MODE

#define PSR_F_BIT	0x00000040	/* >= V4, but not V7M */
#define PSR_I_BIT	0x00000080	/* >= V4, but not V7M */
#define SVC_MODE	0x00000013

 

你可能感兴趣的:(linux内核)