Linux移植之make uImage编译过程分析中罗列出了最后链接生成vmlinux的过程。可以看到在每个子目录下都有一个built-in.o文件。对于此产生了疑问built-in.o文件是根据什么产生的。

arm-linux-ld -EL  -p --no-undefined -X -o vmlinux -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_kallsyms2.o

1、测试,在linux目录下添加一个test文件夹,在文件夹里面添加了test.c 和 Makefile。测试是否也会生成built-in.o文件

2、从顶层Makefile文件开始分析built-in.o原理

3、递归规则

1、测试,在linux目录下添加一个test文件夹,在文件夹里面添加了test.c 和 Makefile。测试是否也会生成built-in.o文件

a、mkdir test,创建test文件夹

b、cd test,进入test文件夹

d、vim Makefile,在里面创建Makefile

#
#Makefile for the linux kernel makefile experiment.
#
obj-y := test.o

e、vim test.c,在里面创建C文件

#include <linux/export.h>

int test_global = ;

f、修改顶层Makefile,在core-y后面增加test/目录

-core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ test/

g、make uImage后观察到在链接的过程中多出了test/built-in.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 test/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

2、从顶层Makefile文件开始分析built-in.o原理,在测试成功后,要分析是怎么做到更改了几个文件就能产生test/built-in.o并且编译进内核的。

从顶层Makefile开始分析,vmlinux-dirs包含了所有的linux子目录

vmlinux-dirs    := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
$(net-y) $(net-m) $(libs-y) $(libs-m)))
$(patsubst <pattern>,<replacement>,<text> )
名称:模式字符串替换函数——patsubst。
功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“ 换行”分隔)是否符合模
式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”,
表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>中的这个“%”
将是<pattern>中的那个“%”所代表的字串。(可以用“\”来转义,以“\%”来表示真实含
义的“%”字符)
返回:函数返回被替换过后的字符串。
$(filter <pattern...>,<text> )
名称:过滤函数——filter。
功能:以<pattern>模式过滤<text>字符串中的单词,保留符合模式<pattern>的单词。可以有
多个模式。
返回:返回符合模式<pattern>的字串。

另外在arch/arm/Makefile下也定义了一些文件夹:

    core-y                += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y += $(MACHINE)
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2400/
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2412/
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2440/
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2442/
core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2443/
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/ # If we have a common platform directory, then include it in the build.
core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/
core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/
core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/ libs-y := arch/arm/lib/ $(libs-y)

展开得到

vmlinux-dir = init usr \
arch/arm/kernel arch/arm/mm arch/arm/common arch/arm/mach-s3c2410 arch/arm/mach-s3c2400 arch/arm/mach-s3c2412 arch/arm/mach-s3c2440 \
arch/arm/mach-s3c2442 arch/arm/mach-s3c2443 arch/arm/nwfpe arch/arm/plat-s3c24xx \
kernel mm fs ipc security crypto block test \
arch/arm/lib lib arch/arm/lib \
drivers sound net \

继续看顶层Makefile生成vmlinux-dirs的规则如下:

    $(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@

以创建的test目录为例:展开得到。它的意思是调用scripts/Makefile.build。令参数obj=test,然后make。

make -f scripts/Makefile.build obj=test

接着进入scripts/Makefile.build继续分析,它的默认目标是__build:

    PHONY := __build
__build: __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
$(subdir-ym) $(always)
@:

接着看builtin-target、lib-target,它们被定义的条件是obj-%、lib-%不能为空

    ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
lib-target := $(obj)/lib.a
endif ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
builtin-target := $(obj)/built-in.o
endif
名称:去空格函数——strip。
功能:去掉<string>字串中开头和结尾的空字符。
返回:返回被去掉空格的字符串值。

接着看生成builtin-target的规则,lib-target的规则类似,还是在scripts/Makefile.build里找到如下规则

    # To build objects in subdirs, we need to descend into the directories
$(sort $(subdir-obj-y)): $(subdir-ym) ; #
# Rule to compile a set of .o files into one .o file
#
ifdef builtin-target
quiet_cmd_link_o_target = LD $@
# If the list of objects to link is empty, just create an empty built-in.o
cmd_link_o_target = $(if $(strip $(obj-y)),\
$(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
rm -f $@; $(AR) rcs $@) $(builtin-target): $(obj-y) FORCE
$(call if_changed,link_o_target) targets += $(builtin-target)
endif # builtin-target

调用if_changed函数,进入scripts/Kbuild.include中

    if_changed = $(if $(strip $(any-prereq) $(arg-check)),                       \
@set -e; \
$(echo-cmd) $(cmd_$()); \
echo 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)

可以看到最后调用的是cmd_link_o_target 脚本,回到scripts/Makefile.build中:

    #
# Rule to compile a set of .o files into one .o file
#
ifdef builtin-target
quiet_cmd_link_o_target = LD $@
# If the list of objects to link is empty, just create an empty built-in.o
cmd_link_o_target = $(if $(strip $(obj-y)),\
$(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
rm -f $@; $(AR) rcs $@)

其中obj-y=test.o定义在test目录下的Makefile中,如下在scripts/Makefile.build中include了$(kbuild-dir)/Makefile,即test/Makefile

    kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)

将规则展开得到:最终得到了test/built-in.o

cmd_link_o_target = arm-linux-ld -EL -r -o test/built-in.o test.o arm-linux-ar rcs test/built-in.o  

3、递归规则。如果在子目录下还有子目录编译系统会怎么操作呢,下面就讲述递归的规则:

继续看scripts/Makefile.build,它包含了scripts/Makefile.lib

 include scripts/Makefile.lib

接着看到scripts/Makefile.lib,里面定义了subdir-ym 这个变量表示的是如果obj-y含有文件夹则将文件夹放到subdir-ym中

    __subdir-y    := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
subdir-m += $(__subdir-m)
obj-y := $(patsubst %/, %/built-in.o, $(obj-y))
obj-m := $(filter-out %/, $(obj-m)) # Subdirectories we need to descend into subdir-ym := $(sort $(subdir-y) $(subdir-m))

继续回到scripts/Makefile.build,看到有关subdir-y的规则

    $(subdir-ym):
$(Q)$(MAKE) $(build)=$@

可以看到这个规则与第二部分的规则很类似,这是一个递归调用,scripts/Makefile.build调用自己生成subdir-ym/built-in.o。具体分析与第二部分一样。下面截图自第二部分分析

子目录下的built-in.o 就是这么生成的。参考自https://www.ibm.com/developerworks/community/blogs/5144904d-5d75-45ed-9d2b-cf1754ee936a/entry/kernel-build-system?lang=en

Linux移植之子目录下的built-in.o生成过程分析的更多相关文章

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

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

  2. linux下删除目录及其子目录下某种类型文件

    Linux下,如果想要删除目录及其子目录下某种类型文件,比如说所有的txt文件,则可以使用下面的命令: find . -name "*.txt" -type f -print -e ...

  3. win下gvim或者linux下的vim安装vundle都适用的配置文件 - 在当前目录及其子目录下**, 的所有文件* 中, 搜索当前光标所在的单词

    gvim下的普通配置: if v:lang =~ "utf8$" || v:lang =~ "UTF-8$" set fileencodings=utf-8,g ...

  4. Linux: 在某个路径及其子目录下查找所有包含“hello abcserver”字符串的文件。

    find /etc -name “*” | xargs grep “hello abcserver” 在 / 及其子目录下查找所有包含UNEXPECTED_SCHEMA find /  -name * ...

  5. Linux移植随笔:终于解决Tslib的问题了【转】

    转自:http://www.latelee.org/embedded-linux/porting-linux-tslib.html 前段时间让Tslib搞晕头了,原来一切都是版本惹的祸.本文只是一个随 ...

  6. ZYNQ Linux 移植:包含petalinux移植和手动移植debian9

    参考: https://electronut.in/workflow-for-using-linux-on-xilinx-zynq/ https://blog.csdn.net/m0_37545528 ...

  7. linux复制指定目录下的全部文件到另一个目录中

    linux复制指定目录下的全部文件到另一个目录中复制指定目录下的全部文件到另一个目录中文件及目录的复制是经常要用到的.linux下进行复制的命令为cp.假设复制源目录 为 dir1 ,目标目录为dir ...

  8. Linux中/proc目录下文件详解

    转载于:http://blog.chinaunix.net/uid-10449864-id-2956854.html Linux中/proc目录下文件详解(一)/proc文件系统下的多种文件提供的系统 ...

  9. Linux 统计文件夹下文件个数

    查看统计当前目录下文件的个数,包括子目录里的. ls -lR| grep "^-" | wc -l Linux下查看某个目录下的文件.或文件夹个数用到3个命令:ls列目录.用gre ...

随机推荐

  1. vmware搭建lnmp环境配置域名

    找到nginx配置文件,修改server_name 然后找到/etc/hosts文件 修改成如下 之后在Windows本地的C盘的hosts文件中添加解析 好了,这样就可以访问了 通往牛逼的路上,在意 ...

  2. VC++ 获取系统时间、程序运行时间(精确到秒,毫秒)的五种方法

    1.使用CTime类(获取系统当前时间,精确到秒) CString str; //获取系统时间 CTime tm; tm=CTime::GetCurrentTime();//获取系统日期 str=tm ...

  3. Python unindent dese not match any out indentation level 问题

    今天写个小程序出现 “unindent dese not  match any out indentation level”. 一直没找到原因,经过仔细对比发现实际上是缩进的问题. 上下两行的缩进用的 ...

  4. WilliamChart各种图表效果实现大全《IT蓝豹》

    WilliamChart各种图表效果实现大全,有水平线条表格,有柱状表格等.由LineFragment,BarFragment,StackedFragment,SandboxFragment几个fra ...

  5. SPSS-聚类分析

    聚类分析(层次聚类分析(Q型聚类和R型聚类).快速聚类分析) 聚类分析的实质:是建立一种分类方法,它能够将一批样本数据按照他们在性质上的亲密程度在没有先验知识的情况下自动进行分类.这里所说的类就是一个 ...

  6. jquery val() text() html()的区别

    value()主要用在表单元素上,如果其他的元素获取value是通过attract()的方法,text()是获取元素的纯文本,如果text(“content”)就会更改元素的文本内容:html()获取 ...

  7. windows的cmd下面格式化某个盘符

    1.crl+R 输入cmd回车. 2.如果要格式化的是E盘,哪直接输入 在DOS窗口中输入“format  f: “ ,其中:format 为格式化命令,f: 为需要格式化的分区

  8. ScrollReveal.js 用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力。

    ScrollReveal.js 用于创建和管理元素进入可视区域时的动画效果,帮助你的网站增加吸引力. 1.http://www.yangqq.com/jstt/css3/2017-08-08/787. ...

  9. keras初探

    1.对网络的理解: 2.怎样训练,输入已经数据,经过训练,输入测试数据,得到相似数据 3.RNNs  循环神经网络

  10. 添加setuptools脚本

    #!/usr/bin/env python """Setuptools bootstrapping installer. Maintained at https://gi ...