如下:
VERSION = 2012
PATCHLEVEL = 04
SUBLEVEL = 01
EXTRAVERSION =
ifneq “$(SUBLEVEL)” “”
U_BOOT_VERSION =
$ (VERSION).$ (PATCHLEVEL).$ (SUBLEVEL)$(EXTRAVERSION)
else
U_BOOT_VERSION =
$ (VERSION).$ (PATCHLEVEL)$(EXTRAVERSION)
endif
TIMESTAMP_FILE =
$(obj)include/generated/timestamp_autogenerated.h
VERSION_FILE =
$(obj)include/generated/version_autogenerated.h
变量名 | 含义 |
---|---|
U_BOOT_VERSION | 2012.04.01 |
TIMESTAMP_FILE | include/generated/timestamp_autogenerated.h |
VERSION_FILE | include/generated/version_autogenerated.h |
HOSTARCH := $(shell uname -m | \
sed
-e s/i.86/x86/ \
-e s/sun4u/sparc64/ \
-e s/arm.*/arm/ \
-e s/sa110/arm/ \
-e s/ppc64/powerpc/ \
-e s/ppc/powerpc/ \
-e s/macppc/powerpc/\
-e s/sh.*/sh/)
HOSTOS := $(shell uname -s | tr '[:upper:]'
'[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
“sed
–e”表示后面跟的是一串命令脚本,而表达式“s/abc/def/”表示要从标准输入中,查找到内容为“abc”的,然后替换成“def”。其中“abc”表达式用可以使用“.”作为通配符。
命令“uname –m”将输出主机CPU的体系架构类型。作者的电脑使用Intel Core2系列的CPU,因此“uname –m”输出“i686”。 “i686”可以匹配命令“sed -e
s/i.86/x86/”中的“i.86”,因此在作者的机器上执行Makefile,HOSTARCH将被设置成“x86” 。
“uname
–s”输出主机内核名字,作者使用Linux发行版Ubuntu10.04,因此“uname –s”结果是“Linux”。“tr
'[:upper:]' '[:lower:]'”作用是将标准输入中的所有大写字母转换为响应的小写字母。因此执行结果是将HOSTOS 设置为“linux”。
# Set shell to bash if possible, otherwise
fall back to sh
SHELL := $(shell if [ -x "$$BASH"
]; then echo $$BASH; \
else
if [ -x /bin/bash ]; then echo /bin/bash; \
else
echo sh; fi; fi)
export HOSTARCH
HOSTOS SHELL
# Deal with colliding definitions from tcsh
etc.
VENDOR=
#########################################################################
# Allow for silent builds
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
#因为没有定义MAKEFLAGS,所以XECHO=echo
#########################################################################
#
# U-boot build supports producing a object
files to the separate external
# directory. Two use cases are supported:
#
# 1) Add O= to the make command line
# 'make O=/tmp/build all'
#
# 2) Set environement variable BUILD_DIR to
point to the desired location
# 'export BUILD_DIR=/tmp/build'
# 'make'
#
# 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.
#
ifdef O
ifeq ("$(origin O)",
"command line")
BUILD_DIR := $(O)
endif
endif
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),)
OBJTREE :=
$(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SPLTREE :=
$(OBJTREE)/spl
SRCTREE :=
$(CURDIR)
TOPDIR :=
$(SRCTREE)
LNDIR :=
$(OBJTREE)
export TOPDIR
SRCTREE OBJTREE SPLTREE
MKCONFIG :=
$(SRCTREE)/mkconfig
export MKCONFIG
ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD := 1
export REMOTE_BUILD
endif
# $(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
CURDIR变量指示Make当前的工作目录,由于当前Make在U-Boot顶层目录执行Makefile,因此CURDIR此时就是U-Boot顶层目录。
执行完上面的代码后, SRCTREE,src变量就是U-Boot代码顶层目录,而OBJTREE,obj变量就是输出目录,若没有定义BUILD_DIR环境变量,则SRCTREE,src变量与OBJTREE,obj变量都是U-Boot源代码目录。而MKCONFIG则表示U-Boot根目录下的mkconfig脚本。
变量 | 含义 |
---|---|
OBJTREE | Omapl138/uboot |
SPLTREE | Omapl138/uboot/spl |
SRCTREE | Omapl138/uboot |
TOPDIR | Omapl138/uboot |
LNDDIR | Omapl138/uboot |
src | Omapl138/uboot |
obj | Omapl138/uboot |
MKCONFIG | Omapl138/uboot/mkconfig |
# Make sure CDPATH settings don't interfere
unexport
CDPATH
#########################################################################
# The "tools" are needed early,
so put this first
# Don't include stuff already done in
$(LIBS)
# The "examples" conditionally
depend on U-Boot (say, when USE_PRIVATE_LIBGCC
# is "yes"), so compile examples
after U-Boot is compiled.
SUBDIR_TOOLS = tools
SUBDIR_EXAMPLES = examples/standalone
examples/api
SUBDIRS = $(SUBDIR_TOOLS)
.PHONY : $(SUBDIRS) $(VERSION_FILE)
$(TIMESTAMP_FILE)
ifeq ($(obj)include/config.mk,$(wildcard
$(obj)include/config.mk))
# Include autoconf.mk before config.mk so
that the config options are available
# to all top level build files. We need the dummy all: target to prevent the
# dependency target in autoconf.mk.dep from
being the default.
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk
当makefile中有两个相同目标的时候,会执行后一个目标。因为后一个目标会重载前一个。如果你 执行make的时候没有带任何其他目标。单独的一个make。可以避免以autoconf.mk.dep里面的include/autoconf.mk作为错误目标。如果你执行make的时候带了目标。这个all:有不有都无所谓。
ifndef CONFIG_SANDBOX
SUBDIRS += $(SUBDIR_EXAMPLES)
endif
# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export ARCH
CPU BOARD VENDOR SOC
#包含include/config.mk文件,这个文件是在makexxx_config过程中产生的
# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif
#HOSTARCH是x86的,目标是arm的,所以不执行
这个CROSS_COMPILE是通过命令行引入的,make CROSS_COMPILE=arm-none-linux-gnueabi-
# load other configuration
include $(TOPDIR)/config.mk
#包含Omapl138/uboot/mkconfig
# If board code explicitly specified
LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
# that (or fail if absent). Otherwise, search for a linker script in a
# standard location.
LDSCRIPT_MAKEFILE_DIR = $(dir $(LDSCRIPT))
#用等号赋值的变量是递归方式扩展的变量。变量定义时,变量值中对其他变量的引用不会被替换展开;
#而是变量在引用它的地方替换展开的同时,它所引用的其它变量才会被一同替换展开。
#其优点是:
#这种类型变量在定义时,可以引用其它的之前没有定义的变量(可能在后续部分定义,或者是通过make的命令行选项传递的变量)。
#LDSCRIPT变量就是后面才定义的
ifndef LDSCRIPT
#LDSCRIPT
:= $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
ifdef
CONFIG_SYS_LDSCRIPT
#没有定义
#
need to strip off double quotes
LDSCRIPT
:= $(subst ",,$(CONFIG_SYS_LDSCRIPT))
#如果定义了CONFIG_SYS_LDSCRIPT,将CONFIG_SYS_LDSCRIPT代表的字符串去掉双引号后赋值给LDSCRIPT变量
endif
endif
# If there is no specified link script, we
look in a number of places for it
ifndef LDSCRIPT
ifeq
($(CONFIG_NAND_U_BOOT),y)
LDSCRIPT
:= $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
ifeq
($(wildcard $(LDSCRIPT)),)
LDSCRIPT
:= $(TOPDIR)/$(CPUDIR)/u-boot-nand.lds
endif
endif
ifeq
($(wildcard $(LDSCRIPT)),)
LDSCRIPT
:= $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
endif
ifeq
($(wildcard $(LDSCRIPT)),)
LDSCRIPT
:= $(TOPDIR)/$(CPUDIR)/u-boot.lds
endif
ifeq
($(wildcard $(LDSCRIPT)),)
LDSCRIPT
:= $(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds
#
We don't expect a Makefile here
LDSCRIPT_MAKEFILE_DIR
=
endif
ifeq
($(wildcard $(LDSCRIPT)),)
$(error could not find linker script)
endif
endif
在config.mk中有如下定义:
BOARDDIR =$ (VENDDOR)/$( BOARD)
CPUDIR=arch/$ (ARCH)/cpu/$(CPU)
ifneq
($ (SRCTREE)/$ (CPUDIR),$ (wildcard $ (SRCTREE)/$ (CPUDIR)))
CPUDIR= arch/$(ARCH)/cpu
结合boards.cfg中的定义:
变量名 | 定义 |
---|---|
ARCH | arm |
CPU | arm926ejs |
BOARD name | da8xxevm |
Vendor | davinci |
SOC | davinci |
综上:
BOARDDIR=davinci/da8xxevm/
CPUDIF=arch/arm/cpu/arm926ejs
#注释写的很明确,如果没有用CONFIG_SYS_LDSCRIPT指定LDSCRIPT,那么就在几个地方搜
#第一个地方:如果CONFIG_NAND_U_BOOT是y,就用u-boot-nand.lds但是这里没有这个定义
#第一个地方没找到,就找第二个地方:uboot/board/davinci /da8xxevm这个目录没有u-boot.lds文件
#第二个地方没找到,就找第三个地方:其中CPUDIR是在顶层的config.mk中定义的,在arch/arm/cpu/arm926ejs中找这个目录也没有
#第三个地方没找到,就找第四个地方:arch/arm/cpu/u-boot.lds,这里就找到了!!!!
#########################################################################
# U-Boot objects....order is important
(i.e. start must be first)
OBJS
= $(CPUDIR)/start.o
OBJS =arch/arm/cpu/arm926ejs/start.o
ifeq ($(CPU),x86)
OBJS += $(CPUDIR)/start16.o
OBJS += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),ppc4xx)
OBJS += $(CPUDIR)/resetvec.o
endif
ifeq ($(CPU),mpc85xx)
OBJS += $(CPUDIR)/resetvec.o
endif
均不满足
OBJS := $(addprefix $(obj),$(OBJS))
OBJS:=arch/arm/cpu/arm926ejs/start.o
LIBS
= lib/libgeneric.o
LIBS += lib/lzma/liblzma.o
LIBS += lib/lzo/liblzo.o
LIBS += lib/zlib/libz.o
LIBS += $(shell if [ -f
board/$(VENDOR)/common/Makefile ]; then echo \
"board/$(VENDOR)/common/lib$(VENDOR).o";
fi)
#-f表示该文件为常规文件,经查该文件不存在
LIBS += $(CPUDIR)/lib$(CPU).o
LIBS+= arch/arm/cpu/arm926ejs/libarm926ejs.o
ifdef SOC
LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).o
LIBS+=
arch/arm/cpu/arm926ejs/davinci/libdavinci.o
endif
ifeq ($(CPU),ixp)
LIBS += arch/arm/cpu/ixp/npe/libnpe.o
endif
ifeq ($(CONFIG_OF_EMBED),y)
LIBS += dts/libdts.o
endif
LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
LIBS+= arch/arm/libarm.o
LIBS += fs/cramfs/libcramfs.o
fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
fs/reiserfs/libreiserfs.o
fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
fs/ubifs/libubifs.o
LIBS += net/libnet.o
LIBS += disk/libdisk.o
LIBS +=
drivers/bios_emulator/libatibiosemu.o
LIBS += drivers/block/libblock.o
LIBS += drivers/dma/libdma.o
LIBS += drivers/fpga/libfpga.o
LIBS += drivers/gpio/libgpio.o
LIBS += drivers/hwmon/libhwmon.o
LIBS += drivers/i2c/libi2c.o
LIBS += drivers/input/libinput.o
LIBS += drivers/misc/libmisc.o
LIBS += drivers/mmc/libmmc.o
LIBS += drivers/mtd/libmtd.o
LIBS += drivers/mtd/nand/libnand.o
LIBS += drivers/mtd/onenand/libonenand.o
LIBS += drivers/mtd/ubi/libubi.o
LIBS += drivers/mtd/spi/libspi_flash.o
LIBS += drivers/net/libnet.o
LIBS += drivers/net/phy/libphy.o
LIBS += drivers/pci/libpci.o
LIBS += drivers/pcmcia/libpcmcia.o
LIBS += drivers/power/libpower.o
LIBS += drivers/spi/libspi.o
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/libqe.o
LIBS +=
arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
ifeq ($(CPU),mpc85xx)
LIBS += drivers/qe/libqe.o
LIBS += drivers/net/fm/libfm.o
LIBS +=
arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
ifeq ($(CPU),mpc86xx)
LIBS +=
arch/powerpc/cpu/mpc8xxx/ddr/libddr.o
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o
endif
LIBS += drivers/rtc/librtc.o
LIBS += drivers/serial/libserial.o
ifeq ($(CONFIG_GENERIC_LPC_TPM),y)
LIBS += drivers/tpm/libtpm.o
endif
LIBS += drivers/twserial/libtws.o
LIBS += drivers/usb/eth/libusb_eth.o
LIBS += drivers/usb/gadget/libusb_gadget.o
LIBS += drivers/usb/host/libusb_host.o
LIBS += drivers/usb/musb/libusb_musb.o
LIBS += drivers/usb/phy/libusb_phy.o
LIBS += drivers/usb/ulpi/libusb_ulpi.o
LIBS += drivers/video/libvideo.o
LIBS += drivers/watchdog/libwatchdog.o
LIBS += common/libcommon.o
LIBS += lib/libfdt/libfdt.o
LIBS += api/libapi.o
LIBS += post/libpost.o
ifneq
($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
LIBS +=
$(CPUDIR)/omap-common/libomap-common.o
endif
ifeq ($(SOC),mx5)
LIBS +=
$(CPUDIR)/imx-common/libimx-common.o
endif
ifeq ($(SOC),mx6)
LIBS +=
$(CPUDIR)/imx-common/libimx-common.o
endif
ifeq ($(SOC),s5pc1xx)
LIBS +=
$(CPUDIR)/s5p-common/libs5p-common.o
endif
ifeq ($(SOC),exynos)
LIBS +=
$(CPUDIR)/s5p-common/libs5p-common.o
endif
LIBS := $(addprefix $(obj),$(sort $(LIBS)))
.PHONY : $(LIBS)
LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
#为LIBBOARD增加前缀,board/davinci/da8xxevm/libda8xxevm.o
# Add GCC lib
ifdef USE_PRIVATE_LIBGCC
ifeq ("$(USE_PRIVATE_LIBGCC)",
"yes")
PLATFORM_LIBGCC = $(OBJTREE)/arch/$(ARCH)/lib/libgcc.o
else
PLATFORM_LIBGCC = -L $(USE_PRIVATE_LIBGCC)
-lgcc
endif
else
PLATFORM_LIBGCC := -L $(shell dirname
`$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
#dirname 命令读取指定路径名删除最后一个“/”(斜杠)及其后面的字符,保留其他部分,并写结果到标准输出。如果最后一个“/”后无字符,dirname
命令使用倒数第二个“/”,并忽略其后的所有字符。
CFLGS:=$(CPPFLAGS) -Wall
-Wstrict-prototypes
1)USE_PRIVATE_LIBGCC = yes,从 /arch/arm/lib 中获得 libgcc.a
2)USE_PRIVATE_LIBGCC = path+file,从 指定的路径获得 libgcc.a
3)如果没有配置USE_PRIVATE_LIBGCC,就从工具链 libgcc路径获得。
我们这里没有定义用户私有GCC库,所以执行ifdef的else分支
PLATFORM_LIBGCC
= -L $ (shell dirname $(CC) $(CFLAGS) -print-libgcc-file-name
) -lgcc
CC和CFLAGS都是make的隐含变量,CC表示C语言编译器,缺省为:‘cc’。cflags表示执行CC时的命令行参数
但是在这里并不是使用“cc”这个编译器,在顶层的config.mk文件中我们可以找到关于$ (CC)和$(CFLAGS)的定义,如下:
dirname
$(CC) $(CFLAGS) -print-libgcc-file-name
取得交叉编译器的libgcc.a的绝对路径
CC =
$(CROSS_COMPILE)gcc // CROSS_COMPILE = arm-none-linux-gnueabi-
//所以这里:CC = arm-none-linux-gnueabi-gcc
# 没有定义BUILD_TAG,执行else分支,赋值CFLAGS
ifdef BUILD_TAG
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes \
-DBUILD_TAG='"$(BUILD_TAG)"'
else
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
endif
##########################################################
# 利用call函数,使得$1=cc-option ,$2=-fno-stack-protector
# CFLAGS_SSP= $1$2 = -fno-stack-protector,然后把CFLAGS_SSP
# 追加给CFLAGS
CFLAGS_SSP := $(call cc-option,-fno-stack-protector)
# ARFLAGS = $(error update your Makefile to use cmd_link_o_target and not AR)
# RELFLAGS=$(PLATFORM_RELFLAGS)=-fno-common -ffixed-r8 -msoft-float
# DBGFLAGS = -g
# OPTFLAGS = -Os
# OBJCFLAGS = --gap-fill=0xff
# gccincdir = $(shell $(CC) -print-file-name=include)=交叉工具链include目录在宿# 主机中的位置CPPFLAGS = -g -Os -fno-common -ffixed-r8 -msoft-float -D__KERNEL__
ARFLAGS = $(error update your Makefile to use cmd_link_o_target and not AR)
RELFLAGS= $(PLATFORM_RELFLAGS)
DBGFLAGS= -g # -DDEBUG
OPTFLAGS= -Os # -fomit-frame-pointer
OBJCFLAGS += --gap-fill=0xff
gccincdir := $(shell $(CC) -print-file-name=include)
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
-D__KERNEL__
# Enable garbage collection of un-used sections for SPL
ifeq ($(CONFIG_SPL_BUILD),y)
CPPFLAGS += -ffunction-sections -fdata-sections
LDFLAGS_FINAL += --gc-sections
endif
-L
表示:编译程序按照-L指定的路进去寻找库文件,一般的在-L的后面可以一次用-l指定多个库文件。
-lgcc 代表链接器将连接GCC的支持库libgcc.a
endif
PLATFORM_LIBS += $(PLATFORM_LIBGCC)
export PLATFORM_LIBS
# Special flags for CPP when processing the
linker script.
# Pass the version down so we can handle
backwards compatibility
# on the fly.
LDPPFLAGS += \
-include
$(TOPDIR)/include/u-boot/u-boot.lds.h \
-DCPUDIR=$(CPUDIR)
\
$(shell
$(LD) --version | \
sed -ne 's/GNU ld version
\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
__OBJS := $(subst $(obj),,$(OBJS))
__LIBS := $(subst $(obj),,$(LIBS)) $(subst
$(obj),,$(LIBBOARD))
#########################################################################
#########################################################################
ifneq ($(CONFIG_BOARD_SIZE_LIMIT),)
BOARD_SIZE_CHECK = \
@actual=`wc
-c $@ | awk '{print $$1}'`; \
limit=$(CONFIG_BOARD_SIZE_LIMIT);
\
if
test $$actual -gt $$limit; then \
echo
"$@ exceeds file size limit:"; \
echo
" limit: $$limit bytes"; \
echo
" actual: $$actual bytes"; \
echo
" excess: $$((actual - limit))
bytes"; \
exit
1; \
fi
else
BOARD_SIZE_CHECK =
endif
# Always append ALL so that arch
config.mk's can add custom ones
ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin
$(obj)System.map
ALL-$(CONFIG_NAND_U_BOOT) +=
$(obj)u-boot-nand.bin
ALL-$(CONFIG_ONENAND_U_BOOT) +=
$(obj)u-boot-onenand.bin
ONENAND_BIN ?=
$(obj)onenand_ipl/onenand-ipl-2k.bin
ALL-$(CONFIG_SPL) +=
$(obj)spl/u-boot-spl.bin
ALL-$(CONFIG_OF_SEPARATE) +=
$(obj)u-boot.dtb $(obj)u-boot-dtb.bin
all: $(ALL-y)
$(SUBDIR_EXAMPLES)
$(obj)u-boot.dtb: $(obj)u-boot
$(MAKE)
-C dts binary
mv
$(obj)dts/dt.dtb $@
$(obj)u-boot-dtb.bin: $(obj)u-boot.bin $(obj)u-boot.dtb
cat
$^ >$@
$(obj)u-boot.hex: $(obj)u-boot
$(OBJCOPY)
${OBJCFLAGS} -O ihex $< $@
$(obj)u-boot.srec: $(obj)u-boot
$(OBJCOPY)
-O srec $< $@
$(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY)
${OBJCFLAGS} -O binary $< $@
$(BOARD_SIZE_CHECK)
$(obj)u-boot.ldr: $(obj)u-boot
$(CREATE_LDR_ENV)
$(LDR)
-T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
$(BOARD_SIZE_CHECK)
$(obj)u-boot.ldr.hex: $(obj)u-boot.ldr
$(OBJCOPY)
${OBJCFLAGS} -O ihex $< $@ -I binary
$(obj)u-boot.ldr.srec: $(obj)u-boot.ldr
$(OBJCOPY)
${OBJCFLAGS} -O srec $< $@ -I binary
$(obj)u-boot.img: $(obj)u-boot.bin
$(obj)tools/mkimage
-A $(ARCH) -T firmware -C none \
-O
u-boot -a $(CONFIG_SYS_TEXT_BASE) -e 0 \
-n
$(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
sed
-e 's/"[ ]*$$/ for $(BOARD)
board"/') \
-d
$< $@
$(obj)u-boot.imx: $(obj)u-boot.bin
$(obj)tools/mkimage
-n $(CONFIG_IMX_CONFIG) -T imximage \
-e
$(CONFIG_SYS_TEXT_BASE) -d $< $@
$(obj)u-boot.kwb: $(obj)u-boot.bin
$(obj)tools/mkimage
-n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \
-a
$(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -d $< $@
$(obj)u-boot.sha1: $(obj)u-boot.bin
$(obj)tools/ubsha1
$(obj)u-boot.bin
$(obj)u-boot.dis: $(obj)u-boot
$(OBJDUMP)
-d $< > $@
$(obj)u-boot.ubl: $(obj)spl/u-boot-spl.bin
$(obj)u-boot.bin
$(OBJCOPY)
${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $(obj)spl/u-boot-spl
$(obj)spl/u-boot-spl-pad.bin
cat
$(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $(obj)u-boot-ubl.bin
$(obj)tools/mkimage
-n $(UBL_CONFIG) -T ublimage \
-e
$(CONFIG_SYS_TEXT_BASE) -d $(obj)u-boot-ubl.bin $(obj)u-boot.ubl
rm
$(obj)u-boot-ubl.bin
rm
$(obj)spl/u-boot-spl-pad.bin
$(obj)u-boot.ais: $(obj)spl/u-boot-spl.bin
$(obj)u-boot.bin
$(obj)tools/mkimage -s -n
/dev/null -T aisimage \
-e $(CONFIG_SPL_TEXT_BASE)
\
-d $(obj)spl/u-boot-spl.bin
\
$(obj)spl/u-boot-spl.ais
$(OBJCOPY) ${OBJCFLAGS} -I binary
\
--pad-to=$(CONFIG_SPL_MAX_SIZE)
-O binary \
$(obj)spl/u-boot-spl.ais
$(obj)spl/u-boot-spl-pad.ais
cat $(obj)spl/u-boot-spl-pad.ais
$(obj)u-boot.bin > \
$(obj)u-boot.ais
u-boot.ais的编译依赖u-boot-spl.bin,u-boot.bin等文件
$(obj)u-boot.sb: $(obj)u-boot.bin
$(obj)spl/u-boot-spl.bin
elftosb
-zdf imx28 -c $(TOPDIR)/board/$(BOARDDIR)/u-boot.bd \
-o
$(obj)u-boot.sb
ifeq ($(CONFIG_SANDBOX),y)
GEN_UBOOT = \
cd
$(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
-Wl,--start-group
$(__LIBS) -Wl,--end-group \
$(PLATFORM_LIBS)
-Wl,-Map -Wl,u-boot.map -o u-boot
else
GEN_UBOOT = \
UNDEF_SYM=`$(OBJDUMP)
-x $(LIBBOARD) $(LIBS) | \
sed -n -e
's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd
$(LNDIR) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $$UNDEF_SYM $(__OBJS) \
--start-group
$(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map
u-boot.map -o u-boot
endif
$(obj)u-boot: depend \
$(SUBDIR_TOOLS)
$(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
$(GEN_UBOOT)
u-boot.ais的编译依赖u-boot-spl.bin,u-boot.bin等文件
$(obj)u-boot.sb: $(obj)u-boot.bin
$(obj)spl/u-boot-spl.bin
elftosb
-zdf imx28 -c $(TOPDIR)/board/$(BOARDDIR)/u-boot.bd \
-o
$(obj)u-boot.sb
ifeq ($(CONFIG_SANDBOX),y)
GEN_UBOOT = \
cd
$(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
-Wl,--start-group
$(__LIBS) -Wl,--end-group \
$(PLATFORM_LIBS)
-Wl,-Map -Wl,u-boot.map -o u-boot
else
GEN_UBOOT = \
UNDEF_SYM=`$(OBJDUMP)
-x $(LIBBOARD) $(LIBS) | \
sed -n -e
's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd
$(LNDIR) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $$UNDEF_SYM $(__OBJS) \
--start-group
$(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map
u-boot.map -o u-boot
endif
$(obj)u-boot: depend \
$(SUBDIR_TOOLS)
$(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
$(GEN_UBOOT)
#all依赖于$(ALL) 最终生成镜像文件,注意各种依赖关系。
重点分析一下“u-boot.bin”, u-boot.bin的依赖关系是这样的:$(obj)u-boot.bin - > $(obj)u-boot - >
depend
$(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
先来看看GEN_UBOOT变量的具体内容:
(1) $(OBJDUMP)
在顶层目录的config.mk($(TOPDIR)/config.mk )文件中我们可以找到该变量的定义:
OBJDUMP =
$(CROSS_COMPILE)objdump
命令行中定义了 CROSS_COMPILE=arm-none-linux-gnueabi-,所以
OBJDUMP =arm- none-linux-gnueabi
-objdump
(2) $(LIBBOARD)
LIBBOARD在Makefile中有定义。如下:
LIBBOARD =
board/
(
B
O
A
R
D
D
I
R
)
/
l
i
b
(BOARDDIR)/lib
(BOARDDIR)/lib(BOARD).o
LIBBOARD :=
$(addprefix
(
o
b
j
)
,
(obj),
(obj),(LIBBOARD))
展开后得到的结果是:
LIBBOARD =
$(obj)board/davinci/da8xxevm/libda8xxevm.o
(3)$(LIBS)
这个变量是添加库了(在Makefile中定义的),内容比较多,如下:
LIBS =
lib_generic/libgeneric.a
LIBS +=
lib_generic/lzma/liblzma.a
LIBS +=
lib_generic/lzo/liblzo.a
LIBS += ( s h e l l i f [ − f b o a r d / (shell if [ -f board/ (shellif[−fboard/(VENDOR)/common/Makefile ]; then echo \
“board/
(
V
E
N
D
O
R
)
/
c
o
m
m
o
n
/
l
i
b
(VENDOR)/common/lib
(VENDOR)/common/lib(VENDOR).a”;
fi)
LIBS +=
cpu/
(
C
P
U
)
/
l
i
b
(CPU)/lib
(CPU)/lib(CPU).a
ifdef SOC
LIBS +=
cpu/
(
C
P
U
)
/
(CPU)/
(CPU)/(SOC)/lib$(SOC).a
endif
ifeq ($(CPU),ixp)
LIBS +=
cpu/ixp/npe/libnpe.a
endif
LIBS +=
lib_
(
A
R
C
H
)
/
l
i
b
(ARCH)/lib
(ARCH)/lib(ARCH).a
LIBS +=
fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
fs/reiserfs/libreiserfs.a
fs/ext2/libext2fs.a fs/yaffs2/libyaffs2.a \
fs/ubifs/libubifs.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS +=
drivers/bios_emulator/libatibiosemu.a
LIBS +=
drivers/block/libblock.a
LIBS +=
drivers/dma/libdma.a
LIBS +=
drivers/fpga/libfpga.a
LIBS +=
drivers/gpio/libgpio.a
LIBS +=
drivers/hwmon/libhwmon.a
LIBS +=
drivers/i2c/libi2c.a
LIBS +=
drivers/input/libinput.a
LIBS +=
drivers/misc/libmisc.a
LIBS +=
drivers/mmc/libmmc.a
LIBS +=
drivers/mtd/libmtd.a
LIBS +=
drivers/mtd/nand/libnand.a
LIBS +=
drivers/mtd/onenand/libonenand.a
LIBS +=
drivers/mtd/ubi/libubi.a
LIBS +=
drivers/mtd/spi/libspi_flash.a
LIBS +=
drivers/net/libnet.a
LIBS +=
drivers/net/phy/libphy.a
LIBS +=
drivers/pci/libpci.a
LIBS +=
drivers/pcmcia/libpcmcia.a
LIBS +=
drivers/power/libpower.a
LIBS +=
drivers/spi/libspi.a
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/qe.a
endif
ifeq ($(CPU),mpc85xx)
LIBS += drivers/qe/qe.a
LIBS += cpu/mpc8xxx/ddr/libddr.a
LIBS +=
cpu/mpc8xxx/lib8xxx.a
endif
ifeq ($(CPU),mpc86xx)
LIBS +=
cpu/mpc8xxx/ddr/libddr.a
LIBS +=
cpu/mpc8xxx/lib8xxx.a
endif
LIBS +=
drivers/rtc/librtc.a
LIBS +=
drivers/serial/libserial.a
LIBS +=
drivers/twserial/libtws.a
LIBS += drivers/usb/gadget/libusb_gadget.a
LIBS +=
drivers/usb/host/libusb_host.a
LIBS +=
drivers/usb/musb/libusb_musb.a
LBS +=
drivers/usb/phy/libusb_phy.a
LIBS +=
drivers/video/libvideo.a
LIBS += drivers/watchdog/libwatchdog.a
LIBS +=
common/libcommon.a
LIBS += libfdt/libfdt.a
LIBS += api/libapi.a
LIBS += post/libpost.a
从这些添加进来的这些库的文件名,大概可以知道这些库的用途了,包含了cup的配置、drivers驱动程序、api等,这里就不列出了。
(3)$(SYM_PREFIX)
没有定义这个变量,
(4) $(LNDIR)
LNDIR := $(OBJTREE) ,前面分析知道 OBJTREE就是顶层目录了。
(5) $(LD)
在config.mk中有定义
LD =
$(CROSS_COMPILE)ld
结果为: LD = arm-none-linux-gnueabi-ld
咱们可以用type命令查看一下“ arm-linux-ld”命令在哪里:
(6)$(LDFLAGS)、$(LDFLAGS_$(@F))
在config.mk中有定义 :
LDFLAGS
+=$(PLATFORM_LDFLAGS)
LDFLAGS_FINAL += -Bstatic
# 设置U-boot的链接选项
LDFLAGS_u-boot += -T $(obj)u-boot.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SYS_TEXT_BASE),)
LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
endif
# 设置U-boot的链接选项,当uboot是采用spl时的情况
LDFLAGS_u-boot-spl += -T $(obj)u-boot-spl.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SPL_TEXT_BASE),)
LDFLAGS_u-boot-spl += -Ttext $(CONFIG_SPL_TEXT_BASE)
endif
(7) $(__OBJS)和 $(__LIBS)
在config.mk中有定义 :
__OBJS :=
$(subst $(obj),,$(OBJS))
__LIBS :=
$(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
subst函数的使用规则:
$(subst from,to,text)
在文本‘text’中使用‘to’替换每一处‘from’。
结果就是:将变量OBJS内容里的$(obj)替换成空,然后赋给 __OBJS
(8)$(PLATFORM_LIBS)
PLATFORM_LIBS在Makefile中定义为:
PLATFORM_LIBS += $(PLATFORM_LIBGCC)
ifeq ($(CONFIG_KALLSYMS),y)
smap=`$(call
SYSTEM_MAP,u-boot) | \
awk
'$$2 ~ /[tTwW]/ {printf $$1 $$3 "\\\\000"}'` ; \
$(CC)
$(CFLAGS) -DSYSTEM_MAP="\"$${smap}\"" \
-c
common/system_map.c -o $(obj)common/system_map.o
$(GEN_UBOOT)
$(obj)common/system_map.o
endif
$(OBJS): depend
$(MAKE)
-C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
$(LIBS): depend
$(SUBDIR_TOOLS)
$(MAKE)
-C $(dir $(subst $(obj),,$@))
$(LIBBOARD): depend $(LIBS)
$(MAKE)
-C $(dir $(subst $(obj),,$@))
$(SUBDIRS): depend
$(MAKE)
-C $@ all
$(SUBDIR_EXAMPLES): $(obj)u-boot
$(LDSCRIPT): depend
$(MAKE)
-C $(dir $@) $(notdir $@)
$(obj)u-boot.lds: $(LDSCRIPT)
$(CPP)
$(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@
#CPP=$(CC)
-E=$(CORSS_COMPILE)gcc -E=arm-none-linux-gnueabi-gcc -E
# LDPPFLAGS += \
-include $(TOPDIR)/include/u-boot/u-boot.lds.h \具体的位置是/include/u-boot/u-boot.lds.h
-DCPUDIR=$(CPUDIR) \
$(shell $(LD) --version | \
sed -ne 's/GNU ld
version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
默认变量“ CPP” :C
程序的预处理器(输出是标准输出设备)。默认命令是“$(CC) –E”。
-Dmacro:定义宏macro,宏的内容定义为字符串`1'. 这里
-D__ASSEMBLY__ 相当于 #define __ASSEMBLY__ ‘1’
。-D 是选项,__ASSEMBLY__ 相当于一个宏。