2023-3-8作业

作业:

1.分析vmlinux可执行文件是如何生成的?

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


1.分析vmlinux可执行文件是如何生成的?

1.在内核源码顶层目录下打开Makefile文件,搜索vmlinux
    vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
    +$(call if_changed,link-vmlinux)

2.If_changed是定义在scripts/Kbuild.include中的函数
    # Execute command if command has changed or prerequisite(s) are updated.
    if_changed = $(if $(newer-prereqs)$(cmd-check),
        $(cmd);                                                              \
        printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)

3.心的代码是 $(cmd) , 展开之后$(cmd_link-vmlinux), 也就是调用cmd_link-vmlinux函数。 
  cmd_link-vmlinux函数的定义在顶层Makefile
    # Final link of vmlinux with optional arch pass after final link
    cmd_link-vmlinux =                                                 \
        $(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)";    \
        $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)


4.第一行代码中$<代表第一个依赖项:/scripts/link-vmlinux.sh,进入内核源码/scripts/link- 
  vmlinux.sh文件中发现:
   
# Link of vmlinux
# ${1} - output file
# ${2}, ${3}, ... - optional extra .o files
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
}

由此可知:如果平台不是“um”,那么就调用链接器将变量KBUILD_ VMLINUX_INIT、KBUILD_VMLINUX_MAIN中记录的目标文件链接为vmlinux

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

uImage镜像文件

1.在内核源码顶层目录下打开Makefile文件,搜索uImage,发现没有目标,猜测在Makefile中包含其他路径的Makefile文件
    596 include arch/$(SRCARCH)/Makefile = arch/arm/Makefile
2.进入arch/arm目录下,打开Makefile文件,搜索uImage,打印每个变量信息
    323 $(BOOT_TARGETS): vmlinux
    324    $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
打印信息内容:
    @
    -f ./scripts/Makefile.build obj
    arch/arm/boot
    
    uImage
    make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/uImage
3.进入内核源码/scripts/Makefile.build文件,搜索uImage
     6 src := $(obj)=arch/arm/boot
     42 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))  kbuild-dir :=$(src)
     43 kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
          kbuild-file := $(kbuild-dir)/Kbuild和$(kbuild-dir)/Makefile
     44 include $(kbuild-file) :将 arch/arm/boot/Makefile和当前的Makfile.build文件合并
4.进入内核源码arch/arm/boot/,打开Makefile文件,搜索uImage
     89 $(obj)/uImage:  $(obj)/zImage FORCE
     90     @$(check_for_multiple_loadaddr) ------->检测uImage镜像文件的入口地址
     91     $(call if_changed,uimage)------->call:调用if_changed命令,makefile中固定的用法
5. 入内核源码arch/arm/boot/,打开Makefile文件,指定LOADADDR这个变量的信息,将加载的地址赋值    
     70 LOADADDR = 0xc2000000     -------> 需要添加内容                                                                                 
     71 ifneq ($(LOADADDR),)
     72   UIMAGE_LOADADDR=$(LOADADDR)
6.进入内核源码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
7. 进入内核源码scripts/Makefile.lib目录下,搜索cmd_uimage
        398       cmd_uimage = $(BASH) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \
        399             -C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \
        400             -T $(UIMAGE_TYPE) \
        401             -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
        402             -n $(UIMAGE_NAME) -d $< $@
    解析:
     385 MKIMAGE := ./scripts/mkuboot.sh    
     cmd_uimage = /usr/bin/mkimage -A arm -O linux -C gzip -T kernel -n uImage -d zImage
7.uImage和zImage之间关系?
    1)uImage使用在zImage使用mkimage工具得到的,uImage在zImage前添加64字节头部信息
    2)每次编译打印信息的内容就是编译到uImage中内容
    Image Name:   Linux-5.10.61
    Created:      Wed Mar  8 16:15:39 2023
    Image Type:   ARM Linux Kernel Image (uncompressed)
    Data Size:    7172080 Bytes = 7003.98 KiB = 6.84 MiB
    Load Address: c2000000
    Entry Point:  c2000000

 zImage镜像文件

1.进入内核源码arch/arm/boot/,打开Makefile文件,搜索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
2.zImage和arch/arm/boot/compressed/vmlinux关系?
    zImage是通过vmlinux格式化转换为的文件

compressed/vmlinux文件

1.进入内核源码arch/arm/boot/,打开Makefile文件,搜索vmlinux
     63 $(obj)/compressed/vmlinux: $(obj)/Image FORCE                                                                 
     64     $(Q) $(MAKE) $(build)=$(obj)/compressed $@
    执行命令:make -f ./scripts/Makefile.build obj=arch/arm/boot/compressed arch/arm/boot/compressed/vmlinux
2.进入内核源码arch/arm/boot/compressed,打开Makefile文件,搜索vmlinux
        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.进入内核源码scripts/Makefile.lib目录下,搜索cmd_gzip
         cmd_gzip =  $(KGZIP) -n -f -9 > $@ = gzip Image > vmlinx
4.rch/arm/boot/compressedvmlinux文件和Image之间关系
    将Image镜像文件经过gzip压缩生成rch/arm/boot/compressed/vmlinx镜像文件


   

Image镜像文件

1.进入内核源码arch/arm/boot/compressed,打开Makefile文件,搜索Image
     60 $(obj)/Image: vmlinux FORCE
     61     $(call if_changed,objcopy)   ----->调用cmd_objcopy  
2.Image和内核顶层目录下vmlinx关系
    vmlinux通过objcopy格式化转换为Image

总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值