主Makefile位于uboot源码的根目录下,其内容主要结构为:
1. 确定版本号及主机信息(23至48行)
2. 实现静默编译功能(48至55行)
3. 设置各种路径(56至123行)
4. 设置编译工具链(124至186行,大部分在config.mk内)
5. 设置规则(187至470行)
6. 设置与cpu相关的伪目标(480至末尾)
需要注意的是,结构顺序不代表代码执行顺序
为了保证阅读的效果,请按推荐的顺序阅读源码。
0.许可声明(1至22行,略)
在Makefile的语法中,井号只有在行首才具有完整的行注释功能,与C语言中的//用法略有不同1.确定版本号及主机信息(23至48行)
1
2
3
4
5
6
7
|
VERSION = 1 PATCHLEVEL = 3 SUBLEVEL = 4 EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) VERSION_FILE = $(obj)include/version_autogenerated.h </code> |
1
2
3
4
5
6
7
8
9
|
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/) </code> |
1
2
3
|
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | sed -e 's/(cygwin).*/cygwin/' ) </code> |
1
|
export HOSTARCH HOSTOS</code> |
2.实现静默编译功能(48至55行)
1
2
3
4
5
6
7
8
|
######################################################################### # Allow for silent builds ifeq (,$(findstring s,$(MAKEFLAGS))) XECHO = echo else XECHO = : endif </code> |
3.设置各种路径(56至123行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
######################################################################### # # 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. # </code> |
1
2
3
4
5
6
7
8
|
ifdef O ifeq ( "$(origin O)" , "command line" ) BUILD_DIR := $(O) endif endif ifneq ($(BUILD_DIR),) saved-output := $(BUILD_DIR)</code> |
1
2
|
# Attempt to create a output directory. $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})</code> |
1
2
3
4
|
# 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),)</code> |
1
2
3
4
5
|
OBJTREE := $( if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) SRCTREE := $(CURDIR) TOPDIR := $(SRCTREE) LNDIR := $(OBJTREE) export TOPDIR SRCTREE OBJTREE</code> |
1
2
3
|
MKCONFIG := $(SRCTREE)/mkconfig export MKCONFIG </code> |
1
2
3
4
5
|
ifneq ($(OBJTREE),$(SRCTREE)) REMOTE_BUILD := 1 export REMOTE_BUILD endif </code> |
1
2
3
4
5
6
7
8
9
10
11
12
|
# $(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 </code> |
4.设置编译工具链(124至186行,大部分在config.mk内)
1
2
3
4
5
6
|
ifeq ($(ARCH),powerpc) ARCH = ppc endif ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk)) </code> |
1
2
3
|
# load ARCH, BOARD, and CPU configuration include $(obj)include/config.mk export ARCH CPU BOARD VENDOR SOC</code> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
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 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</code> |
1
2
|
# load other configuration include $(TOPDIR)/config.mk</code> |
5.设置规则(187至470行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
######################################################################### # U-Boot objects....order is important (i.e. start must be first) OBJS = cpu/$(CPU)/start.o ifeq ($(CPU),i386) OBJS += cpu/$(CPU)/start16.o OBJS += cpu/$(CPU)/reset.o endif ifeq ($(CPU),ppc4xx) OBJS += cpu/$(CPU)/resetvec.o endif ifeq ($(CPU),mpc85xx) OBJS += cpu/$(CPU)/resetvec.o endif OBJS := $(addprefix $(obj),$(OBJS)) </code> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
LIBS = lib_generic/libgeneric.a LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo "board/$(VENDOR)/common/lib$(VENDOR).a" ; fi) LIBS += cpu/$(CPU)/lib$(CPU).a ifdef SOC LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a endif ifeq ($(CPU),ixp) LIBS += cpu/ixp/npe/libnpe.a endif LIBS += lib_$(ARCH)/lib$(ARCH).a LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a LIBS += net/libnet.a LIBS += disk/libdisk.a LIBS += drivers/bios_emulator/libatibiosemu.a LIBS += drivers/block/libblock.a LIBS += drivers/dma/libdma.a LIBS += drivers/hwmon/libhwmon.a LIBS += drivers/i2c/libi2c.a LIBS += drivers/input/libinput.a LIBS += drivers/misc/libmisc.a LIBS += drivers/mmc/libmmc.a LIBS += drivers/mtd/libmtd.a LIBS += drivers/mtd/nand/libnand.a LIBS += drivers/mtd/nand_legacy/libnand_legacy.a LIBS += drivers/mtd/onenand/libonenand.a LIBS += drivers/mtd/ubi/libubi.a LIBS += drivers/mtd/spi/libspi_flash.a LIBS += drivers/net/libnet.a LIBS += drivers/net/sk98lin/libsk98lin.a LIBS += drivers/pci/libpci.a LIBS += drivers/pcmcia/libpcmcia.a LIBS += drivers/spi/libspi.a ifeq ($(CPU),mpc83xx) LIBS += drivers/qe/qe.a endif ifeq ($(CPU),mpc85xx) LIBS += drivers/qe/qe.a endif LIBS += drivers/rtc/librtc.a LIBS += drivers/serial/libserial.a LIBS += drivers/usb/libusb.a LIBS += drivers/video/libvideo.a LIBS += common/libcommon.a LIBS += libfdt/libfdt.a LIBS += api/libapi.a LIBS += post/libpost.a LIBS := $(addprefix $(obj),$(LIBS)) .PHONY : $(LIBS) $(VERSION_FILE) LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a LIBBOARD := $(addprefix $(obj),$(LIBBOARD)) # Add GCC lib PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc </code> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
SUBDIRS = tools examples api_examples .PHONY : $(SUBDIRS) ifeq ($(CONFIG_NAND_U_BOOT),y) NAND_SPL = nand_spl U_BOOT_NAND = $(obj)u-boot-nand.bin endif ifeq ($(CONFIG_ONENAND_U_BOOT),y) ONENAND_IPL = onenand_bl1 U_BOOT_ONENAND = $(obj)u-boot-onenand.bin endif __OBJS := $(subst $(obj),,$(OBJS)) __LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD)) </code> |
1
2
3
4
5
6
7
8
9
10
|
######################################################################### ######################################################################### ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND) $(obj)u-boot.dis ifeq ($(ARCH),blackfin) ALL += $(obj)u-boot.ldr endif all: $(ALL) </code> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
$(obj)u-boot.hex: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ $(obj)u-boot.srec: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ $(obj)u-boot.bin: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ $(obj)u-boot.ldr: $(obj)u-boot $(LDR) -T $(CONFIG_BFIN_CPU) -f -c $@ $< $(LDR_FLAGS) $(obj)u-boot.ldr.hex: $(obj)u-boot.ldr $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary $(obj)u-boot.ldr.srec: $(obj)u-boot.ldr $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary $(obj)u-boot.img: $(obj)u-boot.bin ./tools/mkimage -A $(ARCH) -T firmware -C none -a $(TEXT_BASE) -e 0
-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | sed -e 's/"[ ]*$$/ for $(BOARD) board"/' ) -d $< $@ $(obj)u-boot.sha1: $(obj)u-boot.bin $(obj)tools/ubsha1 $(obj)u-boot.bin $(obj)u-boot.dis: $(obj)u-boot $(OBJDUMP) -d $< > $@ $(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | sed -n -e 's/.*($(SYM_PREFIX)__u_boot_cmd_.*)/-u1/p' |sort|uniq`; cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) -Map u-boot.map -o u-boot $(OBJS): depend $(obj)include/autoconf.mk $(MAKE) -C cpu/$(CPU) $( if $(REMOTE_BUILD),$@,$(notdir $@)) $(LIBS): depend $(obj)include/autoconf.mk $(MAKE) -C $(dir $(subst $(obj),,$@)) $(LIBBOARD): depend $(LIBS) $(obj)include/autoconf.mk $(MAKE) -C $(dir $(subst $(obj),,$@)) $(SUBDIRS): depend $(obj)include/autoconf.mk $(MAKE) -C $@ all $(LDSCRIPT): depend $(obj)include/autoconf.mk $(MAKE) -C $(dir $@) $(notdir $@) $(NAND_SPL): $(VERSION_FILE) $(obj)include/autoconf.mk $(MAKE) -C nand_spl/board/$(BOARDDIR) all $(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin 后面还有一大堆繁琐但不是很重要的代码,就不贴了</code> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# # Auto-generate the autoconf.mk file (which is included by all makefiles) # # This target actually generates 2 files; autoconf.mk and autoconf.mk.dep. # the dep file is only include in this top level makefile to determine when # to regenerate the autoconf.mk file. $(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h @$(XECHO) Generating $@ ; set -e ; : Generate the dependancies ; $(CC) -x c -DDO_DEPS_ONLY -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)include/autoconf.mk include/common.h > $@ $(obj)include/autoconf.mk: $(obj)include/config.h @$(XECHO) Generating $@ ; set -e ; : Extract the config macros ; $(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | sed -n -f tools/scripts/define2mk.sed > $@ sinclude $(obj)include/autoconf.mk.dep </code> |
6.设置与cpu相关的伪目标(480至末尾)
1
2
3
4
5
6
|
#由于这些代码都与cpu本身有关,有 2000 多行,且功能重复,故这里挑选我们板子上的s5pv210为例子来分析,这行代码大概位于 2600 多行。 x210_sd_config : unconfig @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110 @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk </code> |
引用自:http://blog.csdn.net/qq_28992301/article/details/51802885