首先根据开发板的资料,在自己的开发环境中建立交叉编译环境,安装交叉编译工具链。
厂家提供的内核源码拷贝到开发机中,解压并进入到主路径:
tar -xvzf linux-2.6.28.6-20111212.tar.gz
cd linux-2.6.28.6/
zdy@ubuntu:~/work/linux-2.6.28.6$ ls -alh
total 1020K
drwxr-xr-x 22 zdy zdy 4.0K Dec 12 2011 .
drwxrwxr-x 6 zdy zdy 4.0K Apr 2 19:58 ..
drwxr-xr-x 24 zdy zdy 4.0K Dec 8 2009 arch
drwxr-xr-x 2 zdy zdy 4.0K Dec 12 2011 block
-rw-r--r-- 1 zdy zdy 67K Apr 30 2009 ChangeLog
-rw-r--r-- 1 zdy zdy 64K Apr 30 2009 ChangeLog_mfc
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_a70
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_ezvga
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_h43
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_l80
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_n43
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_s70
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_t35
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_vga1024x768
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_vga640x480
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_vga800x600
-rw-r--r-- 1 zdy zdy 42K Dec 12 2011 config_mini6410_w50
-rw-r--r-- 1 zdy zdy 19K Apr 30 2009 COPYING
-rw-r--r-- 1 zdy zdy 92K Apr 30 2009 CREDITS
-rw-r--r-- 1 zdy zdy 11 Apr 7 2010 .cross_compile
drwxr-xr-x 3 zdy zdy 4.0K Dec 12 2011 crypto
drwxr-xr-x 82 zdy zdy 4.0K May 27 2010 Documentation
drwxr-xr-x 83 zdy zdy 4.0K Dec 12 2011 drivers
drwxr-xr-x 18 zdy zdy 4.0K Dec 12 2011 firmware
drwxr-xr-x 63 zdy zdy 4.0K Dec 12 2011 fs
-rw-r--r-- 1 zdy zdy 867 Apr 30 2009 .gitignore
drwxr-xr-x 27 zdy zdy 4.0K Dec 12 2011 include
drwxr-xr-x 2 zdy zdy 4.0K Dec 12 2011 init
drwxr-xr-x 2 zdy zdy 4.0K Dec 12 2011 ipc
-rw-r--r-- 1 zdy zdy 2.4K Apr 30 2009 Kbuild
drwxr-xr-x 6 zdy zdy 4.0K Dec 12 2011 kernel
drwxr-xr-x 6 zdy zdy 4.0K Dec 12 2011 lib
-rw-r--r-- 1 zdy zdy 3.9K Apr 30 2009 .mailmap
-rw-r--r-- 1 zdy zdy 104K Apr 30 2009 MAINTAINERS
-rw-r--r-- 1 zdy zdy 57K Dec 11 2011 Makefile
drwxr-xr-x 2 zdy zdy 4.0K Dec 12 2011 mm
drwxr-xr-x 45 zdy zdy 4.0K Dec 12 2011 net
-rw-r--r-- 1 zdy zdy 17K Apr 30 2009 README
-rw-r--r-- 1 zdy zdy 3.1K Apr 30 2009 REPORTING-BUGS
drwxr-xr-x 7 zdy zdy 4.0K Apr 30 2009 samples
drwxr-xr-x 10 zdy zdy 4.0K Dec 12 2011 scripts
drwxr-xr-x 5 zdy zdy 4.0K Dec 12 2011 security
drwxr-xr-x 20 zdy zdy 4.0K Dec 12 2011 sound
drwxr-xr-x 2 zdy zdy 4.0K Dec 12 2011 usr
drwxr-xr-x 3 zdy zdy 4.0K Apr 30 2009 virt
上述内核压缩包解压出来后,会有好多文件,具体文件先关内容解释如下:
首先根据厂家的指导书,我们先按照步骤进行配置
root@ubuntu:~/work/linux-2.6.28.6# cp config_mini6410_n43 .config
然后编译内核:
373 if (@val) {
374 @val = compute_values($hz);
375 }
make zImage V=1
当命令行编译时输入V=1时,可以清楚的看到每一条指令
编译过程中,可能由于版本问题,会出现如下错误:
Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
解决方案是将kernel/timeconst.pl中第373行的defined()去掉只留下@val就可以了,如下:
sudo vim kernel/timeconst.pl
改为如下内容即可
373 if (@val) {
374 @val = compute_values($hz);
375 }
在此编译,此错误消失
编译时间因电脑而已,稍等就是。最后编译结果如下:
最终编译的内核镜像在arch/arm/boot/路径下
把 zImage 下载到开发板接口运行起来了。
以上是实操,至于其编译原理,还需要解析其Makefile文件
FriendlyARM mini6410内核Makefile解析-文本注释
以下解析都是个人看法,如果不对之处,还请大家告知:
编译配置
在编译内核时,通常需要先配置,本开发板采用厂家提供的配置文件来做配置,可以更改或者默认。.config即为顶层配置文件,可以通过控制命令行输入make menuconfig来生成或者修改。顶层Makefile会使用这个.config文件来构建内核。include/config/auto.conf 路径下会自动生成一个auto.conf文件,各级Makefile可通过此文件来确定编译内容。
其次,大多数内核软件模块也通过.config文件间接地读取配置内容,原理如下:
在构建过程中,构建系统会处理这个.config文件,并生成一个名为autoconf.h的C语言头文件,放在目录…/include/linux中,这个文件是自动生成的。尽量不要直接修改这个文件。
综上所述:配置过程主要是通过make menuconfig来完成编译配置,并生成.config文件。在编译过程中,会自动生成include/config/auto.conf 文件工Makefile调用以及include/linux/autoconfig.h功内核源码引用.
编译内核
由用户层交互角度进行第二笔编译,通命令行make开始编译内核。根据Makefile规则,其默认规则是编译 make all,
根据上述四张图片及相关文件内容可知,编译目标文件为vmlinux、zImage及moudles
根据Makefile可以得到 vmlinux 依赖文件为:
编译zImage
根据arch/arm/Makefile中编译规则,其依赖文件为vmlinux,具体如下:
此步骤编译输出如下所示:
make -f scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/mach-s3c6400/ arch/arm/boot/zImage
编译Modules
由顶层Makefile解析后可知:vmlinux-dirs = init, arch/arm/kernel, arch/arm/mm, arch/arm/common, arch/arm/net, arch/arm/crypto, arch/arm/firmware, arch/arm/mach-astevb, drivers, sound, firmware, net, lib, arch/arm/lib
此步骤编译输出如下所示:
awk '!x[$0]++' /home/zdy/work/linux-2.6.28.6/init/modules.order /home/zdy/work/linux-2.6.28.6/usr/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/kernel/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/mm/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/common/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/mach-s3c6400/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/mach-s3c6410/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/plat-s3c64xx/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/plat-s3c/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/nwfpe/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/vfp/modules.order /home/zdy/work/linux-2.6.28.6/kernel/modules.order /home/zdy/work/linux-2.6.28.6/mm/modules.order /home/zdy/work/linux-2.6.28.6/fs/modules.order /home/zdy/work/linux-2.6.28.6/ipc/modules.order /home/zdy/work/linux-2.6.28.6/security/modules.order /home/zdy/work/linux-2.6.28.6/crypto/modules.order /home/zdy/work/linux-2.6.28.6/block/modules.order /home/zdy/work/linux-2.6.28.6/drivers/modules.order /home/zdy/work/linux-2.6.28.6/sound/modules.order /home/zdy/work/linux-2.6.28.6/firmware/modules.order /home/zdy/work/linux-2.6.28.6/net/modules.order /home/zdy/work/linux-2.6.28.6/arch/arm/lib/modules.order /home/zdy/work/linux-2.6.28.6/lib/modules.order > /home/zdy/work/linux-2.6.28.6/modules.order
Building modules, stage 2.
make -f /home/zdy/work/linux-2.6.28.6/scripts/Makefile.modpost
scripts/mod/modpost -o /home/zdy/work/linux-2.6.28.6/Module.symvers -S -c -s
arm-linux-gcc -Wp,-MD,drivers/char/.mini6410_hello_module.mod.o.d -nostdinc -isystem /home/zdy/work/opt/FriendlyARM/toolschain/4.5.1/bin/../lib/gcc/arm-none-linux-gnueabi/4.5.1/include -D__KERNEL__ -Iinclude -I/home/zdy/work/linux-2.6.28.6/arch/arm/include -include include/linux/autoconf.h -mlittle-endian -Iarch/arm/mach-s3c6400/include -Iarch/arm/mach-s3c6410/include -Iarch/arm/plat-s3c64xx/include -Iarch/arm/plat-s3c/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -marm -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -D__LINUX_ARM_ARCH__=6 -march=armv6k -mtune=arm1136j-s -msoft-float -Uarm -Wframe-larger-than=1024 -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -Wdeclaration-after-statement -Wno-pointer-sign -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(mini6410_hello_module.mod)" -D"KBUILD_MODNAME=KBUILD_STR(mini6410_hello_module)" -DMODULE -c -o drivers/char/mini6410_hello_module.mod.o drivers/char/mini6410_hello_module.mod.c
arm-linux-ld -EL -r -o drivers/char/mini6410_hello_module.ko drivers/char/mini6410_hello_module.o drivers/char/mini6410_hello_module.mod.o
arm-linux-gcc -Wp,-MD,drivers/scsi/.scsi_wait_scan.mod.o.d -nostdinc -isystem /home/zdy/work/opt/FriendlyARM/toolschain/4.5.1/bin/../lib/gcc/arm-none-linux-gnueabi/4.5.1/include -D__KERNEL__ -Iinclude -I/home/zdy/work/linux-2.6.28.6/arch/arm/include -include include/linux/autoconf.h -mlittle-endian -Iarch/arm/mach-s3c6400/include -Iarch/arm/mach-s3c6410/include -Iarch/arm/plat-s3c64xx/include -Iarch/arm/plat-s3c/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -marm -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -D__LINUX_ARM_ARCH__=6 -march=armv6k -mtune=arm1136j-s -msoft-float -Uarm -Wframe-larger-than=1024 -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -Wdeclaration-after-statement -Wno-pointer-sign -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(scsi_wait_scan.mod)" -D"KBUILD_MODNAME=KBUILD_STR(scsi_wait_scan)" -DMODULE -c -o drivers/scsi/scsi_wait_scan.mod.o drivers/scsi/scsi_wait_scan.mod.c
arm-linux-ld -EL -r -o drivers/scsi/scsi_wait_scan.ko drivers/scsi/scsi_wait_scan.o drivers/scsi/scsi_wait_scan.mod.o
make -f /home/zdy/work/linux-2.6.28.6/scripts/Makefile.fwinst obj=firmware __fw_modbuild
如下是内核编译终端输出日志
FriendlyARM mini6410内核编译输出日志
综上分析,内核编译主要工作是在编译vmlinux,该文件也是各个镜像文件的依赖文件。编译此文件时,会逐级展开内核各文件夹下的子Makefile并编译各种文件,最终生成vmlinux文件。