内核启动流程分析
内核启动的终极目的是挂载根文件系统,运行应用程序;
内核基础操作
解压缩,并打补丁;
配置(有三种方法):
直接执行make menuconfig,从头到尾每一项都自己配置;
使用默认的配置,在此基础上来修改;
可以使用如下命令查找目前都有哪些默认配置:
find -name "*defconfig*" *
查找发现在./arch/arm/configs/目录下有很多默认的配置文件,可以在其中找到一个与自己单板比较接近的配置文件来使用和修改;
执行配置文件的操作命令是:
make xxxxx_defconfig
例如:make s3c2410_defconfig,执行后的结果是将所有的配置项写入到.config文件中;
make muneconfig
执行后会在xxxxx_defconfig配置基础上(读取.config文件)出现一个配置菜单,然后可进一步修改配置项;
使用厂家提供的配置文件;
厂家提供的文件一般为config_厂家,所以执行如下命令将文件转换为.config文件
cp config_厂家 .config
然后直接执行:make menuconfig进行配置;
编译
直接执行make,或者执行make uImage生成对应文件;
配置编译内核的过程分析
配置的结果就是生成了.config文件,里面的内容就是功能配置选项的宏,这些宏具有不同的值,表明这些功能在编译时,编入内核或者不编入内核或者以模块的形式编译(模块之后可以动态加载入内核);
当执行make uImage命令后:
- .config文件将生成/include/linux/autoconf.h文件,该文件被内核源码使用;
- .config文件将生成/include/config/auto.conf文件,该文件被顶层Makefile文件包含,在子目录下的Makefile文件中会使用到,会判断某个.o文件是被编译进内核还是编译成.ko模块;
内核启动过程分析
分析Makefile文件可以找到第一个被连接的文件(可以找到程序的入口依次分析启动流程)以及连接脚本(可以知道内核应该被放在哪里(连接地址)、内部是如何排布的);
第一个文件是:arch/arm/kernel/head.o arch/arm/kernel/init_task.o
连接脚本是:arch/arm/kernel/vmlinux.lds(根据文件vmlinux.lds.S编译后生成的);
处理流程:
判断是否支持这个CPU;
判断是否支持这个单板(参数由u-boot传入机器ID);
建立页表(虚拟地址到实际物理地址的转换);
使能MMU;
跳转到start_kernel(内核中执行的第一个C函数),在其中的setup_arch()和setup_commond_line()两个函数中处理u-boot中传入的参数,之后的调用关系依次是:
start_kernel setup_arch /* 解析u-boot传入的启动参数 */ setup_commond_line rest_init kernel_init prepare_namespace mount_root /* 挂载根文件系统 */ init_post /* 执行应用程序 */
内核中分区的定义
内核中所谓的分区是按照实际需求规划好后在代码中写的固定值,至于在哪个文件中写的,可以使用grep命令,查找"bootloader"字样,然后找对应的文件;