1、uboot版本号的确定
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 4
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)这句代码,代表了uboot的最终格式。
例如这里U_BOOT_VERSION = 1.3.4
VERSION:主版本号
PATCHLEVEL:次版本号
SUBLEVEL:再次版本号
EXTRAVERSION:
2、HOSTARCH和HOSTOS的确定
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/)
(1)$(shell uname -m) :就是执行shell命令:uname -m,结果就是将当前的主机硬件架构名称,在Ubuntu中结果为i686.
(2) “ | ”:在Makefile中的含义为,把前面的表达式输出结果,作为后面表达式的输入,这里就是将i686作为后面代码sed -e s/i.86/i386/ 的输入。
(3)sed -e s/i.86/i386/ :sed就是字符串比较指令,-e代表相等的意思,s就是替换,如果比较的字符串和i.86(.代表的任意符号的意思)相等的时候,就使用i386替换该字符串输出。所以这里的HOSTARCH的结果为i386。
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
(1)shell uname -s:shell命令uname -s,显示操作系统的名称,这里Ubuntu的结果为Linux,
(2)tr命令可以对来自标准输入的字符进行替换、压缩和删除。它可以将一组字符变成另一组字符,经常用来编写优美的单行命令,作用很强大。
[:upper:]:代表所用的大写字母。
[:lower:]:代表所有的小写字母。
$(shell uname -s | tr '[:upper:]' '[:lower:]':把所用的大写字母变成小写字母,所里这里输出linux。
备注:这里还有一种执行shell命令的方法:反引号的方式。
3、静默编译:即不会输出相关的一些信息。
# Allow for silent builds
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
当我们在编译uboot的时候,可以同通过传递的参数make -s来使用该功能能。
MAKWFLAGS,代表输入的参数。
4、编译方法:原地编译和单独输出文件夹编译的方式。
(1)原地编译:编译出来的.o和.c直接放在一起
(2)单独输出文件:基本思路就是在编译的时候另外指定一个输出目录。
用法:指定输出文件目录
make O = 输出目录;
export BUILD_DIR = 输出目录,然后make,这两个命令都可以指定输出目录,但是第一个的优先级更好。意思就是当我们同时使用两个命令的时候,第一个命令起作用。
note:由于这两种编译方式的不同,就会导致,后面代码的差别的。也就是 OBJTREE和SRCTREE的是否相同的。
5、OBJTREE、SRCTREE、TOPDIR环境变量
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
OBJTREE:代表编译出来的.o文件的存放目录的根目录。
SRCTREE:源码目录,也就是源代码的根目录,也就是当前目录。
总结:OBJTREE就是为了实现记录编译后的.o文件,往哪里放,就是为了实现make O=xxx的这种编译方式。
6、MKCONFIG环境变量
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
MKCONFIG是一个环境变量,它所对应的数值,代表的是一个文件mkconfig,源码目录底下的,是一个脚本文件,就是我们的配置脚本,很重要的一个文件。
7、include $(obj)include/config.mk
# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
这个config.mk是配置过程中生成的makefile文件,不是源码自带的,就是我们在make x210_sd_config配置uboot的时候生成的,这个config.mk中的内容为:
ARCH = arm
CPU = s5pc11x
BOARD = x210
VENDOR = samsung
SOC = s5pc110
通过包含这个文件,将这些环境变量导出。这些环境变量,都是在配置的时候生成,例如配置目标对应的命令,会传递这几个参数:
x210_sd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110这句代码,最后六个作为参数传递给第一个脚本程序,这个脚本程序,在这个脚本程序中,会在./include目录下创建config.mk文件,并将这些环境变量传递进去。
8、交叉编译工具链的前缀确定:CROSS_COMPILE环境变量
ifndef CROSS_COMPILE
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE =
else
ifeq ($(ARCH),ppc)
CROSS_COMPILE = ppc_8xx-
endif
ifeq ($(ARCH),arm) #我们uboot的ARCH为arm,而且编译代码的主机和执行的主机是不同
cc
endif
最终CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
这里需要说明的一点为什么要区分前缀和后缀:
交叉编译工具链的确定需要前缀和后缀,这里把前缀和后缀分开,在不同框架的CPU的交叉编译工具链中,只是前缀不同,后缀完全相同,所以可以执行很好。只要确定好前缀就可以了。
还有我们也可以通过编码代码的时候,指定交叉编译工具链的前缀,而且优先级是最高的。
9、include $(TOPDIR)/config.mk
下面分析该文件中代码:
1、将交叉编译工具链的前缀和后缀结合
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB = $(CROSS_COMPILE)RANLIB
2、包含 sinclude $(OBJTREE)/include/autoconf.mk ,其中的部分代码
CONFIG_CMD_FAT=y
CONFIG_USB_OHCI=y
CONFIG_SYS_CLK_FREQ=24000000
CONFIG_CMD_ITEST=y
CONFIG_S3C_HSMMC=y
CONFIG_DISPLAY_BOARDINFO=y
CONFIG_CMD_XIMG=y
CONFIG_CMD_CACHE=y
CONFIG_STACKSIZE="0x40000"
CONFIG_BOOTDELAY=3
CONFIG_CHECK_MPLL_LOCK=y
CONFIG_NR_DRAM_BANKS=2
CONFIG_ETHADDR="00:40:5c:26:0a:5b"
CONFIG_CMD_CONSOLE=y
CONFIG_SW_WORKAROUND=y
CONFIG_GATEWAYIP="192.168.0.1"
CONFIG_DRIVER_DM9000=y
CONFIG_ZIMAGE_BOOT=y
CONFIG_CMD_REGINFO=y
autoconfi.mk是用来指导整个uboot编译过程的。这个文件的内容就是很多CONFIG_开头的宏定义。这些宏会影响我们uboot编译过程的走向(作用原理就在于uboot中的众多的条件编译)。在uboot代码中有很多地方使用了条件编写进行编写,这个条件编译的目的就是用来实现可移植性的。可以说uboot的源码很大程序上是拼凑出来的,同一代码包含了各种不同开发板的适用代码,用条件编译来进行区分。
这个文件也是配置过程中自动生成的。