内核版本 3.10.90
对应文件:arch\arm\boot\compressed\head.S (下面的代码有删减)
.section ".start", #alloc, #execinstr
/* .start 段,在 arch\arm\boot\compressed\vmlinux.lds.in
* 里 _start 指向的就是 .start 段的开始
*/
/*
* sort out different calling conventions
*/
.align
.arm @ Always enter in ARM state
start: /* 进入linux后从此处开始执行 */
.type start,#function /* 申明 start 为函数 ??*/
.rept 7
mov r0, r0 /* 重复7次,占用了 28个字节,用来存放 ARM 异常向量表 ? ?*/
.endr
ARM( mov r0, r0 )
ARM( b 1f )
THUMB( adr r12, BSYM(1f) )
THUMB( bx r12 )
/* 下面这三个word的值都是用于 loader ? */
.word 0x016f2818 @ Magic numbers to help the loader
.word start @ absolute load/run zImage address
/* 即该文件前面定义的 start */
.word _edata @ zImage end address
/* 在 arch\arm\boot\compressed\vmlinux.lds.in
* 里定义,与链接相关
*/
THUMB( .thumb )
1:
mrs r9, cpsr
#ifdef CONFIG_ARM_VIRT_EXT
bl __hyp_stub_install @ get into SVC mode, reversibly
#endif
mov r7, r1 @ save architecture ID r1 里为 ID
mov r8, r2 @ save atags pointer, r2 里为 atags pointer
#ifndef __ARM_ARCH_2__
/*
* 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?
bne not_angel
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
/* cxsf:表示从低到高分别占用4个8比特的数据域,
* 分别表示控制域,扩充域和标志域
* 这是MSR指令在对 CPSR 和 SPSR 寄存器操作时,
* 为了避免对某些位的操作而影响其他域所定义的几个标志位 *
* c - control field mask byte(xPSR[7:0])
* x - extension field mask byte(xPSR[15:8])
* s - status field mask byte(xPSR[23:16)
* f - flags field mask byte(xPSR[31:24]).*/
#else
teqp pc, #0x0c000003 @ turn off interrupts
#endif
/*
* Note that some cache flushing and other stuff may
* be needed here - is there an Angel SWI call for this?
*/
/*
* some architecture specific code can be inserted
* by the linker here, but it should preserve r7, r8, and r9.
*/
.text
#ifdef CONFIG_AUTO_ZRELADDR
@ determine final kernel image address /* 指的是解压后kernel的运行地址 */
mov r4, pc
and r4, r4, #0xf8000000
add r4, r4, #TEXT_OFFSET /* TEXT_OFFSET 是从哪里来的呢 ???*/
#else
ldr r4, =zreladdr /* 在 arch\arm\boot\makefile 里指定
* 解压后 kernel运行的地址
*/
#endif
bl cache_on
restart: adr r0, LC0 /* 如果当前的代码段+dtb 与解压后的内核空间有 overwrite, 在
* 真正执行解压内核前要将当前代码段和dtb relocate 到一个合适的地点