内核启动流程分析
一.内核启动流程之编译体验
1.解压缩 tar
2.打补丁 patch –p <补丁文件>
3.配置 (make menuconfig或者使用默认配置上修改或者使用厂家提供的)
使用默认配置上修改:
(1)在arch/arm/config下找到相似的配置文件(xxx_defconfig)
(2)make xxx_defconfig然后再make menuconfig
(3)在菜单中进行配置
使用厂家提供的:
(1)cp 厂家的config文件为 .Config
(2)make menucongfig
(3)在菜单中进行配置内核
4.编译 make uImage
二. 内核启动流程之配置
1.配置结果就是生成了.Config文件,查看.config文件
以配置项 config_DM9000为例:
(1)c源码用到了 config_DM9000(宏)
(2)子目录 makefile drivers/net/makefile(配置菜单里会显示 m 或者 y,配置为y就会编译进内核,定义为m就会编译为一个模块)
(3)include/config/auto.conf定义为m,或者y(也来源于config,这个文件会被顶层的makefile包含)
(4)include/linux/autoconf.h.(上面的宏从这里定义)这个文件是自动生成的,内容来源于.Config 文件。定义为1,宏就可以用了
Make uImage
(1).config 会自动生成autoconfig.h(源码文件会包含这个文件)和auto.conf(子目录下makefile会用)
Obj –y +=xxx.c 为 y 时表示.c文件会编译进内核里面
Obj –m +=yyy.o 为 m时会编译为 . ko模块
配置项没设置,表示该文件没有使用
分析makefile :可以知道 第一个文件(可以逐层跟踪),链接脚本(可以了解内核排布)
子目录下makeflie
Obj –m +=xxx.c
Obj –y +=xxx.c
想a.c b.c组成模块的方法
Obj –m +=ab.o a.c->a.o
ab –objs = a.o b.o è b.c->b.o è链接成ab.ko
make uimage的时候,目标没有在顶层文件夹下,位于arch/arm/makefile下
所以架构相关makefile肯定会包含到顶层相关makefile里
(打补丁操作会修改顶层目录下的makefile,)
顶层目录 makefile
uImage (头部+真正的内核)依赖于vmlinux,(正真的内核)
vmlinux依赖(在顶层makefile)
vmlinux-init := $(head-y) $(init-y)
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
init-y :=init/
init-y :=$/patsubst %/, %/built-in.c, $(init-y)=init/built-in.o
将init目录下的文件编译为built-in.o
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
直接编译查看编译原料
1.第一个文件:arch/arm/kernel/head.s
2.链接脚本:arch/arm/kernel/vmlinux.lds(决定内核的排布)
启动流程分析:
U-boot通过theKernel(0,bd->bi_arch_number,bd->bi_boot_params)
theKernel(内核入口地址)1.0 2.机器ID 3.参数存放的地址
所以内核启动的时候一定是要先处理u-boot存入的参数,内核的最终目的是运行应用程序,应用程序在根文件系统中,所以就是挂接根文件系统,启动应用
通过第一个文件开始进行分析。
1. u-boot 启动内核时传入的机器ID,解析是否支持当前的CPU