linux 内核启动分析
/arch架构相关/arch/arm/boot/zImage编译出的内核镜像/arch/arm/boot/dts设备树
/block块设备相关/crypto各种加密算法/Documentation各种文档/driver驱动/firmware有些外设或模块需要/fs文件系统相关/include头文件/init初始化相关/ipc进程间通信/kernel内核相关/lib库/mm内存管理相关算法、机制实现/net网络协议/sample简单的示例代码/script各种脚本/security安全相关/sound音频相关的,包含驱动/usr/virt虚拟化相关Kconfigmenuconfig 用到的Makefile顶层的vmlinux
做嵌入式 linux 开发,关注 boot 里的东西。还有参考现成驱动 driver 里的东西。老的 uboot 用 uImage 镜像。
启动流程
内核链接脚本 arch/arm/kernel/vmlinux.lds 里,可以找到 ENTRY(stext) 指定了内核入口,这个标识符定义在 arch/arm/kernel/head.S 中。
linux 内核启动之前的要求
关闭 MMU
关闭 D-Cache
I-Cache
需要准备的参数
r0 = 0
r1 = machine nr (机器ID)
r2 = atage 或者是 设备树的地址
最终调用定义在 init/main.c 里的 start_kernel() 函数来启动内核,这个函数调用了相当多的东西,最后调用了 rest_init() 函数,此函数会调用 kernel_thread(kernel_init, NULL, CLONE_FS); 创建 init 内核进程,此进程 PID 为 1。
init 进程一开始为内核进程,此进程会在后面根文件系统中查找名为 init 的程序,此程序处于用户态,通过运行此程序,init进程从内核态转到用户态。
之后还会创建 kthread 内核进程,PID 为 2 ,负责所有内核进程的调度和管理。
kernel_thread 中传入的第一个参数便是进程入口,此函数也定义 init/main.c 中。此进程中,首先看看有没有 Uboot 传入要执行的 init 的地址参数。如果没有的话,后面尝试去找 /sbin/init /etc/init /bin/init /sbin/sh 启动起来。如果什么东西都没有,那就 kernel panic 了。
最后更新于
这有帮助吗?