Level10day5 homework

1.根据内核启动流程,在内核源码的文件中对应位置加打印信息输出,通过打印信息跟踪程序运行情况。 编译源码后,放在板子上运行。

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

2.查找对应位置 写入打印代码

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”.

编译 测试

效果展示