本篇要学习的config.mk文件,位于uboot源码的根目录下, 其包含了子目录下许多同名的config.mk。所以千万注意这些同名文件的主次区别
该文件内容主要结构为:
1. 设置各种路径
2. 设置主机环境的编译选项
3. 确定各交叉编译工具
4. 确定各种级别的编译选项
5. 指定链接脚本
6. 获得起始链接地址
7. 设置头文件搜寻路径
8. 使用起始链接地址
9. 设置自动推导规则
>> 设置各种路径
#设置各种路径
ifeq ($(CURDIR),$(SRCTREE))
#判断当前目录是否是顶层目录,如果是,设置dir为空
dir :=
else
# 如果不是,那么dir路径为 (CURDIR)去掉(SRCTREE)的部分
dir := $(subst $(SRCTREE)/,,$(CURDIR))
endif
# 如果源码目录与输出目录不是同一目录
ifneq ($(OBJTREE),$(SRCTREE))
# Create object files for SPL in a separate directory
# 且SPL是放在独立的目录下
ifeq ($(CONFIG_SPL_BUILD),y)
# 如果dir不为空,则obj路径在(SPLTREE)/dir/目录下
# 否则obj路径在(SPLTREE)目录下
obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)
else
# 如果SPL不是放在独立目录下
# 如果dir不为空,就放在(OBJTREE)/dir目录下
# 否则obj路径为(OBJTREE)目录下
obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/)
endif
# 设置src路径
# 如果dir目录不为空,则src路径指向dir
# 否则指向(SRCTREE)
# 建立obj文件夹???
src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/)
$(shell mkdir -p $(obj))
else
# Create object files for SPL in a separate directory
ifeq ($(CONFIG_SPL_BUILD),y)
obj := $(if $(dir),$(SPLTREE)/$(dir)/,$(SPLTREE)/)
$(shell mkdir -p $(obj))
else
obj :=
endif
src :=
endif
本段代码还是在进行原地编译和外部输出编译的一些路径设置,说到底,其实是把主Makefile中和路径有关的变量导入进来
#下面几个FLAG清除,作用…??
# clean the slate ...
PLATFORM_RELFLAGS =
PLATFORM_CPPFLAGS =
PLATFORM_LDFLAGS =
#########################################################################
#下面这两句不知道是什么意思,度娘也没有查出来...
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \
$(HOSTCPPFLAGS)
HOSTSTRIP = strip
#
# Mac OS X / Darwin's C preprocessor is Apple specific. It
# generates numerous errors and warnings. We want to bypass it
# and use GNU C's cpp. To do this we pass the -traditional-cpp
# option to the compiler. Note that the -traditional-cpp flag
# DOES NOT have the same semantics as GNU C's flag, all it does
# is invoke the GNU preprocessor in stock ANSI/ISO C fashion.
#
# Apple's linker is similar, thanks to the new 2 stage linking
# multiple symbol definitions are treated as errors, hence the
# -multiply_defined suppress option to turn off this error.
#
#根据上面的英文解释,可能是为了兼容苹果系统的编译器,避免警告错误
ifeq ($(HOSTOS),darwin)
# get major and minor product version (e.g. '10' and '6' for Snow Leopard)
# 获取系统版本
DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.')
DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.')
os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \
$(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)
# Snow Leopards build environment has no longer restrictions as described above
# 在雪豹系统上建议环境变量,我用的uboot是2011.09版本,所以当时苹果电脑还是用的雪豹版本
HOSTCC = $(call os_x_before, 10, 5, "cc", "gcc")
HOSTCFLAGS += $(call os_x_before, 10, 4, "-traditional-cpp")
HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress")
else
# 其它情况就是gcc编译器
HOSTCC = gcc
endif
ifeq ($(HOSTOS),cygwin)
# 设置标志位
HOSTCFLAGS += -ansi
endif
# We build some files with extra pedantic flags to try to minimize things
# that won't build on some weird host compiler -- though there are lots of
# exceptions for files that aren't complaint.
# 同样是设置一些标志
HOSTCFLAGS_NOPED = $(filter-out -pedantic,$(HOSTCFLAGS))
HOSTCFLAGS += -pedantic
>>关于编译器的一些设置
确定了完整的各交叉编译工具,通过顶层makefile中得到的CROSS_COMPILE变量(即工具链的前缀),由此定义各工具的名称
#########################################################################
#
# Option checker (courtesy linux kernel) to ensure
# only supported compiler options are used
# 下面这句话的意思是,测试cc是否支持第一个参数,然后根据返回结果选用不同的参数
cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
#
# 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
>>设置CPU相关路径,配置文件等
#########################################################################
# Load generated board configuration
# 加载配置文件
sinclude $(OBJTREE)/include/autoconf.mk
sinclude $(OBJTREE)/include/config.mk
# Some architecture config.mk files need to know what CPUDIR is set to,
# so calculate CPUDIR before including ARCH/SOC/CPU config.mk files.
# Check if arch/$ARCH/cpu/$CPU exists, otherwise assume arch/$ARCH/cpu contains
# CPU-specific code.
# 设置CPU的目录
CPUDIR=arch/$(ARCH)/cpu/$(CPU)
# 检查CUP目录
ifneq ($(SRCTREE)/$(CPUDIR),$(wildcard $(SRCTREE)/$(CPUDIR)))
CPUDIR=arch/$(ARCH)/cpu
endif
# 包含配置文件
sinclude $(TOPDIR)/arch/$(ARCH)/config.mk # include architecture dependend rules
sinclude $(TOPDIR)/$(CPUDIR)/config.mk # include CPU specific rules
# 包含上CPU的特殊配置
ifdef SOC
sinclude $(TOPDIR)/$(CPUDIR)/$(SOC)/config.mk # include SoC specific rules
endif
# 根据生产商,设置板子路径
ifdef VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
# 如果没有生产商,直接是默认的路径下
BOARDDIR = $(BOARD)
endif
# 如果找到,就包含上板子的特殊配置
ifdef BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
endif
#########################################################################
- 本段最开始包含了一个autoconf.mk文件,此文件也不是源码自带的,其内容全部都是CONFIG_开头的变量,makefile利用这些变量来指导编译过程的走向(.c文件条件编译)
- autoconf.mk其实是由顶层Makefile利用根目录下include/configs/x210_sd.h生成的,其内容与x210_sd.h没什么区别,其生成方式在顶层makefile的470多行左右
- uboot的可移植性很大程度来源于x210_sd.h文件,它也是移植工作的关键所在
- 后面几行分别inlude了和ARCH、CPU、SOC、VENDOR、BOARD相关的子config.mk,也就是包含了各种级别的编译属性选项
>>关于编译器的一些设置
ifneq (,$(findstring s,$(MAKEFLAGS)))
ARFLAGS = cr
else
ARFLAGS = crv
endif
RELFLAGS= $(PLATFORM_RELFLAGS)
DBGFLAGS= -g # -DDEBUG
OPTFLAGS= -Os #-fomit-frame-pointer
OBJCFLAGS += --gap-fill=0xff
gccincdir := $(shell $(CC) -print-file-name=include)
ARFLAGS = cr
else
ARFLAGS = crv
endif
RELFLAGS= $(PLATFORM_RELFLAGS)
DBGFLAGS= -g # -DDEBUG
OPTFLAGS= -Os #-fomit-frame-pointer
OBJCFLAGS += --gap-fill=0xff
gccincdir := $(shell $(CC) -print-file-name=include)
>> 本段最开始先配置了一些编译选项,随后做了一些和TEXT_BASE相关的工作
>> 在前面include了一个board级别的config.mk文件 ,这个.mk文件源码中不存在,
是在顶层makefile中由x210_sd_config创建的,并在ARCH、SOC等变量后面添加TEXT_BASE,展开后就获得了一个TEXT_BASE变量
>> EXT_BASE这个变量的含义是uboot将来被链接时的起始地址,
是规定好的,但由于uboot使用虚拟地址映射,所以这个地址并不是真正的物理地址
>> 最后进行判断,如果TEXT_BASE不为空,就将其设置到CPPFLAGS里面去
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
ifneq ($(CONFIG_SYS_TEXT_BASE),)
CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE)
endif
ifneq ($(CONFIG_SPL_TEXT_BASE),)
CPPFLAGS += -DCONFIG_SPL_TEXT_BASE=$(CONFIG_SPL_TEXT_BASE)
endif
ifeq ($(CONFIG_SPL_BUILD),y)
CPPFLAGS += -DCONFIG_SPL_BUILD
endif
ifneq ($(RESET_VECTOR_ADDRESS),)
CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS)
endif
ifneq ($(OBJTREE),$(SRCTREE))
CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include
endif
CPPFLAGS += -I$(TOPDIR)/include
CPPFLAGS += -fno-builtin -ffreestanding -nostdinc \
-isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS)
ifdef BUILD_TAG
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes \
-DBUILD_TAG='"$(BUILD_TAG)"'
else
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes
endif
CFLAGS += $(call cc-option,-fno-stack-protector)
# Some toolchains enable security related warning flags by default,
# but they don't make much sense in the u-boot world, so disable them.
CFLAGS += $(call cc-option,-Wno-format-nonliteral)
CFLAGS += $(call cc-option,-Wno-format-security)
# $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format>
# option to the assembler.
AFLAGS_DEBUG :=
# turn jbsr into jsr for m68k
ifeq ($(ARCH),m68k)
ifeq ($(findstring 3.4,$(shell $(CC) --version)),3.4)
AFLAGS_DEBUG := -Wa,-gstabs,-S
endif
endif
AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)
LDFLAGS += $(PLATFORM_LDFLAGS)
LDFLAGS_FINAL += -Bstatic
LDFLAGS_u-boot += -T $(obj)u-boot.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SYS_TEXT_BASE),)
LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
endif
LDFLAGS_u-boot-spl += -T $(obj)u-boot-spl.lds $(LDFLAGS_FINAL)
ifneq ($(CONFIG_SPL_TEXT_BASE),)
#指定起始地址TEXT_BASE
LDFLAGS_u-boot-spl += -Ttext $(CONFIG_SPL_TEXT_BASE)
Endif
TEXT_BASE和_start的区别 :
_start是可以动态变化,而TEXT_BASE是链接时就确定的地址。
_start是实际运行的地址,而TEXT_BASE是要copy到sdram中运行的地址, 当然也是最终u-boot实际运行的地址。
u-boot的start.S中在启动第一阶段会比较这两个值是否相等,不相等则会将自身copy到sdram中。
假设_start出是第一条执行的指令,并且TEXT_BASE=0x27800000,那么分两种情况说明:
当u-boot被download到nor flash或被copy到内部sram时,假设被copy到的地址是0x907000,那么此时_start的地址是0x907000,此时就需要将自身copy到TEXT_BASE地方。
当u-boot本身就被download sdram的TEXT_BASE定义的地址出,那么此时_start本身的地址就是0x27800000了,所以和TEXT_BASE比较的结果相等而不用作自身代码搬移的工作了。
_start是可以动态变化,而TEXT_BASE是链接时就确定的地址。
_start是实际运行的地址,而TEXT_BASE是要copy到sdram中运行的地址, 当然也是最终u-boot实际运行的地址。
u-boot的start.S中在启动第一阶段会比较这两个值是否相等,不相等则会将自身copy到sdram中。
假设_start出是第一条执行的指令,并且TEXT_BASE=0x27800000,那么分两种情况说明:
当u-boot被download到nor flash或被copy到内部sram时,假设被copy到的地址是0x907000,那么此时_start的地址是0x907000,此时就需要将自身copy到TEXT_BASE地方。
当u-boot本身就被download sdram的TEXT_BASE定义的地址出,那么此时_start本身的地址就是0x27800000了,所以和TEXT_BASE比较的结果相等而不用作自身代码搬移的工作了。
# Location of a usable BFD library, where we define "usable" as
# "built for ${HOST}, supports ${TARGET}". Sensible values are
# - When cross-compiling: the root of the cross-environment
# - Linux/ppc (native): /usr
# - NetBSD/ppc (native): you lose ... (must extract these from the
# binutils build directory, plus the native and U-Boot include
# files don't like each other)
#
# So far, this is used only by tools/gdb/Makefile.
# 不同的系统设置不同的路径
ifeq ($(HOSTOS),darwin)
BFD_ROOT_DIR = /usr/local/tools
else
ifeq ($(HOSTARCH),$(ARCH))
# native
BFD_ROOT_DIR = /usr
else
#BFD_ROOT_DIR = /LinuxPPC/CDK # Linux/i386
#BFD_ROOT_DIR = /usr/pkg/cross # NetBSD/i386
BFD_ROOT_DIR = /opt/powerpc
endif
endif
#########################################################################
# 设置环境变量???
export HOSTCC HOSTCFLAGS HOSTLDFLAGS PEDCFLAGS HOSTSTRIP CROSS_COMPILE \
AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE
export CONFIG_SYS_TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS
#########################################################################
指定编译规则
#########################################################################
# Allow boards to use custom optimize flags on a per dir/file basis
#
BCURDIR = $(subst $(SRCTREE)/,,$(CURDIR:$(obj)%=%))
ALL_AFLAGS = $(AFLAGS) $(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR))
ALL_CFLAGS = $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR))
$(obj)%.s: %.S
$(CPP) $(ALL_AFLAGS) -o $@ $<
$(obj)%.o: %.S
$(CC) $(ALL_AFLAGS) -o $@ $< -c
$(obj)%.o: %.c
$(CC) $(ALL_CFLAGS) -o $@ $< -c
$(obj)%.i: %.c
$(CPP) $(ALL_CFLAGS) -o $@ $< -c
$(obj)%.s: %.c
$(CC) $(ALL_CFLAGS) -o $@ $< -c -S
#########################################################################
# If the list of objects to link is empty, just create an empty built-in.o
cmd_link_o_target = $(if $(strip $1),\
$(LD) $(LDFLAGS) -r -o $@ $1,\
rm -f $@; $(AR) rcs $@ )
#########################################################################