版本:Linux3.0
Linux内核启动主要有两步:
- 汇编部分:设置临时页表,使能MMU,调用C函数,复制数据段,清除BSS段。
- start_kernel函数:内核初始化,重新设置页表,创建系统第一个进程,重新初始化串口,设置系统时钟
汇编部分:
输入:R0=0 R1=machine ID R2=参数列表地址 和 dtb保存地址
入口:head.s stext (arch/arm/kernel)
__HEAD
ENTRY(stext)
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
@ and irqs disabled
mrc p15, 0, r9, c0, c0 @ get processor id @ 从协处理器p15中读取处理器ID
bl __lookup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)? //movs :影响状态寄存器的mov指令
THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_p @ yes, error 'p'
#ifndef CONFIG_XIP_KERNEL //内核image在物理内存中的实际偏移地址。
adr r3, 2f //相对偏移,所以可以寻址,此处可以寻址很重要
ldmia r3, {r4, r8}
sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET)
add r8, r8, r4 @ PHYS_OFFSET
#else
ldr r8, =PLAT_PHYS_OFFSET
#endif
/*
* r1 = machine no, r2 = atags or dtb,
* r8 = phys_offset, r9 = cpuid, r10 = procinfo (arch/arm/include/asm/procinfo.h arch/arm/mm/proc-arm920.S)
*/
bl __vet_atags //验证参数列表或者设备树
#ifdef CONFIG_SMP_ON_UP
bl __fixup_smp
#endif
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
bl __fixup_pv_table
#endif
bl __create_page_tables
/*
* The following calls CPU specific code in a position independent
* manner. See arch/arm/mm/proc-*.S for details. r10 = base of
* xxx_proc_info structure selected by __lookup_processor_type
* above.
On return, the CPU will be ready for the MMU to be
* turned on, and r0 will hold the CPU control register value.
*/
ldr r13, =__mmap_switched @ address to jump to after
@ mmu has been enabled
adr lr, BSYM(1f) @ return (PIC) address
mov r8, r4 @ set TTBR1 to swapper_pg_dir
ARM( add pc, r10, #PROCINFO_INITFUNC )
THUMB( add r12, r10, #PROCINFO_INITFUNC )
THUMB( mov pc, r12 )
1: b __enable_mmu
ENDPROC(stext)
.ltorg
#ifndef CONFIG_XIP_KERNEL
2: .long .
.long PAGE_OFFSET
#endif
主要工作:
- 设置CPU模式为SVC模式,关闭IRQ FRQ
- 检查CPUID是否匹配,确定machine ID 检查合理性
- 获取phy&virt offset
- 检查atags参数
- 创建初始页表 (建立临时页表,映射整个4G物理地址,页表使用了16K=4*(4G/1M)内存,每一项4字节映射1MB的内存。通常这个临时页表中只有部分有效,只映射前几MB的内存。)
参考:
https://blog.csdn.net/skyflying2012/article/details/41344377
https://blog.csdn.net/zqixiao_09/article/details/50821995【汇编全流程详解】
https://blog.csdn.net/ooonebook/article/details/52850433【kernel启动流程】