linux 内核交叉编译

我使用执行make menuconfig配置内核。使用之前,先执行make mrproper,该命令会删除内核源代码中的./config文件和.o文件保证源代码的干净。

在执行make menuconfig时,这里面会涉及到几个文件夹:

Linux内核根目录下的scripts文件夹

arch/$ARCH/Kconfig文件、各层目录下的Kconfig文件

Linux内核根目录下的makefile文件、各层目录下的makefile文件


Linux内核根目录下的的.config文件、arm/$ARCH/下的config文件


Linux内核根目录下的 include/generated/autoconf.h文件

其中,scripts文件夹存放的是跟make menuconfig配置界面的图形绘制相关的文件,无需关心。

分布在各目录下的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。在内核配置make menuconfig(或xconfig等)时,从Kconfig中读出配置菜单,用户配置完后保存到.config(在顶层目录下生成)中。在内核编译时,主Makefile调用这个.config,就知道了用户对内核的配置情况。Kconfig就是对应着内核的配置菜单。内核源码中,了解了Kconfig、Makefile和config,就大致了解了内核代码的整个框架。

在根目录下执行make menuconfig时,系统会读取arch/$ARCH目录下的Kconfig文件生成整个配置界面选项,其中$ARCH值可有Makefile文件获得:

SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
                                  -e s/arm.*/arm/ -e s/sa110/arm/ \
                                  -e s/s390x/s390/ -e s/parisc64/parisc/ \
                                  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
                                  -e s/sh[234].*/sh/ )

所以,在服务器中进行交叉编译时,需要显式设定ARCH的值,否则ARCH会使用SUBARCH的值。

交叉编译时,需要准备好交叉编译工具链和内核的源码。我使用的是迅为的IMX6开发板,在开发板中烧写Ubuntu系统。

首先,迅为的资料中已经包含了内核源码和工具链。进入kernel-imx目录,如下图所示:

linux 内核交叉编译

直接运行build_qt_kernel.sh脚本,即可编译内核。脚本中的内容如下:

linux 内核交叉编译

在kernel_imx/arch/arm/boot目录下生成内核镜像。

生成的zImage和uImage都是生成的可执行内核镜像文件,2者在u-boot中启动的方式分别为go addr与bootm addr来实现启动过程(未实验过,我使用的是uImage,用的是bootm)。

 对于Linux内核,编译可以生成不同格式的映像文件,例如:
# make zImage
# make uImage

    zImage是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明这个映像文件的类型、加载位置、生成时间、大小等信息。换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区别。另外,Linux2.4内核不支持uImage,Linux2.6内核加入了很多对嵌入式系统的支持,但是uImage的生成也需要设置。

使用hexdump命令,查看uImage和zImage,如下:

linux 内核交叉编译