初始阶段
linux内核也不是很复杂,就是:
- 编译为很多built-in.o
- 链接为vmlinux
- 压缩为Image、zImage
ENTRY(stext)
位于arch/arm/kernel/vmlinux.lds
,进入入口函数stext
。
Linux内核会先进行解压缩,解压缩完成以后就要运行Linux内核。
要求:
- MMU关闭
- D cache关闭
- I cache无所谓
- r0 = 0。
- r1 = machine nr
- r2=atags 或设备树
linux内核第一阶段
stext函数
位于/arch/arm/kernel/head.S
__vet_atags 函数:验证atags或dtb是否有效,如果使用设备树的话就是dtb。
__create_page_tables :创建页表。
ldr r13, =__mmap_switched :r13保存__mmap_switched。
__enable_mmu 使能MMU
-> __turn_mmu_on
->_mmap_switched
->start_kernel 启动内核
linux内核第二阶段
kernel_init 函数
位于 /init/main.c
start_kernel
-> rest_init
-> kernel_thread(kernel_init, NULL, CLONE_FS); 创建kernel_init进程。也就是init进程,PID=1
-> kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); 创建kthreadd进程,进程PID为2。
-> cpu_startup_entry 进入空闲进程,也就是主进程退化为空闲进程,idle。
最后进入根文件系统,如果没有找到文件系统的init程序,那就完蛋了,,linux内核启动失败,最好不要发生这种情况。