uboot配置编译过程分析之uboot源码目录下的config.mk的分析:
文件的来源:uboot的原生文件;
文件的路径:uboot/config.mk
文件被引用的地方:主Makefile中被引用,用来分担Makefile的工作 (184行)
config.mk文件在主Makefile中被引用:
# load other configuration
include $(TOPDIR)/config.mk
uboot的config.mk文件其实是Makefile的一个补充版,与Makefile与其他几个文件一起来完成类似于简单代码的Makefile文件的功能,只不过在uboot中将其模块化,Makefile主要进行一些识别的功能,根据我们不同的需求,目标生成不同的相关文件,而config.mk来完成那些相同的工作。
下面将以九鼎为x210移植的uboot源码根目录下的config.mk为分析的目标具体的介绍config.mk的工作:
1.对各种链接参数进行设置:
PLATFORM_RELFLAGS =
PLATFORM_CPPFLAGS =
PLATFORM_LDFLAGS =
清空这些链接参数。
ifeq ($(ARCH),arm)
ifeq ($(CROSS_COMPILE),powerpc-netbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
endif
设置PLATFORM_RELFLAGS参数。
ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc)
HOSTCC = cc
else
HOSTCC = gcc
endif
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTSTRIP = strip
其他链接参数的设置,这里的HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer 相当于我们常写的Makefile中的CFLAGS := -Wall -O2 -g -DDEBUG。
2.导出交叉编译工具链:
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
完整的交叉编译工具链包含很多的编译器,而他们前面的部分都是相同的,就是交叉编译工具链的位置也就是CROSS_COMPILE,在主Makefile将其导出,在这里可直接使用。
3.导入配置阶段make之后生成的autoconf.mk文件:
sinclude $(OBJTREE)/include/autoconf.mk
autoconf.mk这个文件就是用来指导整个uboot的编译过程,这个文件的内容其实就是很多的CONFIG开头的宏,这些宏会影响我们uboot的编译过程,原理就是利用条件编译来区别不同的开发板,是实现可移植性的基础。
autoconfig.mk文件产生于源代码根目录下的include/configs/xxx.h头文件。此config目录下包括了各个版本开发板的全部头文件。在移植的时候,只要是将对应的头文件留下,并作出相应的修改。而我们当前开发板对应的文件是: x210_sd.h。每一个开发板将会对应一个此类的文件,这些开发板配置文件是我们移植uboot的关键所在。
4.通过条件变量添加一些config.mk
ifdef ARCH
sinclude $(TOPDIR)/$(ARCH)_config.mk # include architecture dependend rules
endif
ifdef CPU
sinclude $(TOPDIR)/cpu/$(CPU)/config.mk # include CPU specific rules
endif
ifdef SOC
sinclude $(TOPDIR)/cpu/$(CPU)/$(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
在uboot中配置阶段之后会生成很多的config.mk,在分析时一定要注意区分,在这里在主Makefile中导入了/include/config.mk,然后导出 由于CPU SOC VENDOR BOARD 到环境变量中,所以在这里条件编译成立,包含了五个不同的config.mk,他们都对uboot的编译起着指导作用。
5.引出了链接脚本文件:u-boot.lds:u-boot.lds大侠正式登场
ifeq ($(CONFIG_NAND_U_BOOT),y)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
else
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
由于我们x210使用的是inand启动,而不是nand启动,所来分析来看链接脚本文件指定的是第二个文件;
通过对uboot/include/autoconf.mk文件进行分析:
CONFIG_NAND_BL1_8BIT_ECC=y
配置文件中未定义CONFIG_NAND_U_BOOT,这也充分的验证了我们分析的真确性。
6.对CPPFLAGS连接参数再次进行设置:
ifneq ($(TEXT_BASE),)
CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
endif
在之前的对于ARCH CPU SOC VENDOR BOARD的条件编译时, 由于make时指定了TEXT_BASE的存放位置文件夹,在那里就将TEXT_BASE包含进我们此文件中,然后TEXT_BASE与空进行比对,进而将TEXT_BASE赋值给CPPFLAGS。
7.对链接起始地址进行设置:
在主Makefile中配置开发板时传入了TEXT_BASE,然后建立了一个新的文件/board/samsung/x210/config.mk放入TEXT_BASE
x210_sd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
ifneq ($(TEXT_BASE),)
LDFLAGS += -Ttext $(TEXT_BASE)
endif
与前面的CPPFLAGS一样,在之前包含的五个config.mk中就有着我们配置阶段完成后将链接地址存放的那个config.mk文件,这样一来自然也就定义了TEXT_BASE,config.mk内的TEXT_BASE是整个uboot链接时指定的链接地址。而这个地址是一个虚拟地址映射,具体的地址取决于uboot中的虚拟地址映射关系。
8.设置与Makefile中类似的自动推导规则:
ifndef REMOTE_BUILD
%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
else
$(obj)%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
$(obj)%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
$(obj)%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
endif
对此自动推导规则将不做多余的介绍,具体请参考陈皓的《跟我一起写Makefile》。