首页 > 系统服务 > 详细

Linux内核编译make做了什么?

时间:2019-07-17 22:24:23      阅读:137      评论:0      收藏:0      [点我收藏+]

  执行make默认目标的依赖链如下:

  技术分享图片

  include/config/auto.conf去匹配include/config/%.conf,执行其命令$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig即make -f ./Makefile silentoldconfig该句执行与make x210ii_qt_defconfig相似 silentoldconfig匹配到%config,其依赖scripts_basic,生成fixdep  docproc  hash 再回到%config下执行$(Q)$(MAKE) $(build)=scripts/kconfig $@即make scripts/Makefile.build obj=scripts/kconfig silentoldconfig,其过程为Makefile.build 包含scripts/kconfig/Makefile,其包含了silentoldconfig目标,silentoldconfig又依赖于scripts/kconfig/conf, Makefile.host依据scripts/kconfig里的材料再次生成conf,回到执行silentoldconfig目标下的命令$< -s $(Kconfig) 即scripts/kconfig/conf -s arch/arm/Kconfig该命令根据.config和arch/arm/Kconfig生成include/config/auto.conf.cmd, include/config/auto.conf ,include/generated/autoconf.h 回到include/config/kernel.release,该目标命令$(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@,该句将版本信息输出到include/config/kernel.release,再回到prepare3,无命令;回到prepare2,无命令,到include/linux/version.h下执行$(call filechk,version.h)该句得到include/linux/version.h;再到include/generated/utsrelease.h下执行$(call filechk,utsrelease.h)得到include/generated/utsrelease.h;再回到prepare1,无命令;再到scripts_basic和上次功能一样;回到archprepare执行$(Q)$(MAKE) $(clean)=$(boot),该句产生include/generated/mach-types.h,该命令再arch/arm/Makefile中;回到prepare0 执行$(Q)$(MAKE) $(build)=即把当前目录传递给scripts/Makefile.build,则该makefile会包含根目录下的kbuild,根据该文件下的规则产生include/generated/bounds.h和include/generated/asm-offsets.h;回到prepare0 执行下一句$(Q)$(MAKE) $(build)=. missing-syscalls该句根据kbuild下的规则去执行scripts/checksyscalls.sh脚本,回到prepare,开始执行scripts下的命令$(Q)$(MAKE) $(build)=$(@)  即make -f scripts/Makefile.host obj=script  先包含scripts下的Makefile默认执行目标__build其此时依赖链如下:

__build:

$(subdir-ym)  $(always)

subdir-ym=scripts/mod  always= scripts/kallsyms   scripts/pnmtologo   scripts/conmakehash

开始$(subdir-ym)的命令$(Q)$(MAKE) $(build)=$@即make -f  scripts/Makefile.build obj=scripts/mod该命令先用scripts/mod/mk_elfconfig.c生成mk_elfconfig,再用mk_elfconfig生成mk_elfconfig.h,最后得到scripts/mod/modpost,退出回到$(always)得到scripts/kallsyms scripts/pnmtologo scripts/conmakehash退出scripts目标执行完成

  接下来回到目标$(vmlinux-dirs)执行至关重要的一句话$(Q)$(MAKE) $(build)=$@首先我们来分析$(vmlinux-dirs)它包含  $(init-y)   $(init-m)   $(core-y)   $(core-m)   $(drivers-y)   $(drivers-m)   $(net-y)   $(net-m)   $(libs-y)   $(libs-m) 基本也就是整个内核了,打印出来为:

vmlinux-dirs = init  usr  arch/arm/kernel  arch/arm/mm  arch/arm/common  arch/arm/mach-s5pv210  arch/arm/plat-s5p  arch/arm/plat-samsung  arch/arm/vfp  kernel  mm  fs ipc  security  crypto  block  drivers  sound  firmware  net  arch/arm/lib  lib,$(Q)$(MAKE) $(build)=$@将其一一执行
  $@=init时:$(Q)$(MAKE) $(build)=$@即为make -f scripts/Makefile.build obj=init 将包含init/Makefile,其中定义了一些变量和一些规则导致__build的依赖为编入内核模式即builtin-target = init/built-in.o最后根据scripts/Makefile.build,和init/Makefile中的规则生成 init/built-in.o,执行完成退出。

  最后生成$(vmlinux-lds)  vmlinux.o  $(kallsyms.o)  vmlinux,zimage

 

总结:

  生成内核的过程:先做准备工作,目标$(vmlinux-dirs)的依赖prepare的scripts用于产生头文件的一些功能文件,接着对$(vmlinux-dirs)下文件有一一生成,最后生成$(vmlinux-lds)  vmlinux.o  $(kallsyms.o)  vmlinux,zimage

 

关于文件生成机制:

  主Makefile调用scripts/Makefile.build并且传入obj变量指明要编译的文件目录,scripts/Makefile.build中会包含obj变量的makefile或者kbuild,如果执行时未传入目标则会默认执行scripts/Makefile.build中的__build,该目标有三种依赖模式:编入模式(链接到内核),非编入模式,编译子文件和主机编译模式,每种依赖模式的确定要根据obj中Makefile定义的变量来确定,编译规则则是按照scripts/Makefile.build,scripts/Makefile.host,scripts/Makefile.lib,obj/Makefile等来确定;如果执行时指定目标,则obj下的makefile必然有相应的目标与之对应,再根据scripts/Makefile.build,scripts/Makefile.host,scripts/Makefile.lib,obj/Makefile中的规则编译。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

Linux内核编译make做了什么?

原文:https://www.cnblogs.com/genshu123/p/11198790.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!