|
版本:1.2.0
VERSION =1
PATCHLEVEL =2
SUBLEVEL =0
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h 定义了版本信息的相关变量。
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
export HOSTARCH HOSTOS
# Deal with colliding definitions from tcsh etc.
VENDOR= 使用 uname -s 获得系统类型,后面用 tr 将大写字母([:upper:])转变为小写字母([:lower:]),比如 Linux 转换为 linux 。如果使用的是 cygwin ,那么名字就改为 cygwin 。这里需要提及一下,因为我基本上没用过 cygwin ,不知道在 cygwin 里使用 sed 时括号是不是需要转义后才能识别的,但在 linux 里,括号并不需要转义进行识别。
一段注释:#########################################################################
#
# U-boot build supports producing a object files to the separate external
# directory. Two use cases are supported:
#U-boot 支持在不同的外部目录里存放编译产生的目标文件,有两种方式:
# 1) Add O= to the make command line
# 'make O=/tmp/build all'
# 可以在命令行里使用 O 参数来指定要存放的路径
# 2) Set environement variable BUILD_DIR to point to the desired location
# 'export BUILD_DIR=/tmp/build'
# 'make'
# 还可以在 Makefile 里设置环境变量 BUILD_DIR,使该变量指向要存放的路径
# The second approach can also be used with a MAKEALL script
# 'export BUILD_DIR=/tmp/build'
# './MAKEALL'
#
# Command line 'O=' setting overrides BUILD_DIR environent variable.
#
# When none of the above methods is used the local build is performed and
# the object files are placed in the source directory.
# 如果不用上面两种方法,那么 make 就在源码目录下执行,最后的目标文件也放在源码目录下 下面是对应注释的代码:
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif 如果在命令行中使用 O 选项指定路径,那么就将命令行中给出的路径赋值到 BUILD_DIR 变量中,并且存往 save-output 变量中。
ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [-d ${BUILD_DIR} ] ||mkdir -p ${BUILD_DIR})
# Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) &&/bin/pwd)
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)"does not exist))
endif # ifneq ($(BUILD_DIR),) 接着,若是已经指定了 BUILD_DIR 且当相应的目录不存在时,我们就手动建立它。最后,确认一下这个目录是否建立成功,确认方法是:
先 cd 到该目录,如果成功则用 pwd 获得该目录的路径,并把路径赋给 BUILD_DIR 变量。如果 BUILD_DIR 为空,那么就要用 error 函数停止 make 下去,程序退出。
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE 上面,$(CURDIR) 是 Makefile 内置标准变量,表示当前 make 的路径。一般情况下,我们都很可能不会去指定 BUILD_DIR 路径,所以这里的结果是:$(OBJTREE) ,$(TOPDIR) 和 $(LNDIR) 都是一样的,都表示 u-boot 源码所在的顶层目录路径。
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG mkconfig 是一个脚本,这个脚本用来配置相关的环境信息。这里暂不展开对此脚本的分析。
ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD :=1
export REMOTE_BUILD
endif 从上面分析可知,一般情况下 $(OBJTREE) 等于 $(SRCTREE) ,所以此处的 REMOTE_BUILD 变量在后面也将不会用到。
# $(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 两个变量为空。
ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk))
# load ARCH, BOARD, and CPU configuration
include $(OBJTREE)/include/config.mk
export ARCH CPU BOARD VENDOR SOC 如果执行过诸如 make smdk2410_config 之类的配置命令之后,那么在 include/ 下就会生成 config.mk 文件,这个文件也就是由上面提到的 mkconfig 脚本生成的。比如 smdk2410 对应的 config.mk 文件的内容如下:ARCH = arm
CPU = arm920t
BOARD = smdk2410
SOC = s3c24x0 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
... ... ... ...
export CROSS_COMPILE
根据平台的不同,交叉编译器相应的变量 CROSS_COMPILE 也会不一样。正如 ARM 平台的 gcc 常见的名字为 arm-linux-gcc 。
# load other configuration
include $(TOPDIR)/config.mk 位于源码顶层目录下的 config.mk 是核心的 Makefile 文件,此时将它包含进来。
#########################################################################
# U-Boot objects....order is important (i.e. start must be first)
OBJS = cpu/$(CPU)/start.o
ifeq ($(CPU),i386)
OBJS += cpu/$(CPU)/start16.o
OBJS += cpu/$(CPU)/reset.o
endif
ifeq ($(CPU),ppc4xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc85xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc86xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),bf533)
OBJS += cpu/$(CPU)/start1.o cpu/$(CPU)/interrupt.o cpu/$(CPU)/cache.o
OBJS += cpu/$(CPU)/cplbhdlr.o cpu/$(CPU)/cplbmgr.o cpu/$(CPU)/flush.o
endif
OBJS := $(addprefix $(obj),$(OBJS)) 一般的,OBJS 是由 cpu/$(CPU)/start.s 编译而来的目标文件 start.o。上面,像 i386, ppc4xx 等平台,它们的 OBJS 需要多个 *.o 文件。如果是 ARM 平台,那么只有一个 start.o 。start.s 是 bootloader 初始化 CPU 相关硬件第一个阶段代码文件(stage1)。
LIBS = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
ifdef SOC
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
endif
LIBS += lib_$(ARCH)/lib$(ARCH).a
... ... ... ...
LIBS := $(addprefix $(obj),$(LIBS))
.PHONY : $(LIBS)
LIBS 表示相关的依赖库。 |
|