Linux 的顶层 Makefile 和 uboot 的顶层 Makefile 非常相似,因为 uboot 参考了 Linux,前 602行几乎一样,所以前面部分我们大致看一下就行了。

版本号

MAKEFLAGS变量

MAKEFLAGS += -rR --include-dir=$(CURDIR)

命令输出

  • Linux 编译的时候也可以通过“V=1”来输出完整的命令,这个和 uboot 一样

实现源码

69 ifeq ("$(origin V)", "command line")
70 KBUILD_VERBOSE = $(V)
71 endif
72 ifndef KBUILD_VERBOSE
73 KBUILD_VERBOSE = 0
74 endif
75
76 ifeq ($(KBUILD_VERBOSE),1)
77 quiet =
78 Q =
79 else
80 quiet=quiet_
81 Q = @
82 endif

静默输出

  • Linux 编译的时候使用“make -s”就可实现静默编译,编译的时候就不会打印任何的信息,同 uboot 一样

实现源码

87 ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
88 ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
89 quiet=silent_
90 endif
91 else # make-3.8x
92 ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
93 quiet=silent_
94 endif
95 endif
96
97 export quiet Q KBUILD_VERBOSE

设置编译结果输出目录

  • Linux 编译的时候使用“O=xxx”即可将编译产生的过程文件输出到指定的目录中

实现源码

116 ifeq ($(KBUILD_SRC),)
117
118 # OK, Make called in directory where kernel src resides
119 # Do we want to locate output files in a separate directory?
120 ifeq ("$(origin O)", "command line")
121 KBUILD_OUTPUT := $(O)
122 endif

代码检查

  • Linux 也支持代码检查,使用命令“make C=1”使能代码检查,检查那些需要重新编译的文件。“make C=2”用于检查所有的源码文件

实现源码

172 ifeq ("$(origin C)", "command line")
173 KBUILD_CHECKSRC = $(C)
174 endif
175 ifndef KBUILD_CHECKSRC
176 KBUILD_CHECKSRC = 0
177 endif

模块编译

  • Linux 允许单独编译某个模块,使用命令“make M=dir”即可,旧语法“make SUBDIRS=dir”也是支持的

实现源码

179 # Use make M=dir to specify directory of external module to build
180 # Old syntax make ... SUBDIRS=$PWD is still supported
181 # Setting the environment variable KBUILD_EXTMOD take precedence
182 ifdef SUBDIRS
183 KBUILD_EXTMOD ?= $(SUBDIRS)
184 endif
185
186 ifeq ("$(origin M)", "command line")
187 KBUILD_EXTMOD := $(M)
188 endif
189
190 # If building an external module we do not care about the all: rule
191 # but instead _all depend on modules
192 PHONY += all
193 ifeq ($(KBUILD_EXTMOD),)
194 _all: all
195 else
196 _all: modules
197 endif
198
199 ifeq ($(KBUILD_SRC),)
200 # building in the source tree
201 srctree := .
202 else
203 ifeq ($(KBUILD_SRC)/,$(dir $(CURDIR)))
204 # building in a subdirectory of the source tree
205 srctree := ..
206 else
207 srctree := $(KBUILD_SRC)
208 endif
209 endif
210 objtree := .
211 src := $(srctree)
212 obj := $(objtree)
213
214 VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
215
216 export srctree objtree VPATH

外部模块编译过程和 uboot 也一样,最终导出 srctree、objtree 和 VPATH 这三个变量的值,其中 srctree=.,也就是当前目录,objtree 同样为“.”

设置目标架构和交叉编译器

  • 同uboot一样,Linux编译的时候需要设置目标板架构ARCH和交叉编译器CROSS_COMPILE

实现源码

252 ARCH ?= $(SUBARCH)
253 CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)

调用scripts/Kbuild.include文件

  • 同 uboot 一样,Linux 顶层 Makefile 也会调用文件 scripts/Kbuild.include

实现源码

348 # We need some generic definitions (do not try to remake the file).
349 scripts/Kbuild.include: ;
350 include scripts/Kbuild.include

交叉编译工具变量设置

  • LA、LD、CC 等这些都是交叉编译器所使用的工具

实现源码

353 AS = $(CROSS_COMPILE)as
354 LD = $(CROSS_COMPILE)ld
355 CC = $(CROSS_COMPILE)gcc
356 CPP = $(CC) -E
357 AR = $(CROSS_COMPILE)ar
358 NM = $(CROSS_COMPILE)nm
359 STRIP = $(CROSS_COMPILE)strip
360 OBJCOPY = $(CROSS_COMPILE)objcopy
361 OBJDUMP = $(CROSS_COMPILE)objdump

头文件路径变量

  • 顶层 Makefile 定义了两个变量保存头文件路径:USERINCLUDE 和 LINUXINCLUDE

实现源码

381 USERINCLUDE := \
382 -I$(srctree)/arch/$(hdr-arch)/include/uapi \
383 -Iarch/$(hdr-arch)/include/generated/uapi \
384 -I$(srctree)/include/uapi \
385 -Iinclude/generated/uapi \
386 -include $(srctree)/include/linux/kconfig.h
387
388 # Use LINUXINCLUDE when you must reference the include/ directory.
389 # Needed to be compatible with the O= option
390 LINUXINCLUDE := \
391 -I$(srctree)/arch/$(hdr-arch)/include \
392 -Iarch/$(hdr-arch)/include/generated/uapi \
393 -Iarch/$(hdr-arch)/include/generated \
394 $(if $(KBUILD_SRC), -I$(srctree)/include) \
395 -Iinclude \
396 $(USERINCLUDE)
  • 第 381~386 行是 USERINCLUDE 是 UAPI 相关的头文件路径
  • 第 390~396 行是LINUXINCLUDE 是 Linux 内核源码的头文件路径
  • 其中srctree=.,hdr-arch=arm,KBUILD_SRC 为空,因此,将 USERINCLUDE 和 LINUXINCLUDE 展开以后为:
USERINCLUDE := \
-I./arch/arm/include/uapi \
-Iarch/arm/include/generated/uapi \
-I./include/uapi \
-Iinclude/generated/uapi \
-include ./include/linux/kconfig.hLINUXINCLUDE := \
-I./arch/arm/include \
-Iarch/arm/include/generated/uapi \
-Iarch/arm/include/generated \
-Iinclude \
-I./arch/arm/include/uapi \
-Iarch/arm/include/generated/uapi \
-I./include/uapi \
-Iinclude/generated/uapi \
-include ./include/linux/kconfig.h

导出变量

  • 顶层 Makefile 会导出很多变量给子 Makefile 使用

实现源码

417 export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
418 export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
419 export CPP AR NM STRIP OBJCOPY OBJDUMP
420 export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
421 export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
422
423 export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
424 export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV CFLAGS_KASAN
425 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
426 export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
427 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
428 export KBUILD_ARFLAGS

make xxx_defconfig  过程

make过程

make zImage  过程

vmlinux 、Image ,zImage 、uImage 的区别

vmlinux 是 ELF 格式的文件,但是在实际中我们不会使用 vmlinux,而是使用 zImage 或 uImage 这样的 Linux 内核镜像文件

vmlinux 是编译出来的最原始的内核文件,包含符号表等信息并且是未压缩的。vmlinux 差不多有 16MB。

Image 是 Linux 内核镜像文件,但是 Image 仅包含可执行的二进制数据。Image 就是使用 objcopy 取消掉 vmlinux 中的一些其他信息,比如符号表什么的。但是 Image 是没有压缩过的,Image 保存在 arch/arm/boot 目录下。其大小大概在 12MB 左右。

zImage 是经过 gzip 压缩后的 Image,经过压缩以后其大小大概在 6MB 左右

uImage 是老版本 uboot 专用的镜像文件,uImag 是在 zImage 前面加了一个长度为 64字节的“头”,这个头信息描述了该镜像文件的类型、加载位置、生成时间、大小等信息。但是新的 uboot 已经支持了 zImage 启动!所以已经很少用到 uImage 了,除非你用的很古老的 uboot。

使用“make”、“make all”、“make zImage”这些命令就可以编译出 zImage 镜像

310 BOOT_TARGETS = zImage Image xipImage bootpImage uImage
......
315 $(BOOT_TARGETS): vmlinux
316 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
  • 第 310 行,变量 BOOT_TARGETS 包含 zImage,Image,xipImage 等镜像文件
  • 第 315 行,BOOT_TARGETS 依赖 vmlinux,因此如果使用“make zImage”编译的 Linux 内核的话,首先肯定要先编译出 vmlinux
  • 第 316 行,具体的命令,比如要编译 zImage,那么命令展开以后如下所示:
    @ make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/zImage
    看来又是使用 scripts/Makefile.build 文件来完成 vmliux 到 zImage 的转换。

imx6ull:顶层Makefile分析相关推荐

  1. imx6ull:uboot顶层Makefile分析

    版本号 MAKEFLAGES变量 20 MAKEFLAGS += -rR --include-dir=$(CURDIR) Makefile有两个特殊的变量:"SHELL"和&quo ...

  2. U-Boot顶层Makefile分析

    参考:U-Boot顶层Makefile介绍 作者:一只青木呀 发布时间: 2020-10-22 16:22:17 网址:https://blog.csdn.net/weixin_45309916/ar ...

  3. openwrt顶层Makefile分析-转

    openwrt 这里主要介绍openwrt的主Makefile,并未对各个目录下的Makefile和相关文件进行介绍. 在Makefile里是两个主要的分支,由if语句根据OPENWRT_BUILD的 ...

  4. u-boot 顶层Makefile 分析

    U-Boot 顶层Makefile 解析 u-Boot -Makefile(一)  声明 : 以下解析大部分来自网络大神之手 所以可以放心阅读  Good luck VERSION = 1 PATCH ...

  5. U-Boot 顶层 Makefile 分析二

    6.代码检查   uboot 支持代码检查,使用命令"make C=1"使能代码检查,检查那些需要重新编译的文件."make C=2"用于检查所有的源码文件 # ...

  6. u-boot的Makefile分析

    U-BOOT是一个LINUX下的工程,在编译之前必须已经安装对应体系结构的交叉编译环境,这里只针对ARM,编译器系列软件为arm-linux-*. U-BOOT的下载地址: http://source ...

  7. 【正点原子Linux连载】第三十一章 U-Boot顶层Makefile详解 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  8. U-Boot 顶层 Makefile 详解

    U-Boot 顶层 Makefile 详解 1.U-Boot 工程目录分析 我们在分析 uboot 源码之前一定要 先在 Ubuntu 中编译一下 uboot 源码,因为编译过程会生成一些文件,而生成 ...

  9. U-BOOT分析(二)之顶层Makefile文件(1)

    U-BOOT分析(二)之顶层Makefile文件(1) U-BOOT版本 u-boot版本:    u-boot-2021.01.tar.bz2 Makefile && make简介 ...

  10. Linux内核移植之一:内核源码结构与Makefile分析

    内容来自 韦东山<嵌入式Linux应用开发完全手册> 一.内核介绍 1.版本及其特点 Linux内核的版本号可以从源代码的顶层目录下的Makefile中看到,比如下面几行它们构成了Linu ...

最新文章

  1. VS2012+EF6+Mysq
  2. redis-4.0.1安装配置(CentOS 6.6)
  3. SpringBoot_异常_01_Caused by: java.lang.BootstrapMethodError: java.lang.NoSuchMethodError
  4. 北大电池新研究登上Nature:3万次循环测试,性能衰减不到30%,大幅提高锂空电池性能...
  5. quartus中pin planner中分配引脚的对话框不见了,怎么找回(附方法)
  6. SQL SERVER 2005 进行XML查询
  7. 介绍Java中的内存泄漏
  8. 基于图像处理的数码印花喷墨墨滴形状规范的研究(Python+OpenCV+Mysql)
  9. LeetCode 623. 在二叉树中增加一行(BFS/DFS)
  10. java提取文章摘要内容
  11. php脚本开头注释_PHP文件注释标记及规范小结
  12. zabbix监控业务进程变动
  13. 让天之痕窗口化运行!
  14. NAS和私有云盘的区别?1篇文章说清楚
  15. 如何给你的谷歌浏览器添加自制插件
  16. java源文件基本布局结构_请调试课本 “第117页”5.4.1节 菜单资源 的代码, 并将程序运行的屏幕截图 和 核心源代码的截图(布局文件,菜单资源文件,Java文件,程序结构图等)提交。...
  17. 下载win10镜像_安装配置win10虚拟机_获取win10产品密钥
  18. BMZCTF Ook
  19. Python绘制六边形
  20. STAR法则修改简历

热门文章

  1. 注册表修改-Smartphone
  2. Redis源码学习(2),t_string.c 学习(一),Set命令实现学习
  3. Android面试500:012如何在不失真的条件下显示一张超高清的图片或者长图?
  4. 文本分类: 零SHOT学习、跨语言迁移学习、零样本学习
  5. tp5结合workerman+gateway实现简单的IM
  6. leaft 动态配置渲染河流
  7. pc端移动端多开软件工具教程
  8. 5+单细胞+脂质代谢+预后模型+实验
  9. 大数据架构师必知必会系列:数据可视化与探索
  10. 目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】机器视觉