本文内容来自对 《朱有鹏嵌入式linux核心课程》学习总结
uboot主makefile分析2
1. OBJTREE, SRCTREE, TOPDIR
OBJTREE
: 编译出.o
文件放的目录的根目录。在默认编译下,OBJTREE
等于当前目录;在o=xx
编译下,OBJTREE
就等于我们设置的那个输出目录。SRCTREE
: 源码目录,其实就浊源代码的根目录,也就是当前目录。
总结: 在默认编译下,OBJTREE
和SRCTREE
相等;在o=xx
这种编译下OBJTREE
和SRCTREE
不相等。Makefile
中定义这两个变量,其实就是为了记录编译后的.o
文件往哪里放,就是为了实现o=xx
的这种编译方式。
2. MKCONFIG (101行)
Makefile
中定义的一个变量(在这里定义,在后面使用),它的值就是我们源码根目录下面的mkconfig
。这个mkconfig
是一个脚本,这个脚本就是uboot
配置阶段的配置脚本。MKCONFIG := $(SRCTREE)/mkconfig export MKCONFIG
3. include $(obj)include/config.mk(133行)
include/config.mk
不是源码自带的(没有编译过的源码目录下没有这个文件),要在配置过程(make x21_sd_config
)中才会生成这个文件。因此这个文件的值和我们配置过程有关,根据我们的配置自动生成的。- 我们在
x210
在iNand
情况下配置生成的config.mk
内容为:ARCH = arm CPU = s5pc11x BOARD = x210 VENDOR = samsung SOC = s5pc110
- 在下一行(134行)
export
导出了这5个变量作为环境变量。所以这两行加起来是为当前makefile
定义了5个环境变量而已。之所以不直接给出这5个环境变量的值,是因为我们希望这5个值是可以被集中配置的。 - 这里的配置值来自于2589行那里的配置项。如果我们要更改这里的某个配置值要到2589行那里调用
MKCONFIG
脚本传参时的参数。
4. ARCH_CROSS_COMPILE
- 接下来有两个重要的环境变量。一个是
ARCH
,上面导出的,值来自于我们的配置过程,它的值会影响后面的CROSS_COMPILE
环境变量的值。ARCH
的意义是定义当前编译的目标CPU
的架构。 CROSS_COMPILE
在136-182行来确定。CROSS_COMPILE
是被ARCH
所确定的,只要配置了ARCH=arm
,那么我们就只能在ARM
的那个分支去设置CROSS_COMPILE
的值。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 = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi- endif ifeq ($(ARCH),i386) CROSS_COMPILE = i386-linux- endif ifeq ($(ARCH),mips) CROSS_COMPILE = mips_4KC- endif
- 实际运用时,可以在
Makefile
中去更改设置CROSS-COMPILE
的值,也可以在编译时用make CROSS_COMPILE=xxx
来设置,而且编译时传参的方法可以覆盖Makefile
里面的设置。
5. $(TOPDIR)/config.mk(主makefile的185行)
6. 编译工具定义(config.mk 94-107行)
7. 包含开发板配置项目(config.mk 112行)
autoconfig.mk
文件不是源码提供的,是配置过程生成的。- 这个文件的作用就是用来指导整个
uboot
的编译过程。这个文件的内容其实就是很多CONFIG
开头的宏(可以理解为变量),这些宏/变量会影响我们uboot
编译过程的走向(原理就是条件编译)。在uboot
代码中有很多地方使用条件编译进行编写,这个条件编译是用来实现可移植性的。(可以说uboot
的源代码在很大程序来说是拼凑起来的,同一个代码包含了各种不同开发板的适用代码,用条件编译进行区别)。 - 这个文件不是凭空产生的,配置过程也是需要原材料来产生这个文件的。原材料在源码目录的
include/configs/xxx.h
头文件。(x210开发板中为incude/configs/x210_sd.h
)。这个头文件里面全都是宏定义,这些宏定义就是我们对当前开发板的移植。每一个开发板的移植都对应这个目录下的一个头文件,这个头文件里每一个宏定义都很重要,这些配置的宏定义就是我们移植uboot
的关键所在。
8. 链接脚本(config.mk 142-149行)
-
如果定义了
CONFIG_NAND_U_BOOT
宏,则链接脚本叫u-boot-nand.lds
,如果未定义这个宏则链接脚本叫u-boot.lds
。 -
CONFIG_NAND_U_BOOT
是在Nand版本情况下才使用的,我们使用的X210
都是iNand
版本的,因此这个宏没有的。 -
实际在
board\samsung\x210
目录下有u-boot.lds
,这个就是链接脚本。在分析uboot
的编译链接过程时要考虑这个链接脚本。ifeq ($(CONFIG_NAND_U_BOOT),y) LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds else LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds endif
9. TEXT_BASE (config.mk 156-158行)
-
Makefile
中配置x210
开发板时,在board\samsung\x210
目录下生成了一个文件config.mk
,其中的内容就是:TEXT_BASE = 0xc3e00000
相当于定义了一个变量。 -
TEXT_BASE
是将来我们整个uboot
链接时指定的链接地址。因为uboot
中启用了虚拟地址映射,因此这个C3E00000
地址就等于0x23E00000
(也可能是33E00000
具体地址要取决于uboot
中做的虚拟地址映射关系)。ifneq ($(TEXT_BASE),) CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) endif
10. 自动推导规则(config.mk 239-256行)
- 具体可参考《和我一起学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
11. 目标
Makefile
第291行出现了整个主Makefile
中第一个目标all
(也就是默认目标,我们直接在uboot
根目录下make
其实就等于make all
,就等于make
这个目标)- 目标中有一些比较重要的。譬如:
u-boot
是最终编译链接生成的elf
格式的可执行文件。 unconfig
。这个符号用来做为我们各个开发板配置目标的依赖。目标是不发我们已经配置过一个开发板后再次去配置时还可以配置。- 我们配置开发板时使用:
make x210_sd_config
,因此分析x210_sd_config
肯定是主Makefile
中的一个目标。