uboot主Makefile分析

1. VERSION(24 ~ 29行)

VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 4
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h

VERSION:主版本号

PATCHLEVEL:次版本号

SUBLEVEL:修正版本号

EXTRAVERSION:扩展版本号

U_BOOT_VERSION:uboot的版本号

include/version_autogenerated.h文件是编译过程中自动生成的一个文件,因此源目录中没有,只有编译后才有。内容如下:

#define U_BOOT_VERSION "U-Boot 1.3.4"

2. HOSTARCH、HOSTOS(31 ~ 43行)

HOSTARCH := $(shell uname -m | \
	sed -e s/i.86/i386/ \
	    -e s/sun4u/sparc64/ \
	    -e s/arm.*/arm/ \
	    -e s/sa110/arm/ \
	    -e s/powerpc/ppc/ \
	    -e s/ppc64/ppc/ \
	    -e s/macppc/ppc/)

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
	    sed -e 's/\(cygwin\).*/cygwin/')

export	HOSTARCH HOSTOS

HOSTARCH:主机架构,主机的CPU架构是x86_64。首先执行uname -r得到i686,通过管道传送给sed命令,然后sed命令将执行sed -e s/i*86/i386将i686替换成i386,最后的结果是HOSTARCH=i386

HOSTOS:主机操作系统,主机操作是Linux。首先执行uname -s查看平台的系统,结果为Linux,然后通过管道传送给tr命令,tr命令利用字符类[:upper:]和[:lower:]将Linux字符串转换为linux,然后再利用sed命令,最后的结果是linux。

最后一句是导出HOSTARCH、HOSTOS。 

3. 静默编译(50 ~ 54行)

ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif

默认编译时命令行会打印很多编译信息,但是有时候不希望看到这些编译信息,后台编译即可,这就是静默编译。

使用方法:make -s(在make时加上-s标志)

4. 编译方法选择:原地编译 or 单独输出编译(56 ~ 123行)

#########################################################################
#
# 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))
SRCTREE		:= $(CURDIR)
TOPDIR		:= $(SRCTREE)
LNDIR		:= $(OBJTREE)
export	TOPDIR SRCTREE OBJTREE

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

# Make sure CDPATH settings don't interfere
unexport CDPATH

(1)编译复杂项目,Makefile提供了两种编译方式:原地编译和单独输出编译。

原地编译就是生成.o文件和.c文件放在同一目录下。这种编译的方式好处是处理简单,但是它也有坏处:第一,污染源文件目录;第二,一套源代码只能按照一种配置和编译方法进行处理,无法同时维护2个或2个以上的配置编译方式。

为了解决以上缺陷,Makefile还提供了单独输出编译,它的实现思路是在编译时指定一个输出目录,然后将所有编译生成的.o文件或其他文件都放到这个输出目录中。

使用方法:默认使用的是原地编译,使用单独输出编译需要指定输出目录,如下:

第1种方式:make O=输出目录

第2种方式:export BUILD_DIR=输出目录; make

第3种方式:两个都指定,但是'O=输出目录'的优先级要高于'BUILD_DIR=输出目录'。

(2)OBJTREE、SRCTREE、TOPDIR、LNDIR

OBJTREE:编译出的.o文件存放的目录。在默认编译下,OBJTREE=当前目录;在O=xxx下,OBJTREE=xxx。

SRCTREE:源码目录,uboot的根目录,当前目录。

TOPDIR:顶层目录,也就是uboot的根目录。

LNDIR:链接目录。

总结:在默认编译下,OBJTREE等于SRCTREE;在O=xxx下,OBJTREE与SRCTREE不相等。

(3)MKCONFIG

MKCOFNIG是一个变量,它的值是uboot根目录下的mkconfig。mkconfig是一个脚本文件,在uboot配置阶段使用。

5. 两个重要的环境变量:ARCH、CROSS_COMPILE(124 ~ 182行)

#########################################################################

ifeq ($(ARCH),powerpc)
ARCH = ppc
endif

ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))

# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export	ARCH CPU BOARD VENDOR SOC

ifndef CROSS_COMPILE
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE =
else
ifeq ($(ARCH),ppc)
CROSS_COMPILE = ppc_8xx-
endif
ifeq ($(ARCH),arm)
#CROSS_COMPILE = arm-linux-
#CROSS_COMPILE = /usr/local/arm/4.4.1-eabi-cortex-a8/usr/bin/arm-linux-
#CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
CROSS_COMPILE = /home/linuxwei/toolchain/arm-2009q3/bin/arm-none-linux-gnueabi-
endif
ifeq ($(ARCH),i386)
CROSS_COMPILE = i386-linux-
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-uclinux-
endif
ifeq ($(ARCH),avr32)
CROSS_COMPILE = avr32-linux-
endif
ifeq ($(ARCH),sh)
CROSS_COMPILE = sh4-linux-
endif
ifeq ($(ARCH),sparc)
CROSS_COMPILE = sparc-elf-
endif	# sparc
endif	# HOSTARCH,ARCH
endif	# CROSS_COMPILE

export	CROSS_COMPILE

(1)include $(obj)include/config.mk

include/config.mk不是源码自带的,是在配置过程(make x210_sd_config)中自动生成的。

在x210下生成的config.mk的内容为:

ARCH   = arm
CPU    = s5pc11x
BOARD  = x210
VENDOR = samsung
SOC    = s5pc110

后面一行就将这5个变量使用export导出作为环境变量。

注:这两行的作用就是为当前Makefile定义了5个环境变量,之所以没有直接给出,是希望这5个值可以很容易、集中配置。

(2)ARCH

ARCH:当前编译的目标CPU的架构。ARCH来自于配置过程,在上面已导出,它的值会影响后面CROSS_COMPILE的值。

(3)CROSS_COMPILE

CROSS_COMPILE:交叉编译工具链的前缀。在uboot中使用前缀+后缀的组成工具链中的各种工具,原因是在不同的CPU架构上,交叉编译工具链只是前缀不一样,后缀都是一样的,因此在定义时只需要把前缀和后缀分开,使用前缀来区分不同架构的CPU,就可以实现可移植性。

使用有两种方式:在Makefile中直接更改;在编译时指定CROSS_COMPILE。

6. include $(TOPDIR)/config.mk(185行)

# load other configuration
include $(TOPDIR)/config.mk

包含config.mk,该文件还是比较重要的,它的解析参考《uboot根目录下的config.mk解析》。

7. 第一个目标:all(291行)

all:		$(ALL)

注意一下uboot.*的生成。

8. 目标:unconfig(473 ~ 477行)

unconfig:
	@rm -f $(obj)include/config.h $(obj)include/config.mk \
		$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
		$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep \
		$(obj)board/$(VENDOR)/$(BOARD)/config.mk

9. 目标:x210_sd_config(2589 ~ 2591行)

x210_sd_config :	unconfig
	@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
	@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk

第1行命令:@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110

@:表示该条指令不显示。

$(MKCONFIG):MKCONFIG变量在前面已有定义,表示uboot根目录下的mkconfig,参考第4部分。

$(@:_config):@表示目标,即x210_sd_config,后面的‘:’表示要对其进行加工,即将目标中_config替换为空格。

经过以上分析,那么第1行命令替换完后的结果为mkconfig x210_sd arm s5pc11x x210 samsung s5pc110,也就是说该条指令的意思是执行mkconfig这个脚本文件,并给这个脚本文件传递6个参数,第1个参数为x210_sd,第2个参数为arm,第3个参数为s5pc11x,第4个参数为x210,第5个参数为samsung,第6个参数为s5pc110。

第2行命令:@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk

@:表示该条指令不显示

echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk:表示将内容TEXT_BASE = 0xc3e00000写入到board/samsung/x210/config.mk文件中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值