linux内核启动流程分析

上节内容:
配置内核的结果是,生成一个.config文件,该文件又自动生成一个include/config/auto.conf和include/linux/autoconf.h,其中后者给C的源代码使用,会包含在C源码代码中;前者被顶层的makefile包含,给子目录的makefile使用。
这一点可以通过查找其中某一项模块来跟踪。

本节:

子目录的makefile;
架构相关的makefile(/arch/arm/makefile);
分析一个makefile,从其命令开始分析,make,make uImage,从顶层makefile开始分析。
分析make uImage命令,该目标uImage在顶层makefile里没有,其位置在arch/arm/makefile,则此makefile会被包含进入顶层makefile中。

auto.conf文件也被顶层makefile包含。

回到目标make uImage,在架构makefile中,uImage是内核加头部,uImage依赖于vmlinux,vmlinux是真正的内核;
我们直接命令make,这执行第一个目标all,all也依赖与vmlinux。那么vmlinux依赖于谁呢?
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
以上各部分依赖如下:
vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds  := arch/$(SRCARCH)/kernel/vmlinux.lds
然后,接着分析
head-y:不在顶层makefile,在架构相关makefile中
将上诉依赖一一陈列,再去细细分析可能就会比较繁琐,我们可以通过一一分析makefile去了解文件的连接方式,也可以使用另一种比较实用的方式,直接编译,找出最后一句已执行命令的输出,分析该输出语句。
通过该语句的分析,可以找出:
第一个文件:arch/arm/kernel/head.S
连接脚本:arch/arm/kernel/vmlinux.lds(源码中是vmlinux.lds.S)
文件连接的顺序由命令中.o文件的位置决定 

内核启动流程:
分析makefile的时候我们看到的第一个文件head.S,就是我们分析内核的起始文件!
head.S有两个,一个处于compressed里面:
内核很大,压缩一下,压缩后的代码前加一个自解压代码,因此有一段head.S是在compressed文件夹里。
我们此处暂且只关心真正的head.S。
head.s内核工作:
1.处理uboot传入的数据:机器ID,启动参数;
a.判断是否支持这个CPU;
b.判断是否支持这个单板;
c.建立一级页表;
d.使能mmu
c.跳到start_kernel,此函数即为kernel的第一个c函数;
abc中是在汇编代码中处理有关机器ID的相关的东西,启动参数是在start_kernel开始处理;
直到这里,进行各种初始化。
我们移植uboot,kernel等等,最终的目的是什么?是运行我们的应用程序。那么放在哪里?应用程序放在根文件系统中,因此在运行应用程序之前我们要挂在文件系统。
start_kernel最后回去调用rest_init,该函数嗲用kernel_thread,启动一个线程函数kernel_init,在其中调用prepare_namespace,该函数中又调用了mount_root()挂载根文件系统。挂载上根文件系统后,kernel_init中后面调用init_post()执行应用程序。这个启动层级结构如下:
linux内核启动流程分析_第1张图片
 

你可能感兴趣的:(linux,内核,启动流程)