本帖最后由 xcoder 于 2016-3-19 20:51 编辑
实战3 编译Linux镜像 Linux作为一款开源操作系统,支持多种处理器架构,包含了海量的驱动程序。然而,对于一个特定的电路板而言,处理器型号以及板级的外设芯片已经固定。因此,我们不需要将所有架构的代码、驱动代码都编进内核镜像,只需要编译使用到的驱动程序或功能模块,这就需要对内核进行配置。在这一章中,将介绍如何配置和编译Linux内核镜像。最终的镜像文件在启动的第4阶段被使用。 图3.1 pcDuino启动流程
3.1 下载Linux源代码
使用git命令clone一份linux源码,位于linux目录。
- # git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
复制代码
3.2 配置内核
Linux通常使用menuconfig对内核进行配置,menuconfig是基于文本的配置界面。在linux源码根目录下执行make menuconfig可以打开配置界面, 如图3.2所示。 图3.2 linux配置界面 配置选项按照功能分组,有的配置选项可能存在子选项。每个具体的配置选项有三种状态: l 将该选项描述的功能编译进内核,属于内核的一部分。 l 将该选项描述的功能编译成模块,在需要时动态插入到内核中,插入后属于内核一部分。 l 不将该选项描述的功能编译进内核。 配置选项的状态通过选项行首括号内的标识符描述,共有三种括号,方括号、尖括号和圆括号,使用空格键可以切换括号内的标识符。
中括号:可以是空,可以是"*"。空代表不要编译,”*”号代表要编译进内核。 尖括号:可以是空,"*"和"M"。空代表不要编译,”*”号代表要编译进内核,”M”代表要编译成模块。 圆括号:需要填入合适内容或者从列表中选择一个选项 执行命令选择默认配置
- # ARCH=arm make sunxi_defconfig
复制代码Linux的arch/<ARCH>/configs目录下保存了很多电路板的默认配置,使用命令ARCH=<ARCH> make <boardname>_defconfig上述命令就是将默认配置文件arch/<ARCH>/configs/<boardname>_defconfig拷贝到linux源码根目录下并重命名为.config 打开配置界面,修改配置。 - # ARCH=arm make menuconfig
复制代码
配置清单中选择如下 SoC选项选择A20 图3.4 系统类别 图3.5 内核SOC配置 配置完毕,保存退出。 3.3 编译Linux 执行如下命令编译内核。通过变量LOADADDR设置的地址会在生成uImage镜像时使用,填入uImage文件描述头。u-boot在装载镜像的时候会将镜像拷贝到该地址。make后面参数uImage和dtbs意在告诉编译系统生成的目标文件是uImage和dtb文件。 - # ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LOADADDR=0x40008000 make uImage dtbs
复制代码3.4 查看Linux镜像以及dtb文件 Linux原始的ELF格式文件<linux>/vmlinux 图3.6 Linux原始镜像 u-boot可识别的文件<linux>/arch/arm/boot/uImage 图3.7 uImage镜像 DTB文件<linux>/arch/arm/boot/dts/sun7i-a20-nano.dtb 图3.8 DTB文件
内核编译之后,会生成不同类型的几种镜像文件,如vmlinux、zImage和uImage。 其中vmlinux是未经压缩的内核ELF格式的文件,zImage是vmlinux经过objcopy和gzip压缩后的文件,是ARM架构常用的一种压缩镜像文件。uImage是u-boot专用的镜像文件,它是在zImage之前加上一个长度为64字节的描述头,描述这个镜像文件的类型、加载位置、生成时间、大小等信息,定义如图3.9所示。 图3.9 uImage文件头格式
使用mkimage工具可以将zImage转换成uImage,但需要提供一些参数,常用参数含义如下: -A :用于指定CPU类型,比如arm、x86、mips、ppc -O :用于指定操作系统,比如freebsd、linux、vxworks -T :用于指定image类型,比如kernel、ramdisk、filesystem -C :用于指定压缩类型:none、gzip、bzip2 -a :用于指定uImage的加载地址 -e :用于指定内核的入口地址,一般是:uImage的载入地址+0x40(信息头的大小) -n :用于指定uImage在头结构中的命名 -d :用于指定无头信息的zImage文件名 -x :用于设置执行位置
下面是生成uImage文件的一个势示例
- # mkimage -A arm -O linux -T kernel -C none -a 40008000 -e 40008000 -n linux -d zImage uImage
复制代码
3.5 总结
本章讲解了Linux配置方法,配置选项各种状态的含义,以及Linux镜像编译方式,接着介绍了几种Linux常见镜像格式,尤其是pcDuino板使用的uImage文件,解释了uImage文件格式以及生成方式。 |