Linux移植之make uImage编译过程分析

发布者:MindfulCreator最新更新时间:2024-08-26 来源: cnblogs关键字:Linux移植  make  编译过程 手机看文章 扫描二维码
随时随地手机看文章

编译出uboot可以运行的linux内核代码的命令是make uImage,下面详细介绍下生成linux-2.6.22.6/arch/arm/boot/uImage的过程:

1、vmlinux、Image、uImage、zImage的区别

2、vmlinux生成过程简介

3、uImage生成过程简介

 

1、vmlinux、Image、uImage、zImage的区别,在执行make uImage之后会在%生成如下几个文件Image、uImage、zImage。

vmlinux是可引导的、压缩的内核。“vm”代表“Virtual Memory”。Linux 支持虚拟内存,不像老的操作系统比如DOS有640KB内存的限制。Linux能够使用硬盘空间作为虚拟内存,因此得名“vm”。它是elf格式的文件, 编译内核首先生成的是vmlinux,其它的文件都是基于此生成的。

Image是vmlinux经过OBJCOPY后生成的纯二进制映像文件

zImage是Image经过压缩后形成的一种映像压缩文件

uImage是在zImage基础上在前面64字节加上内核信息后的映像压缩文件,供uboot使用。可以从文件大小看到1848724-1848660=64字节


2、vmlinux生成过程简介,make uImage之后最先生成的是vmlinux,因为uImage依赖于vmlinux,在linux-2.6.22.6/arch/arm/Makefile下面有uImage这个目标,可以看到它依赖于vmlinux,所以先要分析vmlinux的生成过程


227    zImage Image xipImage bootpImage uImage: vmlinux

228        $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@

在linux-2.6.22.6/Makefile顶层Makefile下,定义了vmlinux这个目标


复制代码

745    vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE

746    ifdef CONFIG_HEADERS_CHECK

747        $(Q)$(MAKE) -f $(srctree)/Makefile headers_check

748    endif

749        $(call if_changed_rule,vmlinux__)

750        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@

751        $(Q)rm -f .old_version

复制代码

先逐个分析她的依赖vmlinux-lds、vmlinux-init、vmlinux-main、kallsyms.o、FORCE


 


1)、vmlinux-lds,它是一个链接脚本在链接的时候使用,它跟体系结构相关


611    vmlinux-lds  := arch/$(ARCH)/kernel/vmlinux.lds

 arch/$(ARCH)/kernel/vmlinux.lds一开始是不存在的,它依赖于$(vmlinux-dirs)


755    $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;

vmlinux-dirs这个变量是产生子目录下built-in.o文件的根源,这个在Linux移植之子目录下的built-in.o生成过程分析会介绍。


 


2)、vmlinux-init := $(head-y) $(init-y),其中head-y被定义在linux-2.6.22.6/arch/arm/Makefile中:


94    head-y        := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o

init-y被定义在顶层Makefile中:


434 init-y        := init/

573 init-y        := $(patsubst %/, %/built-in.o, $(init-y))

patsubst是Makefile的函数,意思是找到符合%/格式的,然后以%/built-in.o替换,所以最终init-y = init/built-in.o


所以vmlinux-init = arch/arm/kernel/head.o arch/arm/kernel/init_task.o init/built-in.o


 


3)、vmlinux-main被定义在顶层的Makefile中


609 vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)

类似与vmlinux-init的分析,最终vmlinux-main = usr/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o lib/lib.a lib/built-in.o drivers/built-in.o sound/built-in.o net/built-in.o


 


4)、kallsyms.o被定义在顶层的Makefile中


复制代码

679    ifdef CONFIG_KALLSYMS_EXTRA_PASS

680    last_kallsyms := 3

681    else

682    last_kallsyms := 2

683    endif

684

685    kallsyms.o := .tmp_kallsyms$(last_kallsyms).o

复制代码

顶层的Makefile会包含配置好的.config文件


192    KCONFIG_CONFIG    ?= .config

经查看CONFIG_KALLSYMS_EXTRA_PASS在.config没有设置,所以last_kallsyms := 3


62 # CONFIG_KALLSYMS_EXTRA_PASS is not set

最终kallsyms.o = .tmp_kallsyms2.o


接着寻找.tmp_kallsyms2.o,同样在顶层Makefile中


713    .tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE

714        $(call if_changed_dep,as_o_S)

$(call if_changed_dep,as_o_S)当这条规则被使用时它将检查哪些文件需要更新,或命令行被改变。同时它会重新检测依赖关系的改变并将生成新的依赖文件。所以这里是检查.o、.S、scripts文件是否被更新过。


scripts的定义如下:


429 PHONY += scripts

430    scripts: scripts_basic include/config/auto.conf

431    $(Q)$(MAKE) $(build)=$(@)

总结一下kallsyms.o依赖的作用就是检测以下所有生产vmlinux相关的文件是否更新过。


 


5)、FORCE在Linux移植之配置过程分析已经介绍过,每次执行的时候都认为这个变量是最新的


 


6)、因为CONFIG_HEADERS_CHECK在.config中没有找到,所以执行的规则为:


749        $(call if_changed_rule,vmlinux__)

750        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@

751        $(Q)rm -f .old_version

$(call if_changed_rule,vmlinux__)检查规则是否被改变。它的意思是调用if_changed_rule函数,函数参数为$(1)=vmlinux__。具体分析参考https://blog.csdn.net/zxygww/article/details/50249531。它被定义在linux-2.6.22.6scriptsKbuild.include中

183    if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ),                 

184        @set -e;                                                             

185        $(rule_$(1)))

这段话的意思是if_changed 函数在当发现规则的依赖有更新,或者是对应目标的命令行参数发生改变时($(if strip $(any-prereq) $(arg-check)) 语句结果不为空),执行后面的语句。set -e 表示如果命令执行有错那么命令停止执行并退出。接着执行 $(cmd_$(1) 里的命令rule_vmlinux__:它在顶层Makefile定义为一个shell脚本调用


复制代码

634    define rule_vmlinux__

635        :

636        $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))

637

638        $(call cmd,vmlinux__)

639        $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd

640

641        $(Q)$(if $($(quiet)cmd_sysmap),                                     

642          echo '  $($(quiet)cmd_sysmap)  System.map' &&)                     

643            $(cmd_sysmap) $@ System.map;                                         

644        if [ $$? -ne 0 ]; then                                               

645            rm -f $@;                                                   

646            /bin/false;                                                 

647        fi;

648        $(verify_kallsyms)

649        endef

复制代码

将上述内容实际打印出来得到,在编译内核时需要输入make V=1才能显示完整的内核编译信息。


复制代码

set -e; if [ ! -r .version ]; then rm -f .version; echo 1 >.version; else mv .version .old_version; expr 0$(cat .old_version) + 1 >.version; fi; make -f scripts/Makefile.build obj=init

  CHK     include/linux/compile.h

/bin/bash /work/system/linux-2.6.22.6/scripts/mkcompile_h include/linux/compile.h

    'arm' '' '' 'arm-linux-gcc -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Os -marm -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mapcs-32 -mno-thumb-interwork -D__LINUX_ARM_ARCH__=4 -march=armv4t -mtune=arm9tdmi -malignment-traps -msoft-float -Uarm -fno-omit-frame-pointer -fno-optimize-sibling-calls -g  -Wdeclaration-after-statement '

  UPD     include/linux/compile.h

  arm-linux-gcc -Wp,-MD,init/.version.o.d  -nostdinc -isystem /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/include -D__KERNEL__ -Iinclude  -include include/linux/autoconf.h -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Os -marm -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mapcs-32 -mno-thumb-interwork -D__LINUX_ARM_ARCH__=4 -march=armv4t -mtune=arm9tdmi -malignment-traps -msoft-float -Uarm -fno-omit-frame-pointer -fno-optimize-sibling-calls -g  -Wdeclaration-after-statement     -D'KBUILD_STR(s)=#s' -D'KBUILD_BASENAME=KBUILD_STR(version)'  -D'KBUILD_MODNAME=KBUILD_STR(version)' -c -o init/version.o init/version.c

   arm-linux-ld -EL   -r -o init/built-in.o init/main.o init/version.o init/mounts.o init/initramfs.o init/calibrate.o

  arm-linux-ld -EL  -p --no-undefined -X -o .tmp_vmlinux1 -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o arch/arm/kernel/init_task.o  init/built-in.o --start-group  usr/built-in.o  arch/arm/kernel/built-in.o  arch/arm/mm/built-in.o  arch/arm/common/built-in.o  arch/arm/mach-s3c2410/built-in.o  arch/arm/mach-s3c2400/built-in.o  arch/arm/mach-s3c2412/built-in.o  arch/arm/mach-s3c2440/built-in.o  arch/arm/mach-s3c2442/built-in.o  arch/arm/mach-s3c2443/built-in.o  arch/arm/nwfpe/built-in.o  arch/arm/plat-s3c24xx/built-in.o  kernel/built-in.o  mm/built-in.o  fs/built-in.o  ipc/built-in.o  security/built-in.o  crypto/built-in.o  block/built-in.o  arch/arm/lib/lib.a  lib/lib.a  arch/arm/lib/built-in.o  lib/built-in.o  drivers/built-in.o  sound/built-in.o  net/built-in.o --end-group 

echo 'cmd_.tmp_vmlinux1 := arm-linux-ld -EL  -p --no-undefined -X -o .tmp_vmlinux1 -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o arch/arm/kernel/init_task.o  init/built-in.o --start-group  usr/built-in.o  arch/arm/kernel/built-in.o  arch/arm/mm/built-in.o  arch/arm/common/built-in.o  arch/arm/mach-s3c2410/built-in.o  arch/arm/mach-s3c2400/built-in.o  arch/arm/mach-s3c2412/built-in.o  arch/arm/mach-s3c2440/built-in.o  arch/arm/mach-s3c2442/built-in.o  arch/arm/mach-s3c2443/built-in.o  arch/arm/nwfpe/built-in.o  arch/arm/plat-s3c24xx/built-in.o  kernel/built-in.o  mm/built-in.o  fs/built-in.o  ipc/built-in.o  security/built-in.o  crypto/built-in.o  block/built-in.o  arch/arm/lib/lib.a  lib/lib.a  arch/arm/lib/built-in.o  lib/built-in.o  drivers/built-in.o  sound/built-in.o  net/built-in.o --end-group ' > ./..tmp_vmlinux1.cmd

[1] [2]
关键字:Linux移植  make  编译过程 引用地址:Linux移植之make uImage编译过程分析

上一篇:Linux移植之auto.conf、autoconf.h、Mach-types.h的生成过程简析
下一篇:Linux移植之配置过程分析

推荐阅读最新更新时间:2024-11-12 23:01

基于3c2410的linux2.6.22移植(6)
2. LCD驱动移植:继续在mach-smdk2410.c中添加如下内容: . #include asm/arch/fb.h #include asm/arch/regs-gpio.h #include asm/arch/regs-lcd.h . . static struct s3c2410fb_mach_info smdk2410_lcdcfg __initdata={ .type=S3C2410_LCDCON1_TFT, .fixed_syncs= 0, .regs={ .lcdcon1= S3C2410_LCDCON1_TF
[单片机]
S3C2416 Linux2.6.21 驱动移植--添加UART3 及波特率设置bug消除
一,移植环境 (红色粗字体字为修改后内容,蓝色粗体字为特别注意内容) 1.主机环境:Virtualbox 下ubuntu-10.10 2.编译编译环境:arm-linux-gcc v4.4.3 3.uboot : U-Boot 1.3.4(友坚提供) 4.linux内核版本:2.6.21.5 5.硬件平台:采用友坚UT2416CV02核心板开发的平台 6.参考: linux内核支持S3C2416的UART3 (http://www.itkee.com/os/detail-1677.html ) S3C2416 User's Manual, Revision 1.10 二,添加UART3 S
[单片机]
goAhead 2.5嵌入式web服务器移植到arm9 2440 + linux
本文内容概要:详细描述了移植goAhead 2.5到S3C2440的linux系统的过程、步骤、遇到的问题及其解决方法。 开发环境: 宿 主 机:window XP; 虚 拟 机:ubuntu9.10; 交叉编译器:arm-uclibc-gcc(arm-linux-gcc-4.3.2可以顺利编译通过) ——————————————————————————————————————————————————————————————————— 1. GoAhead Web服务器介绍 goAhead Web服务器,小巧、精致,提供了值得称道的性能,特别适合于嵌入式系统,因此,在很多嵌入式产品如
[单片机]
Linux-2.6.32.2内核在mini2440上的移植(四)---根文件系统制作(3)
移植环境 1,主机环境:VMare下CentOS 5.5 ,1G内存。 2,集成开发环境:Elipse IDE 3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-linux-gnueabi-gcc v4.5.1。 4,开发板:mini2440,2M nor flash,128M nand flash。 5,u-boot版本:u-boot-2009.08 6,linux 版本:linux-2.6.32.2 7,参考文章: 嵌入式linux应用开发完全手册,韦东山,编著。 Mini2440 之Linux 移植开发实战指南 制作linux下根文件系统 系统启动挂载根文件系统时Kernel panic
[单片机]
linux-2.6.32在mini2440开发板上移植 移植I2C-EEPROM 驱动
1 在内核中配置I2C 驱动 Linux-2.6.32.2 对S2C2440 的I2C 接口提供了完善的驱动,因此我们只需在内核中配置一下即可使用。 在内核源代码目录执行:make menuconfig,进入内核配置主菜单,依次选择进入如下子菜单: Device Drivers --- * I2C support --- I2C Hardware Bus support --- 如图,我们看到这里已经选择好了“ * S3C2410 I2C Driver”,这里的S3C2410 也可以适用于S3C2440,因为它们的I2C 端口及寄存器定义都是完全相同的。 以上配置所对
[单片机]
<font color='red'>linux</font>-2.6.32在mini2440开发板上<font color='red'>移植</font> <font color='red'>移植</font>I2C-EEPROM 驱动
S3C6410嵌入式应用平台构建(四)——linux-3.14.4移植到OK6410-(初步启动)
这次,还是把基本的基于我目前最新的Linux源码进行移植到OK6410吧,同时也写下我移植过程中遇到的问题及解决方法,不过有些方法是借鉴网上的,有些是自己加的,会有一些小bug。 一、基本工作 1. 源码下载 https://www.kernel.org/ ,最好是下载stable版本,否则会有小bug。(我现在调试的是stable版本, linux-3.14.4) 2. 拷到自己的文件夹下解压,我下的是.xz后缀的,这样文件比较小,只是解压时多一个步骤。 $ xz –d linux-3.14.4.tar.xz $ tar xvf linux-3.14.4.tar 3. 解压完后,进入解压后的目录 二、源码
[单片机]
S3C6410嵌入式应用平台构建(四)——<font color='red'>linux</font>-3.14.4<font color='red'>移植</font>到OK6410-(初步启动)
05-S3C2440学习之内核(移植linux3.4.2移植(2) yffs2文件系统移植+内核裁剪+内核制作补丁
一、移植YFFS2文件系统 yffs文件系统更加支持nand设备 上节移植了jffs2文件系统(点击查看)到移植的内核中,这节我们将yffs2文件系统移植到刚移植好的内核中。 (1)获取源码并解压 git clone git://www.aleph1.co.uk/yaffs2 tar xjf yaffs2.tar.bz2 (2)给内核打上yffs2补丁 ./patch-ker.sh c m /home/book/linux-3.4.2 (3) 配置内核支持YAFFS 1. ls fs/yaffs2 (4)编译、生成uImage 出错,制作yffs2 source工程. (
[单片机]
05-S3C2440学习之内核(<font color='red'>移植</font>)<font color='red'>linux</font>3.4.2<font color='red'>移植</font>(2) yffs2文件系统<font color='red'>移植</font>+内核裁剪+内核制作补丁
linux-2.6.14移植到S3C2440
现在应该很少使用2.6.14的内核了,但由于项目需要,最近移植了2.6.版本的内核到S3C2440上,并移植了CS8900网卡驱动(网卡驱动移植参考 http://blog.csdn.net/ce123/article/details/8424399 )。之所以移植网卡驱动,是因为yaffs2格式的文件系统一直挂载不成功,启动后的错误信息如下: Mounted devfs on /dev Freeing init memory: 92K Failed to execute /linuxrc. Attempting defaults... Kernel panic - not syncing: No init found. Try p
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved