首先需编译内核源码,生成内核链接器脚本。在 arch/arm/kernel/vmlinux.lds 中,有
第2行ENTYR指定了Linux内核入口stext,该文件定义在内核源码的arch/arm/kernel/head.S
head.S中有如下注释:
分析知:Linux内核启动前的要求如下:
1.关闭MMU;
2.关闭d-cache;
3.i-cache,无关紧要,打开或者关闭都可以;
4.r0 = 0;
5.r1 = machine nr;
6.r2 = atags 或者设备树起始地址。
代码粗略分析一些重要的点:
第92行,调用函数safe_svcmode_maskall确保CPU处于SVC模式,并且关闭了所有的中断。
第94行,读处理器ID,ID值保存在r9寄存器中。
第95行,调用函数__lookup_processor_type检查当前系统是否支持此CPU,如果支持的就获取procinfo信息,Linux每种处理器都对应一个procinfo。可以通过处理器ID来找到对应的procinfo结构。
第121行,调用函数__vet_atags验证atags或设备树(dtb)的合法性。
第128行,调用函数__create_page_tables创建页表。
第149行,将函数__mmap_switched的地址保存到r13寄存器中。
第161行,调用enable_mmu函数使能MMU.enable_mmu最终会通过调用turn_mmu_on来打开MMU,turn_mmu_on最后会执行r13里
面保存的__mmap_switched函数。
至此,完成stext工作,进入下一个阶段__mmap_switched,后面就是函数调用函数,直到最后Linux 内核挂载根文件系统,并且执行根文件系统中的init 程序,以此来进入用户态。