首先加压开发过程自带的内核包,然后减压并打补丁,将厂家给的配置文件config_ok复制成为.config,最后执行make命令完成内核编译。减压和打补丁功能不多过多的描述,对于系统具体支持的模块进行配置。配置方式除了使用自己的方式,还可以通过make menuconfig看有配置界面出来,进行相应的配置。最后进行编译。
tar jxf linux-2.6.22.6.tar.bz2
patch -p1 < ../package/linux-2.6.22.6_jz2440.patch
cp config_ok .config
make uImage
kernel打补丁,编译流程
内核源码包: linux-2.6.22.6.tar.bz2
补丁文件: linux-2.6.22.6_jz2440_v2v3.patch
1. 解压
tar xjf linux-2.6.22.6.tar.bz2
2. 打补丁
cd linux-2.6.22.6 // 先进入源码顶层目录
patch -p1 < ../linux-2.6.22.6_jz2440_v2v3.patch // -p1 表示忽略补丁文件中的第一层目录
3. 配置, 配置的结果是为了生成.config
3.1 可以直接执行make menuconfig 从头到尾每一项都去配置一下
3.2 可以使用默认配置, 在默认配置上修改
find ./ -name "*defconfig" 命令可以找到默认配置文件,
arm架构默认配置文件所在目录linux-2.6.22.6/arch/arm/configs
在linux-2.6.22.6/arch/arm/configs目录下找到合适的默认配置文件, 比如s3c2410_defconfig
回到顶层目录执行
make s3c2410_defconfig // 所有配置信息保存到.config文件里面
然后执行
make menuconfig // 读取.config文件,修改菜单配置项
3.3 使用厂家提供的配置文件
找到厂家的配置文件,比如 config.ok
把config_ok复制为.config
cp cofig.ok .config
然后执行
make menuconfig // 读取.config文件,修改菜单配置项
4、编译
make uImage // uImage 是 头部 + 真正内核 的镜像文件
配置的结果就是生成了一个.config文件:
下面分析.config文件
里面是一些配置项, 配置项由以下几种值
=y 表示对这一选项的支持会编进内核里面去
=m 表示对这一选项的支持会编译成模块, 模块可以动态加载
is no set 表示未设置改选项
以CONFIG_DM9000=y为例:
搜索该选项包含的文件: grep "CONFIG_DM9000" * -nwR
book@www.100ask.org:/work/system/linux-2.6.22.6$ grep "CONFIG_DM9000" * -nwR
...
arch/arm/configs/s3c2410_defconfig:588:CONFIG_DM9000=y
...
arch/arm/plat-s3c24xx/common-smdk.c:46:#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
arch/arm/plat-s3c24xx/common-smdk.c:162:#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
arch/arm/plat-s3c24xx/common-smdk.c:200:#endif /* CONFIG_DM9000 */
arch/arm/plat-s3c24xx/common-smdk.c:250:#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
...
drivers/net/Makefile:197:obj-$(CONFIG_DM9000) += dm9dev9000c.o
drivers/net/Makefile:198:#obj-$(CONFIG_DM9000) += dm9000.o
drivers/net/Makefile:199:#obj-$(CONFIG_DM9000) += dm9ks.o
include/config/auto.conf:144:CONFIG_DM9000=y
include/linux/autoconf.h:145:#define CONFIG_DM9000 1
可以发现有以下几种文件用到了CONFIG_DM9000配置项:
1. C源码文件 用到CONFIG_DM9000宏, 在include/linux/autoconf.h中定义
2. 子目录drivers/net/Makefile
3. include/config/auto.conf
4. include/linux/autoconf.h 定义CONFIG_DM9000宏
include/linux/autoconf.h从名字可以看出autoconf.h是自动生成的,
autoconf.h的内容来源于.config,
当make uImage时候, make机制会自动的根据.config生成autoconf.h
下面分析include/linux/autoconf.h:
可以看到里面定义了一些宏, 这些宏几乎都被定义为1
.config中的配置项不管是=y或=m着这里都会被定义为1, 其他配置项定义了数据的都会照搬过来
#define CONFIG_DM9000 1
而.config配置项=m或=y是在子目录Makefile中体现
下面分析子目录Makefile:
obj-y += xxx.o // 表示xxx.o文件最终会被编译进内核里面
obj-m += aaa.o // 表示aaa.o文件最终会被编译成一个可加载的.ko模块里面
在子目录drivers/net/Makefile中
就是用到了.config中的CONFIG_DM9000=y
obj-$(CONFIG_DM9000) += dm9000c.o
=>
obj-y += dm9000c.o // 这样就会把dm9000c.o编译进内核
综上:
1. include/linux/autoconf.h所定义的宏来源于.config
2. 子目录的Makefile定义的obj-$(CONFIG_xx)是根据.config中的CONFIG_xxx=y或CONFIG_xxx=m决定的
子目录下的Makefile用到的配置项哪里来的???
来源于include/config/auto.conf, 而include/config/auto.conf也是来源于.config
include/config/auto.conf是根据.config自动生成的, 会被顶层Makefile包含用来给子目录Makefile使用
make uImage过程总结:
1、.config被用来自动创建include/linux/autoconf.h文件,给源代码使用
2、.config被用来自动创建include/config/auto.conf文件,被顶层Makefile来包含,给子目录下Makefile使用
下面从顶层Makefile分析.
3. Makefile分析
3.1. make help
直接打印方式给定了当前Makefile进行编译的方式和方法以及对应的编译结果放置在具体的位置。
编译过程中
MAKEFLAGS += -rR --no-print-directory 宏禁止在编译过程中打印目录的跳转动作,只显示编译目录文件所在的目录位置。
编译过程每个目录文件内部包含了自己的Makefile文件,也就是sub-makefile,只需要针对性修改相关的文件就可以实现本目录的编译。如果当前文件以来其他目录,在其他目录中定义的Makefile文件可能被应用。但是这种情况比较少发生。
V参数解析,如果命令行制定了V参数,获取赋值给KBUILD_VERBOSE,如果没有则默认参数为0,也就是默认不会有任何编译过程打印。
C参数戈丁当前代码检查作为C编译器的内容,1表示只检查从编译的文件。
M参数指定外部模块编译目录
O参数指定编译输出目录
获取代码目录和编译目录
SUBARCH指定用户当前执行的环境芯片架构类型
之后指定编译目的主机的ARCH架构,可以通过make来指定这个参数,未指定情况下默认是宿主机的编译内容
加载内核.config配置文件
指定内核使用shell,也同时指定内核编译工具链,编译模块等基本信息并export出来
Beautify output根据之前指定是否安静编译确定最终的编译输出内容
include $(srctree)/scripts/Kbuild.include文件制定了编译过程其他命令表示形式和安静编译的一些基本行为
Read KERNELRELEASE from include/config/kernel.release 获取内核基本发布和版本信息内容
将scripts中basic的内容包含进来进行编译,这个目录具体应该是文档相关的目录生成函数