#based on v2.6.26 kernel

Linux内核Makefile编译生成内核目标文件的过程

直接执行make的编译过程

  • 1.先找到入口点(入口点问题)

    #编译内核line502,直接执行make默认编译此项
    all: vmlinux
    #编译模块line1037,选择编译模块的话会到这里,另外还有其他许多all:target存在,为什么默认执行all: vmlinux ?
    all: modules
  • 2.继续找vmlinux目标
    # vmlinux image - including updated kernel symbols
    # vmlinux目标在line806
    vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
    # FORCE是伪目标,make假定伪目标的时间戳总是最新的,即总是被修改过,因此以它为“依赖”的“目标”“vmlinux”在每次make的时候都会被编译。
  • 3.理解$(vmlinux-lds) $(vmlinux-init) $(vmlinux-main)这个变量的作用
    # line656
    vmlinux-init := $(head-y) $(init-y)
    # -y是指配置为yes表示加入内核,-m是指配置为module,-n是指配置为no表示不加入内核
    vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
    vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
    vmlinux-lds  := arch/$(SRCARCH)/kernel/vmlinux.lds # SRCARCH为体系结构名,这里我们使用x86

生成的vmlinux.lds目标文件是链接生成vmlinux映像的链接描述文件ld script,从该文件中我们大致可以知道vmlinux映像的头部是$(head-y) $(init-y),vmlinux映像的主体部分是$(core-y) $(libs-y) $(drivers-y) $(net-y)等.具体我们可以仔细研究ld script to make i386 Linux kernel.

vmlinux映像
####################################################
#             #                                    #
#  $(head-y)  #  $(core-y) $(libs-y)               #
#  $(init-y)  #  $(drivers-y) $(net-y),etc.        #
#             #                                    #
####################################################
  • 找出$(vmlinux-init)或者说$(head-y) $(init-y)包含那些文件

先找init-y,轻易搞定如下:

# line452
init-y          := init/
# line621
init-y          := $(patsubst %/, %/built-in.o, $(init-y)) ## 表示将$(init-y)列表中"/"替换为"/built-in.o",也就是最终init-y == init/built-in.o

init/built-in.o目标在init目录下生成,其中包含start_kernel函数,这个函数是从启动代码进入linux kernel的点.

在根目录下的Makefile文件中我们找不到head-y的定义,那么head-y肯定在某个被包含(include)进来的文件中. 通过搜索include我们发现head-y可能在/arch/x86/Makefile中.

# line431
include $(srctree)/arch/$(SRCARCH)/Makefile

果然,在/arch/x86/Makefile中找到head-y,

# line161
head-y := arch/x86/kernel/head_$(BITS).o ## BITS是CPU处理的位数的定义,我们使用的32位CPU,这里直接使用32来代替,文件也就是head_32.o
head-y += arch/x86/kernel/head$(BITS).o # head32.o
head-y += arch/x86/kernel/init_task.o
  • vmlinux映像生成的一般规则综述

通过以上分析路径

all --> vmlinux --> $(vmlinux-lds) $(vmlinux-init) --> $(head-y) $(init-y) --
--> built-in.o head32.o head_32.o init_task.o --> *.c *.S

我们可以有了一个大致的概念,那就是通过内核配置信息,我们有了xxxx-y的目标列表,通过深度遍历依次去生成这些目标,并最终生成了vmlinux.

至于内核配置信息与xxxx-y的目标列表以及依然的目录文件等,是如何映射匹配的,还需要更仔细的分析.

  • bzimage - 对vmlinux映像的后续处理

并且在/arch/x86/Makefile中我们还可以发现对vmlinux映像的后续处理部分,后续处理之后的bzimage将会是

bzimage
####################################################
#         #                  #                     #
#  Setup  #  uncompress code #  compressed vmlinux #
#         #                  #                     #
####################################################

接下来我们看看对vmlinux映像的后续处理部分的Makefile,首先要找到起点:

# line200 of /arch/x86/Makefile
####
# boot loader support. Several targets are kept for legacy purposes boot := arch/x86/boot PHONY += zImage bzImage compressed zlilo bzlilo \ zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install # Default kernel to build
all: bzImage # KBUILD_IMAGE specify target image being built KBUILD_IMAGE := $(boot)/bzImage
zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage zImage bzImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE) ## 进入arch/x86/boot目录执行其Makefile $(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/bzImage compressed: zImage

转载于:https://www.cnblogs.com/armlinux/archive/2011/11/06/2396786.html

Linux内核Makefile编译生成内核目标文件的过程相关推荐

  1. 如何分析linux下的几种目标文件

    为什么80%的码农都做不了架构师?>>>    作者:snsn1984 本文中用到的命令: gcc -c addvec.c 生成可重定位目标文件addvec.o readelf ad ...

  2. Linux下如何将源文件逐步编译成目标文件的过程

    前言 请讲一下linux如何源文件逐步编译成可执行文件. 解答 首先先上图对编译的整个过程有个感性的认识,然后再逐步分析各个过程.  以hello.c 程序为例 # include <stdio ...

  3. socket:内核初始化及创建流(文件)详细过程

    socket中文名称为套接字,属于传输协议及功能接口的封装.socket首先初始化注册(socket)文件系统,然后由使用它的模块传入具体的地址族(类型)family,如ipv4模块中的(void)s ...

  4. Linux下gcc编译生成动态链接库*.so文件并调用它

    动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一 ...

  5. linux 如何产生so文件,printf()函数 【转】Linux下gcc编译生成动态链接库*.so文件并调用它(2)...

    本文仅限于介绍 linux 下的库. 1.2. 库的种类 linux 下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在编译过程中已经被载入可执行程序,因 ...

  6. 【转】Linux下gcc编译生成动态链接库*.so文件并调用它

    http://blog.sina.com.cn/s/blog_54f82cc20101153x.html 动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编 ...

  7. linux动态库编译gcc,printf()函数 【转】Linux下gcc编译生成动态链接库*.so文件并调用它(3)...

    如: export LD_LIBRARY_PATH='pwd' 将当前文件目录添加为共享目录 1.6.使用ldd工具,查看可执行程序依赖那些动态库或着动态库依赖于那些动态库: ldd 命令可以查看一个 ...

  8. c语言编译生成的目标文件拓展名,系统默认的C语言源程序文件的扩展名是(),经过编译后生成的目标文件的扩展名是(),经过连接后生成的可执行文件的扩展名是()。...

    系统序文常用的密钥分发技术有 CA 技术和[] 技术. 默认名名探究精神的重要性体现在以下哪些方面?() 如果采用偶校验,的目的可的扩0101010的校验位是(),0011011的校验位是(). 语言 ...

  9. linux下makefile

    概述 -- 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都 为你做了这个工作,但我觉得要作一个好的和 professional的程序员,mak ...

  10. linux下Makefile学习--注释很好

    什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都 为你做了这个工作,但我觉得要作一个好的和 professional的程序员,makefile还 ...

最新文章

  1. 十一、explain属性介绍
  2. LeetCode Add Two Numbers II(栈)
  3. 来自一位家长的肺腑之言,句句在理!!!
  4. CSS transform 使 fixed 定位失效?
  5. Java设计模式11:Facade
  6. RFC 8998: ShangMi (SM) Cipher Suites for TLS 1.3
  7. OOAD理论知识小结
  8. IPv6协议漏洞将威胁核心路由器安全
  9. python曲线图局部放大_python放大图片和画方格实现算法
  10. Threejs初级教程
  11. Java 设计模式 Factory Method 工厂方法 模式
  12. 页面加载过程中触发的事件
  13. 使用人人开源遇到的bug
  14. HCIA--路由交换
  15. python-文字pdf转换为图片pdf
  16. 计算机系统与外部交换信息主要通过显示器,微机系统与外部交换信息主要通过什么设备...
  17. 【图解】共模干扰,差模干扰
  18. java打印一个空心六边形_六边形架构 Java 实现
  19. 机器学习面试题总结(转)
  20. css盒模型(css盒模型包括)

热门文章

  1. 智能对话训练师进阶本领:复杂对话流程处理
  2. BERT大魔王为何在商业环境下碰壁?
  3. 【每日算法Day 95】美团笔试题:四面体方案个数
  4. 每日算法系列【LeetCode 881】救生艇
  5. 分享一些自用软件,学妹们用了都说好用!
  6. [EACL17]K-best Iterative Viterbi Parsing(K-best迭代维特比句法分析)
  7. NLP学习—11.实现基于PyTorch与LSTM的情感分类
  8. leetcode—20.二叉树构建相关题目leetcode总结
  9. 机器学习—XGBoost实战与调参
  10. LeetCode—Python版链表简单题(一)