二、编译内核镜像过程

1、编译过程中涉及到到文件:

/Makefile 编译产生顶层vmlinux镜像文件
/scripts/Kbuild.include    make过程中到一些基本定义
/scripts/Makefile.lib       编译内核时用到到函数库文件
/scripts/Makefile.build     内核编译到相关命令文件
/arch/arm/Makefile        这个是体系结构相关makefile文件
/arch/arm/Kconfig        内核编译到配置文件
/arch/arm/boot/Makefile 生成uImage,zImage,Image到编译文件
/arch/arm/boot/compressed/Makefile 生成最终vmlinux到编译文件
/arch/arm/mach-sep4020/Makefile SEP4020系统结构的编译文件
 

2、编译过程解析;

2.1 /include/linux/autoconfig.h的产生:

在顶层Makefile的487行有相应的编译命令,这个就是把我们顶层的.config文件转变成相应的系统的autoconfig.h文件,而在/include/linux/config.h中有这么一句:
#include <linux/autoconf.h>
以后在c文件中会包含这个/include/linux/config.h头文件的,也即包含了linux/autoconf.h文件

2.2、vmlinux的依赖关系

2.2.1在/Makefile中的298行
# We need some generic definitions
include  $(srctree)/scripts/Kbuild.include
包含了scripts/Kbuild.include文件,在这里定义了大量的函数和变量,供顶层makefile和其他makefile文件使用。 

 
2.2.2在顶层makefile文件的第175行,包含了arch/arm/Makefile。这个是体系结构相关makefile文件。它定义了体系结构相关的一些变量及规则。
下面这个地方将/arch/arm/Makefile文件引入
2.2.3当执行”make”时,arch/arm/Makefile中的499行的规则将是make遇到的第一个规则:
all:   vmlinux
export KBUILD_IMAGE ?= vmlinux(变量赋值)
2.2.4vmlinux目标的规则在顶层Makefile的第741行定义。
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
         $(call if_changed_rule,vmlinux__)
         $(Q)rm -f .old_version

2.2.5这里涉及到几个变量,先看看这几个变量的定义,前三个变量分别在顶层Makefile的605、606、608行定义。 
2.2.6其中head-y在arch/arm/Makefile中第72行定义,
head-y                := arch/arm/kernel/head.o arch/arm/kernel/init_task.o

2.2.7 init-y在顶层makefile的462行定义 

 
后又在第567行进行处理
init-y              := $(patsubst %/, %/built-in.o, $(init-y))
  这里的$(patsubst %/, %/built-in.o, $(init-y)) 这个语句就是将init/ 下的所有c文件编译成目标文件build-in.o
所以变量init-y应为
init-y              := init/built-in.o
因此
vmlinux-init := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o init/built-in.o
同理,其他几个变量也可通过类似方法进行分析,这里不一一分析了。
2.5vmlinux-init这个变量的产生构建规则在顶层Makefile 747行定义:
$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
这里是一个空命令的规则。空命令行可以防止make在执行时试图为重建这个目标去查找隐含命令。其依赖为vmlinux-dirs,这个变量在顶层Makefile第561行定义:
这个变量指定了一系列要进入的下层目录。他的规则在顶层Makefile第757行定义
$(vmlinux-dirs): prepare scripts
       $(Q)$(MAKE) $(build)=$@
这里的两个依赖就不分析了,主要看一下这个规则的命令,build和$@变量展开后如下
       $(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build  \
        obj =$(vmlinux-dirs)
这里会再一次进入scripts/Makefile.build执行82行规则
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
        $(if $(KBUILD_MODULES),$(obj-m)) \
        $(subdir-ym) $(always)
       @:
 $(if $(KBUILD_BUILTIN),$(builtin-target))表示若KBUILD_BUILTIN定义了,则整个表达式为$(builtin-target)

因为KBUILD_BUILTIN在顶层Makefile 195行中被初始化为1,所以这个规则的依赖有一个builtin-target变量。这个变量在scripts/Makefile.build的77行定义
ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
builtin-target := $(obj)/built-in.o
endif
(strip用法:strip <选项> 输入文件   作用:从文件中删除符号和节)
变量obj就是vmlinux-dirs变量指定的目录,这在前面说到的。所以这里会构建$(vmlinux-dirs)/built-in.o目标,在scripts/Makefile.build文件的251行开始,有这个目标的规则及命令的定义 
 
scripts/Makefile.build在第15行开始包含了vmlinux-dirs变量指定目录中的Makefile文件,在这些makefile文件中会指定obj-y变量,它指定的都是一些*.o目标文件,
这些*.o文件的生成方法由scripts/Makefile.build文件192行的模式规则指定
%.o: %.c FORCE
       $(call cmd,force_checksrc)
       $(call if_changed_rule,cc_o_c)
这个就是我们看到的编译各个目录下.o目标文件的过程,这个中间在182行中:
$(if $($(quiet)cmd_cc_o_c),echo '  $(call escsq,$($(quiet)cmd_cc_o_c))';)  \(其中的分号表示不显示命令执行)
这个就会在屏幕上输出编译的信息:
CC      net/ipv4/devinet.o
通过上面这一系列的步骤,就编译链接出由变量vmlinux-init指定的目标,vmlinux-main变量指定的目标的构建与此类似。

Arm Linux交叉编译和连接过程分析(2)相关推荐

  1. Arm Linux交叉编译和连接过程分析(1)

    一.配置内核(Kconfig) 我们配置内核是实质是根据众多目录下面的Kconfig文件中组合成我们需要的一个最佳选择,即最终在根目录下面生成的.config文件,而这个文件会在根目录Makefile ...

  2. Arm Linux 交叉编译(交叉编译是什么?CROSS_COMPILE)(交叉编译工具链【待更】)

    文章目录 交叉编译 1.编译 2.本地编译 3.交叉编译 交叉编译工具链 交叉编译 在嵌入式系统开发中,经常会听到一个词:交叉编译.到底什么是"交叉编译"呢?为什么要使用" ...

  3. linux top交叉编译_Linux 系统下ARM Linux交叉编译环境crosstool工具

    Linux系统下ARM Linux交叉编译环境的建立目前流行的有三种途径. 一.使用别人编译好的开发工具链本文引用地址:http://www.eepw.com.cn/article/201611/31 ...

  4. arm ubuntu 编译boost_为arm linux 交叉编译boost 1.33.1

    首先在arm linux环境上要有zlib 1 解开boost压缩包, cd进入解压目录 2 编译出bjam,并配置好,看手册页 3 产生Makefile: ./configure "-sB ...

  5. arm linux 交叉编译boost库

    测试编译  boost_1.48_0  编译时thread编译失败 测试编译  boost_1.60_0  编译时thread编译成功 编译步骤: 1.运行 ./bootstrap.sh  此时形成b ...

  6. cgo linux arm,Golang交叉编译各个平台的二进制文件

    熟悉golang的人都知道,golang交叉编译很简单的,只要设置几个环境变量就可以了 # mac上编译linux和windows二进制 CGO_ENABLED=0 GOOS=linux GOARCH ...

  7. arm linux 脚本 排序,arm-linux连接以及连接脚本

    前言:arm linux的连接工具可以使用arm-linux-ld,在进行连接时可以使用-T命令采用脚本控制,如不指明脚本,则使用默认的脚本文件,参见arm-linux-ld的缺省linker scr ...

  8. arm linux 开机电路_ARM Linux启动过程分析

    摘 要: 嵌入式 Linux 的可移植性使得我们可以在各种电子产品上看到它的身影.对 于不 同体系结构的处理器来说 Linux 的启动过程也有所不同. 本文以 S3C2410 ARM 处理器为例, 详 ...

  9. linux c++ toolchain 配置文件,一步一步建立基于ARM+Linux的cross toolchain

    声明:本文在参考网上资料的基础上,以梁元恩的<如何为嵌入式开发建立交叉编译环境>为蓝本修改而成.对于自己在建立过程中遇到的问题进行了详细的说明,本文随自己学习的深入会进行相应的更新. 1引 ...

最新文章

  1. tensorflow学习笔记(四十五):sess.run(tf.global_variables_initializer()) 做了什么?
  2. C语言字符串大小写转换_只愿与一人十指紧扣_新浪博客
  3. 监测linux一些重要文件md5值脚本
  4. NET Core 3.0 AutoFac替换内置DI的新姿势
  5. 电机与系统计算机仿真作业,北邮计算机仿真期末大作业.docx
  6. GDB调试打印STL对象
  7. 阶梯式的岗位技术培训认证体系
  8. 在Windows 7上安装ACE 6.1.0
  9. 为什么说要注销 QQ 的,都是君子呢?
  10. Java高级开发面试,Java面试没有项目经验
  11. 科学家用Google Earth发现千年古迹
  12. 盲目自信、能力不足、年少轻狂,这是我创业失败后总结的3条血泪事实
  13. js实现文本语音播放
  14. 练习使用firewalld的masquerade和nat功能
  15. 网页设计的步骤和标准都有哪些?
  16. Redis统计用户访问量
  17. Python打开电脑文件夹
  18. 西安交通大学计算机组成实验报告,西安交通大学实验报告
  19. hgoi#20190821
  20. Win10彻底删除蓝牙设备

热门文章

  1. SQLServer windows身份验证连接字符串
  2. Java编程提高性能的26个方法
  3. android xml正方形,使用Android Constraintlayout创建一排均匀分布的正方形
  4. (二)ElasticSearch6.1.1 Python API
  5. 【算法设计与分析】03 算法及其时间复杂度
  6. Linux服务部署之NTP时间服务器
  7. day35-hibernate映射 03-Hibernate持久态对象自动更新数据库
  8. 关于oracle sql语句查询时表名和字段名要加双引号的问题
  9. C#中的interface
  10. Oracle RAC学习笔记:基本概念及入门