您现在的位置是:首页 >学无止境 >分析vmlinux编译过程网站首页学无止境

分析vmlinux编译过程

qq_49846847 2024-06-14 17:20:24
简介分析vmlinux编译过程

vmlinux可执行文件产生:

1.在内核源码顶层目录下打开Makefile文件,搜索vmlinux,找到以下代码,可从中得知vmlinux的生成依赖于vmlinux-deps
 


        1178   vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
        1179       +$(call if_changed,link-vmlinux)
 

2.在内核源码顶层目录下打开Makefile文件,搜索vmlinux-deps
 

1147 vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS)           $(KBUILD_VMLINUX_LIBS)
 


3.找到vmlinux-deps的三个依赖,其中export KBUILD_LDS是链接文件,KBUILD_VMLINUX_LIBS := $(filter-out %/, $(libs-y)) 跟库有关,所以我们可以重点关注KBUILD_VMLINUX_OBJS

 
  1132 KBUILD_VMLINUX_OBJS := $(head-y) $(patsubst %/,%/built-in.a, $(core-y))
 
  1136 KBUILD_VMLINUX_LIBS := $(filter-out %/, $(libs-y))
 
  1143 export KBUILD_LDS          := arch/$(SRCARCH)/kernel/vmlinux.lds
 
 

4.通过打印KBUILD_VMLINUX_OBJS信息,会发现KBUILD_VMLINUX_OBJS是由各个子目录下的built-in.a和arch/arm/kernel/head.o组成
 

arch/arm/kernel/head.o init/built-in.a usr/built-in.a arch/arm/built-in.a arch/arm/mach-aspeed/built-in.a arch/arm/mach-milbeaut/built-in.a arch/arm/mach-stm32/built-in.a kernel/built-in.a certs/built-in.a mm/built-in.a fs/built-in.a ipc/built-in.a security/built-in.a crypto/built-in.a block/built-in.a arch/arm/lib/built-in.a lib/built-in.a arch/arm/lib/lib.a lib/lib.a drivers/built-in.a sound/built-in.a samples/built-in.a net/built-in.a virt/built-in.a


5.打开scripts/Makefile.build,我们可以发现built-in.a的生成

 
#
# Rule to compile a set of .o files into one .a file (without symbol table)
#
 
quiet_cmd_ar_builtin = AR      $@
      cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
 
$(obj)/built-in.a: $(real-obj-y) FORCE
    $(call if_changed,ar_builtin)

 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

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。