分析linux内核移植中vmlinux可执行文件是如何生成的?以及 uImage/zImage/Image/vmlinx之间关系

一:分析linux内核移植中vmlinux可执行文件是如何生成的?

1:进入内核源码顶层目录下打开Makefile文件,搜索vmlinux

         这里构建vmlinux的命令使用了makefile的内置函数call。这是一个比较特殊的内置函数,make使用它来引用用户自己定义的带有参数的函数。if_changed是kbuild定义的一个函数,这里通过call引用这个函数,传递的实参是link-vmlinux。

2:进入内核源码scripts/Kbuild.include目录下,搜索:if_changed

218 if_changed = $(if $(newer-prereqs)$(cmd-check),                              
219     $(cmd);                                                              

183 cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1))
 @set -e:在执行的时候有错误就直接退出
 $(cmd_$(1)) = cmd_uimage

3:实参:link-vmlinux

4:通过echo打印信息,进入内核源码  /scripts/link-vmlinux.sh文件中:

vmlinux_link()
{
    local lds="${objtree}/${KBUILD_LDS}"
    local output=${1}
    local objects
    local strip_debug

    info LD ${output}

    # skip output file argument
    shift

    # The kallsyms linking does not need debug symbols included.
    if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ] ; then                  
        strip_debug=-Wl,--strip-debug
    fi

    if [ "${SRCARCH}" != "um" ]; then
        objects="--whole-archive            \
            ${KBUILD_VMLINUX_OBJS}          \
            --no-whole-archive          \
            --start-group               \
            ${KBUILD_VMLINUX_LIBS}          \
            --end-group             \
            ${@}"

        ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux}  \
            ${strip_debug#-Wl,}         \
            -o ${output}                \
            -T ${lds} ${objects}
    else
        objects="-Wl,--whole-archive            \                    
            ${KBUILD_VMLINUX_OBJS}          \
            -Wl,--no-whole-archive          \
            -Wl,--start-group           \
            ${KBUILD_VMLINUX_LIBS}          \
            -Wl,--end-group             \
            ${@}"

        ${CC} ${CFLAGS_vmlinux}             \
            ${strip_debug}              \
            -o ${output}                \
            -Wl,-T,${lds}               \
            ${objects}              \
            -lutil -lrt -lpthread
        rm -f linux
    fi
}

二:整理内核编译流程:uImage/zImage/Image/vmlinx之间关系

1: 顶层目录下的vmlinux 是编译出来的最原始的内核文件,是未压缩的,vmlinux通过objcopy格式化转换为Image。

 60 $(obj)/Image: vmlinux FORCE
 61 $(call if_changed,objcopy)   ----->调用cmd_objcopy  

2:将Image镜像文件经过gzip压缩生成rch/arm/boot/compressed/vmlinx镜像文件

 178 $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
 179         $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
 180         $(bswapsdi2) $(efi-obj-y) FORCE
  
 182     $(call if_changed,ld) ---->cmd_ld
 arch/arm/boot/vmlinux.lds head.o piggy.o  debug.o lib1funcs.o lib1funcs.S ashldi3.S 
 bswapsdi2.S hyp-stub.S bswapsdi2.o lib.a
      
 arm-linux-gnueabihf-ld vmlinux.lds head.o piggy.o  debug.o lib1funcs.o lib1funcs.S 
 ashldi3.S bswapsdi2.S hyp-stub.S bswapsdi2.o lib.a -o vmlinux
 185 $(obj)/piggy_data: $(obj)/../Image FORCE
 186     $(call if_changed,$(gzip)) ----->调用cmd_gzip

 188 $(obj)/piggy.o: $(obj)/piggy_data

3:vmlinux通过格式化转换为zImage文件

66 $(obj)/zImage:  $(obj)/compressed/vmlinux FORCE                                                                67     $(call if_changed,objcopy) ---->cmd_objcopy
267 cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
arm-linux-gnueabihf-objcopy $(obj)/compressed/vmlinux zImage

4:zImage使用mkimage工具得到uImage,uImage在zImage前添加64字节头部信息

 89 $(obj)/uImage:  $(obj)/zImage FORCE
 90     @$(check_for_multiple_loadaddr) ------->检测uImage镜像文件的入口地址 
 91     $(call if_changed,uimage)------->call:调用if_changed命令,makefile中固定的用法

总结:

vmlinx--->objcopy--->Image--->gzip--->arch/arm/boot/compressed/vmlinx--->objcopy--->zImage--->mkimage--->uImage

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值