1.根据内核启动流程,在内核源码的文件中对应位置加打印信息输出,通过打印信息跟踪程序运行情况。 编译源码后,放在板子上运行。
a. 自解压 decompess (arch/arm/boot/compressed/head.S) 汇编
b. 检测合法性 入口 stext (arch/arm/kernel/head.S)
(CPU 类型 机器类型)
c. 运行 C代码 start_kernel (init/main.c)
d. 挂载 rootfs
e. 运行第一个应用程序 linuxrc
a.自解压部分,代码位置
arch/arm/boot/compressed/misc.c
decompress_kernel函数
b. 检测合法性,代码位置
arch/arm/kernel/head.S
stext函数
跳到__enable_mmu函数
调用__enable_mmu函数使能MMU,__enable_mmu定义在文件arch/arm/kernel/head.S中。
__enable_mmu最终会通过调用__turn_mmu_on来打开MMU,__turn_mmu_on最后会执行r13里面保存的__mmap_switched函数。
__mmap_switched函数定义在文件arch/arm/kernel/head-common.S中
因为以上部分都是arm汇编代码,所以决定再后面的start_kernel C代码的开始部分加入打印字符。
start_kernel函数最后调用了rest_init函数
rest_init函数定义在文件init/main.c中
创建内核进程init
kernel_init函数就是init进程具体做的工作,定义在文件init/main.c中
execute_command的值是通过uboot传递,在bootargs中使用“init=xxxx”就可以了,比如“init=/linuxrc”表示根文件系统中的linuxrc就是要执行的用户空间init程序。
kernel_init_freeable函数用于完成init进程的一些其他初始化工作.
kernel_init_freeable定义在文件init/main.c中
调用函数prepare_namespace来挂载根文件系统。跟文件系统也是由命令行参数指定的,也就是uboot的bootargs环境变量。比如“root=/dev/nfs nfsroot=192.168.1.141:/volume1/rootfs rw”.