Linux内核启动流程X86架构之一
简介
本文主要讲述(X86)linux内核启动的流程,从Makefile到内核启动再到执行第一个应用程序。
一.Makefile文件分析
先看看linux内核源码的文件架构,如图下:
由上图可知:图中的Makefile就是linux内核编译时用的主Makefile,接下来我们简要分析下Makefile文件的作用从而理解如何通过Makefile执行linux内核中的第一步:
①看看Makefile文件被执行时的开始all:vmlinux,如图下
②接下来看看vmlinux是什么
③我们在看看vmlinux具体做了什么,也就是理解清楚**vmlinux:**后面的语句
scripts/link-vmlinux.sh vmlinux_prereq (call if_changed,link-vmlinux)
这里我们主要看看这句: vmlinux_prereq (vmlinux-deps) 这个变量在Makefile的定义:
可以看到vmlinux-deps用了$(head-y) (head-y)在哪里被定义的呢?通过搜索发现主Makefile中没有被查到说明这是在其他的Makefile定义的,那么就有一个问题①主Makefile如何引入其他Makefile文件
如上图:#$(SRCARCH)=x86 include arch/$(SRCARCH)/Makefile
这里包含了arch目录下对应需要的Makefile,比如我们常见的pc机使用的就是x86架构,所以X86架构就是include arch/x86/Makefile
接下来我们就可以去看看x86下的Makefile文件,看看前文中的head-y在x86下的Makefile定义的是啥,如图下
图中的head.o就是第一个从Makefile看到的文件,那么我们看看我们找到的第一个文件。head.o是一个linux内核文件,是从.s汇编文件编译链接后得到的,那么我们就看看对应的.S文件都做什么哪些操作,以32位系统为例:head32.S在x86的kernel文件目录下,主要的作用是创建32位程序需要的环境,比如让CPU从16位实模式到32位保护模式,写入描述符等等,但主要的是开始内核
二.开始进入Linux真正的代码
head32.s通过调用initial_code进入i386_start_kernel函数,那么i386_start_kernel在哪里实现的呢?
通过分析这个i386_start_kernel主要的作用就是开始内核,我们接着往下分析,看看都做了什么(函数很长,长话短说)
start_kernel初始化一些系统需要的参数和软硬件条件,并调用rest_init函数执行第一个应用程序,接下来我们分析rest_init函数
rest_init中通过线程的方式调用kernel_init函数
接下来我们看看kernel_init:
①文件系统挂载
kernel_init()->prepare_namespace()->mount_root()
②执行应用程序:以下图是按函数调用流程
run_init_process
run_init_process调用do_execve
do_execve调用do_execveat_common
do_execveat_common函数