青梅煮史各种视角下的历史学 2018-04-20
uboot 的版本号分三个级别:
这4个用.分隔开共同构成了最终的版本号。
Makefile 中的版本号最终生成了一个变量UBOOTVERSION,这个变量记录了 Makefile 中配置的版本号。
include/version_autogenerated.h文件是编译过程中自动生成的一个文件,所以源目录中没有,但是编译过后的uboot中就有了。它里面的内容是一个宏定义,宏定义的值内容就是我们在Makefile中配置的uboot的版本号。
24-29行:
VERSION = PATCHLEVEL = SUBLEVEL = EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) VERSION_FILE = $(obj)include/version_autogenerated.h
obj 变量定义在后面, makefile 中若是有等号,则变量取用最后定义的,若是源码目录编译,没指定O的值的话,obj为空,则放在 include 文件夹下
HOSTARCH:主机CPU架构;HOST是主机,就是当前做开发用的CPU或电脑;ARCH是架构,表示CPU的架构。
HOSTOS:主机的操作系统
这两个变量是用 export 导出的环境变量,
uname 是shell 脚本命令 uname -m 命令是得到CPU的类型
uname -s 显示操作系统类型
sed -e:以选项中的指定的 cript 来处理输入的文本文件
tr命令可以对来自标准输入的字符进行替换、压缩和删除。
tr '[:upper:]' '[:lower:]':将大写字符转换为小写字符
31-42行
1 HOSTARCH := $(shell uname -m | \ 2 sed -e s/i.86/i386/ \ 3 -e s/sun4u/sparc64/ \ 4 -e s/arm.*/arm/ \ 5 -e s/sa110/arm/ \ 6 -e s/powerpc/ppc/ \ 7 -e s/macppc/ppc/) 8 9 HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ 10 sed -e 's/\(cygwin\).*/cygwin/') 11 12 export HOSTARCH HOSTOS
VENDOR= #表示开发商
U-boot 的编译过程可以支持向一个自己定义的路径生成最终的目标文件。这里提供两种方法:
命令行'O='设置会覆盖环境变量BUILD_DIR的设置
如果都不采用上面两种方法,那么目标文件放到源码顶层目录,也就是U-BOOT顶层目录
代码 69 到 98行
1 ifdef O 2 ifeq ("$(origin O)", "command line") 3 BUILD_DIR := $(O) 4 endif 5 endif 6 7 ifneq ($(BUILD_DIR),) 8 saved-output := $(BUILD_DIR) 9 10 # Attempt to create a output directory. 11 $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}) 12 13 # Verify if it was successful. 14 BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd) 15 $(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist)) 16 endif # ifneq ($(BUILD_DIR),) 17 18 OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) 19 SRCTREE := $(CURDIR) 20 TOPDIR := $(SRCTREE) 21 LNDIR := $(OBJTREE) 22 export TOPDIR SRCTREE OBJTREE 23 24 MKCONFIG := $(SRCTREE)/mkconfig 25 export MKCONFIG 26 27 ifneq ($(OBJTREE),$(SRCTREE)) 28 REMOTE_BUILD := 1 29 export REMOTE_BUILD 30 endif
100到110行,实现 编译目录和源代码目录不相同的时候执行 obj赋值,如果是在源码目录赋值,则 obj 和 src 都为空
# $(obj) and (src) are defined in config.mk but here in main Makefile # we also need them before config.mk is included which is the case for # some targets like unconfig, clean, clobber, distclean, etc. ifneq ($(OBJTREE),$(SRCTREE)) obj := $(OBJTREE)/ src := $(SRCTREE)/ else obj := src := endif export obj src
执行完毕后,将 obj src 值输出成环境变量,供 u-boot 其他文件中调用
总结:在默认编译下,OBJTREE和SRCTREE相等;在O=xx这种编译下OBJTREE和SRCTREE不相等。Makefile中定义这两个变量,其实就是为了记录编译后的.o文件往哪里放,就是为了实现O=xx的这种编译方式的。
代码在 92 93 行:
MKCONFIG := $(SRCTREE)/mkconfig export MKCONFIG
Makefile中定义的一个变量(在这里定义,在后面使用),它的值就是我们源码根目录下面的mkconfig。这个mkconfig是一个脚本,这个脚本就是uboot配置阶段的配置脚本。
代码在 112 到 161 行:
######################################################################### # 此句判断有没有生成include/config.mk文件,有这个文件则makefile 认为是配置过了 make xxx_defconfig。 ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk)) # load ARCH, BOARD, and CPU configuration,包含 include/config.mk 文件 include $(OBJTREE)/include/config.mk export ARCH CPU BOARD VENDOR SOC ifndef CROSS_COMPILE ifeq ($(HOSTARCH),ppc) CROSS_COMPILE = else ifeq ($(ARCH),ppc) CROSS_COMPILE = powerpc-linux- endif ifeq ($(ARCH),arm) CROSS_COMPILE = arm-linux- endif ifeq ($(ARCH),i386) ifeq ($(HOSTARCH),i386) CROSS_COMPILE = else CROSS_COMPILE = i386-linux- endif endif ifeq ($(ARCH),mips) CROSS_COMPILE = mips_4KC- endif ifeq ($(ARCH),nios) CROSS_COMPILE = nios-elf- endif ifeq ($(ARCH),nios2) CROSS_COMPILE = nios2-elf- endif ifeq ($(ARCH),m68k) CROSS_COMPILE = m68k-elf- endif ifeq ($(ARCH),microblaze) CROSS_COMPILE = mb- endif ifeq ($(ARCH),blackfin) CROSS_COMPILE = bfin-elf- endif ifeq ($(ARCH),avr32) CROSS_COMPILE = avr32- endif endif endif export CROSS_COMPILE