uboot 主Makefile 分析。
本文以uboot_1.1.6 对应的CPU是S3C2440 为例
uboot_1.1.6 根目录下的主Makefile开头:
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 6
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
1、uboot的版本号分3个级别:
VERSION: 主板本号
PATCHLEVEL: 次版本号
SUBLEVEL: 再次版本号
EXTRAVERSION: 额外的版本信息
2、Makefile中版本号最终生成了一个变量U_BOOT_VERSION,U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) 即:U_BOOT_VERSION = 1. 1.6
3、include/version_autogenerated.h文件是编译过程中执行make xxxx_config 后自动生成的一个文件,所以源目录中没有,但是编译过后的uboot中就有了。被include/version.h文件包含。
在\u-boot-1.1.6_jz2440\u-boot-1.1.6\cpu\arm920 中的START.S中会包含#include <version.h>:
#include <config.h>
#include <version.h>
version.h代码如下:
#ifndef __VERSION_H__ #define __VERSION_H__ #include "version_autogenerated.h" #endif /* __VERSION_H__ */
version_autogenerated.h中代码如下:就是包含了一个UBOOT 版本好的宏定义。
#define U_BOOT_VERSION "U-Boot 1.1.6"
下列代码主要是获取目前使用计算机的架构信息:
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/macppc/ppc/)
$(shell uname -m)表示执行uname –m的shell命令,在本计算机的Ubuntu虚拟机中执行 uname -m命令,返回 x86_64:
book@www.100ask.org:/$ uname -m
x86_64
sed –e s/abc/def 的意思是寻找结果里面是否有’abc’字样,如果有,就用‘def’字样将其代替。所以整条语句的意思就是,取出uname –m的结果,并在其中寻找是否有i.86字样,如果有就用i386代替,是否有arm.*(*是通配符),如果有,就用arm代替……,
本台机的结果是x86-64所以还保持原样,没有用其他字符替换,所以HOSTARCH=x86-64。
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ sed -e 's/\(cygwin\).*/cygwin/') export HOSTARCH HOSTOS
获取主机操作系统信息,执行结果是将Linux中的大写字母全部换成小写字母。
book@www.100ask.org:/$ uname -s | tr '[:upper:]' '[:lower:]' | \
> sed -e 's/\(cygwin\).*/cygwin/'
linux
然后通过export 输出HOSTARCH和HOSTOS变量
下列代码支持uboot编译出的工程文件是放在源文件夹下还是指定的外部文件夹:
######################################################################### # # 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. #
有两种方式通过1、通过命令行方式输出目录 'make O=/tmp/build all' 输出到tmp/build 目录。2、通过设置环境变量的方式,设置BUILD_DIR=/tmp/build。 命令行的方式会覆盖环境变量的方式。如果没有采用上述两种方式将使用源文件路径作为编译对象的输出文件夹。
ifdef O ifeq ("$(origin O)", "command line") BUILD_DIR := $(O) endif endif
通过$(origin O)判断是否 O变量来源于命令行,如果make O=/tmp/build all ,则BUILD_DIR := /tmp/build。
ifneq ($(BUILD_DIR),) //如果$(BUILD_DIR)不等于空 saved-output := $(BUILD_DIR) //saved-output := 等于BUILD_DIR的内容, # Attempt to create a output directory. $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}) //-d是判断BUILD_DIR是否存在。倘若不存在就创建。mkdir的-p参数代表若路径中的BUILD_DIR不存在就创建 # Verify if it was successful. //核查BUILD_DIR是否创建成功 BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd) //尝试进入BUILD_DIR 文件夹,如果能正常进入则将文件路劲赋值给BUILD_DIR 。 $(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))//判断BUILD_DIR 是否为空,为空将打印错误信息。 endif # ifneq ($(BUILD_DIR),)
判断几个表示文件路径的全局变量的值,是指定的外部文件路径还是当前目录路径:
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) //如果BUILD_DIR不为空,OBJTREE := $(BUILD_DIR)否则就是当前目录$(CURDIR) SRCTREE := $(CURDIR) TOPDIR := $(SRCTREE) LNDIR := $(OBJTREE) export TOPDIR SRCTREE OBJTREE //输出几个全局变量
MKCONFIG := $(SRCTREE)/mkconfig //指定MKCONFIG等于当前目录下的mkconfig
export MKCONFIG //输出MKCONFIG
mkconfig文件位于uboot根目录下,我们在make uboot之前要先配置,mkconfig文件执行配置内容,关于mkconfig的分析将在另一篇文章中表述。
ifneq ($(OBJTREE),$(SRCTREE)) //OBJTREE 和SRCTREE不相等REMOTE_BUILD := 1 REMOTE_BUILD := 1 export REMOTE_BUILD endif
# $(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.
//obj和src的定义也出现在了顶层目录的config.mk中,但在此文件被包含进来以前
//如果想使用unconfig clean, clobber, distclean,这些命令,需要将变量obj、src,提前包含进去。
ifneq ($(OBJTREE),$(SRCTREE)) //如果两个目录不相等 obj := $(OBJTREE)/ src := $(SRCTREE)/ else //否则都为空 obj := src := endif export obj src
加载配置命令make xxxx_config 后产生的 include/config.mk文件,
//config.mk主要是配置板级系统信息,用于uboot的make,config.mk如下: ARCH = arm CPU = arm920t BOARD = 100ask24x0 SOC = s3c24x0
然后输出 ARCH CPU BOARD VENDOR SOC等变量。在执行make all之前,首先要执行make xxxx_config,执行mkconfig脚本,可以确定所用cpu的架构(ARCH)例如arm ,cpu的种类(CPU)例如arm920t,开发板(BOARD)例如smdk2410 ,soc(SOC)例如 s3c24x0,这些信息保存在mkconfig脚本生成的makefile包含文件include/config.mk中。include/config.mk会被包含进入顶层makefile中,根据这个文件所定义的变量值,从而确定用那些文件(依赖),例如lib_arm/,board/smdk2410,cpu/arm920t等等。这是一种大方向上的裁剪方式
ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk)) # load ARCH, BOARD, and CPU configuration include $(OBJTREE)/include/config.mk export ARCH CPU BOARD VENDOR SOC
确定交叉编译工具链:
ifndef CROSS_COMPILE ifeq ($(HOSTARCH),ppc) CROSS_COMPILE = else ifeq ($(ARCH),ppc) CROSS_COMPILE = powerpc-linux- endif ifeq ($(ARCH),arm) CROSS_COMPILE = arm-linux- //$(ARCH) = arm 交叉编译工具链为arm-linux- endif
............
export CROSS_COMPILE //输出交叉工具链
包含顶层目录的config.mk
# load other configuration
include $(TOPDIR)/config.mk
加载OBJS对象:
OBJS = cpu/$(CPU)/start.o //加载cpu文件夹下的arm920t/start.o
给OBJ加上前缀:
OBJS := $(addprefix $(obj),$(OBJS))//#将$(obj)做为前缀添加在$(OBJS)中每个文件的前面 $(addprefix prefix,names)参数prefix是前缀 将其添加在names(names代表文件名 之间用空格隔开)的前面
根据config.mk中的ARCH = arm CPU = arm920t BOARD = 100ask24x0 SOC = s3c24x0 添加需要的库文件:
LIBS = lib_generic/libgeneric.a LIBS += board/$(BOARDDIR)/lib$(BOARD).a LIBS += cpu/$(CPU)/lib$(CPU).a ifdef SOC LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).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 += rtc/librtc.a LIBS += dtt/libdtt.a LIBS += drivers/libdrivers.a LIBS += drivers/nand/libnand.a LIBS += drivers/nand_legacy/libnand_legacy.a LIBS += drivers/usb/libusb.a LIBS += drivers/sk98lin/libsk98lin.a LIBS += common/libcommon.a LIBS += $(BOARDLIBS)
给LIBS加上obj前缀,定义LIBS为伪目标,添加GCC库
LIBS := $(addprefix $(obj),$(LIBS))
.PHONY : $(LIBS)
# Add GCC lib #添加GCC库
PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
伪目标SUBDIRS 用于执行tools、examples、post、post\cpu子目录下的make文件
# The "tools" are needed early, so put this first # Don't include stuff already done in $(LIBS) SUBDIRS = tools \ examples \ post \ post/cpu .PHONY : $(SUBDIRS) // .PHONY声明伪目
在执行make后的返回信息中可以看到此段代码的make过程,分别进入了tools、examples、post、post\cpu子目录下执行了该目录下的make文件:
for dir in tools examples post post/cpu ; do make -C $dir _depend ; done make[1]: Entering directory '/work/system/u-boot-1.1.6/tools' make[1]: Nothing to be done for '_depend'. make[1]: Leaving directory '/work/system/u-boot-1.1.6/tools' make[1]: Entering directory '/work/system/u-boot-1.1.6/examples' make[1]: Nothing to be done for '_depend'. make[1]: Leaving directory '/work/system/u-boot-1.1.6/examples' make[1]: Entering directory '/work/system/u-boot-1.1.6/post' make[1]: Nothing to be done for '_depend'. make[1]: Leaving directory '/work/system/u-boot-1.1.6/post' make[1]: Entering directory '/work/system/u-boot-1.1.6/post/cpu' make[1]: Nothing to be done for '_depend'. make[1]: Leaving directory '/work/system/u-boot-1.1.6/post/cpu' make -C tools all make[1]: Entering directory '/work/system/u-boot-1.1.6/tools' make[1]: Leaving directory '/work/system/u-boot-1.1.6/tools' make -C examples all make[1]: Entering directory '/work/system/u-boot-1.1.6/examples' make[1]: Nothing to be done for 'all'. make[1]: Leaving directory '/work/system/u-boot-1.1.6/examples' make -C post all make[1]: Entering directory '/work/system/u-boot-1.1.6/post' make[1]: Nothing to be done for 'all'. make[1]: Leaving directory '/work/system/u-boot-1.1.6/post' make -C post/cpu all make[1]: Entering directory '/work/system/u-boot-1.1.6/post/cpu' make[1]: Nothing to be done for 'all'. make[1]: Leaving directory '/work/system/u-boot-1.1.6/post/cpu'
若定义了CONFIG_NAND_U_BOOT,那么将总目标all中添加$(obj)u-boot-nand.bin,否则不添加
把$(obj)从$(OBJS)、$(LIBS)中删除 。 $(subst from,to,text) 在文本"text"中用"to"替换所有的"from"
ifeq ($(CONFIG_NAND_U_BOOT),y) NAND_SPL = nand_spl U_BOOT_NAND = $(obj)u-boot-nand.bin endif __OBJS := $(subst $(obj),,$(OBJS)) __LIBS := $(subst $(obj),,$(LIBS))
顶层Makefile的总目标all是一个伪目标,有几个分目标(目标文件)组成:(obj)u−boot.srec(obj)u−boot.srec(obj)u-boot.bin (obj)System.map(obj)System.map(U_BOOT_NAND)。
用户也可以添加其他目标,如(obj)u−boot.dis、(obj)u−boot.dis、(obj)u-boot.img、$(obj)u-boot.hex等等。由于是一个伪目标,所以只要输入命令make all,总会重建几个分目标。
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
在顶层目录的config.mk中:CROSS_COMPILE = arm-linux-
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
......
OBJCFLAGS += --gap-fill=0xff
all: $(ALL) $(obj)u-boot.hex: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
//arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec $(obj)u-boot.srec: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
//展开为arm-linux-objcopy--gap-fill=0xff -O binary u-boot u-boot.bin
//编译命令中的“-O binary”选项指定了输出的文件为二进制文件。而“--gap-fill=0xff”选项指定使用“0xff”填充段与段间的空闲区域。
//这条编译命令实现了ELF格式的U-Boot文件到BIN格式的转换。
$(obj)u-boot.bin: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
//uboot.img只是比uboot.bin多了个头,而这个头包括了如何/从哪里执行这个uboot.
//uboot.bin一般是按照具体地址烧写,而uboot.img则包含地址等信息,无需按照地址下载,所以这个也决定了uboot.bin适用于Norflash,而uboot.img更适合SD卡
$(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) | \ //将$(obj)include/version_autogenerated.h文件中的任意字符+U_BOOT_VERSION 替换成空 替换后是字符串"U-Boot 1.1.6" sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \ -d $< $@
//展开arm-linux-objdump -d uboot > uboot.dis 反汇编 $(obj)u-boot.dis: $(obj)u-boot $(OBJDUMP) -d $< > $@
$(obj)u-boot.bin依赖于$(obj)u-boot ,$(obj)u-boot 又依赖于depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT) UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\ cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \ -Map u-boot.map -o u-boot
depend依赖:
depend dep: //note:depend 和dep 是两个目标,执行的命令一样 for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done
依次进入$(SUBDIRS) 表示的子目录tools、examples、post、post\cpu中,并执行make _depend命令,生成各个子目录的.depend文件,在.depend文件中列出每个目标文件的依赖文件。
//make 执行过程:
for dir in tools examples post post/cpu ; do make -C $dir _depend ; done
关于_depend,位于根目录下的rules.mk。.depend依赖于 $(src)Makefile 、 $(TOPDIR)/config.mk 、 $(SRCS),然后执行命令,将 $(SRCS)中各个源文件的依赖关系取出放入到.depend文件,
属于Makefile自动生成依赖的一种做法。
_depend: $(obj).depend $(obj).depend: $(src)Makefile $(TOPDIR)/config.mk $(SRCS) @rm -f $@ @for f in $(SRCS); do \ g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \ //`basename`是在Makefile中使用shell命令,shell中的basename是去除掉文件前面的目录(路径)信息,
//比如/root/test.c变成test.c,sed -e 's/\(.*\)\.\w/\1.o/'是正则表达式用于匹配字符串和替换字符串 $(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \ done
关于sed -e 's/\(.*\)\.\w/\1.o/'
sed的替换命令,常见的是 s/正则表达搜索/替换为/
\(.*\)匹配任意字符,并且放在了捕获括号中,用来做后向引用的,\1 引用前面正则表达式中第一个捕获括号里面的内容
\.是一个点
\w用于匹配字母,数字或下划线字符;
作用:把文件扩展名的首个字符替换成o,比如lowlevel_init.s,被替换成lowlevel_init.o
关于$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ;
首先忽略$(HOST_CFLAGS) ,$(CPPFLAGS)。 $(HOST_CFLAGS)没有找到定义应该为空。
gcc -M -MQ $(obj)$$g $$f >> .depend 将g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; 转换好的.o文件和其他依赖文件($$f 即.s和.c)(如果有)一起追加到 .depend 中
最后一起包含进去
sinclude $(obj).depend
以 \u-boot-1.1.6\board\100ask24x0 目录下生成的依赖文件.depend为例子:
1 lowlevel_init.o: lowlevel_init.S \ 2 /work/system/u-boot-1.1.6/include/config.h \ 3 /work/system/u-boot-1.1.6/include/configs/100ask24x0.h \ 4 /work/system/u-boot-1.1.6/include/cmd_confdefs.h \ 5 /work/system/u-boot-1.1.6/include/version.h \ 6 /work/system/u-boot-1.1.6/include/version_autogenerated.h 7 100ask24x0.o: 100ask24x0.c /work/system/u-boot-1.1.6/include/common.h \ 8 /work/system/u-boot-1.1.6/include/config.h \ 9 /work/system/u-boot-1.1.6/include/configs/100ask24x0.h \ 10 /work/system/u-boot-1.1.6/include/cmd_confdefs.h \ 11 /work/system/u-boot-1.1.6/include/linux/bitops.h \ 12 /work/system/u-boot-1.1.6/include/asm/bitops.h \ 13 /work/system/u-boot-1.1.6/include/linux/types.h \ 14 /work/system/u-boot-1.1.6/include/linux/config.h \ 15 /work/system/u-boot-1.1.6/include/linux/posix_types.h \ 16 /work/system/u-boot-1.1.6/include/linux/stddef.h \ 17 /work/system/u-boot-1.1.6/include/asm/posix_types.h \ 18 /work/system/u-boot-1.1.6/include/asm/types.h \ 19 /work/system/u-boot-1.1.6/include/linux/string.h \ 20 /work/system/u-boot-1.1.6/include/asm/string.h \ 21 /work/system/u-boot-1.1.6/include/asm/ptrace.h \ 22 /work/system/u-boot-1.1.6/include/asm/proc/ptrace.h \ 23 /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/include/stdarg.h \ 24 /work/system/u-boot-1.1.6/include/part.h \ 25 /work/system/u-boot-1.1.6/include/ide.h \ 26 /work/system/u-boot-1.1.6/include/flash.h \ 27 /work/system/u-boot-1.1.6/include/image.h \ 28 /work/system/u-boot-1.1.6/include/asm/u-boot.h \ 29 /work/system/u-boot-1.1.6/include/asm/global_data.h \ 30 /work/system/u-boot-1.1.6/include/asm/mach-types.h \ 31 /work/system/u-boot-1.1.6/include/asm/setup.h \ 32 /work/system/u-boot-1.1.6/include/asm/u-boot-arm.h \ 33 /work/system/u-boot-1.1.6/include/s3c2410.h \ 34 /work/system/u-boot-1.1.6/include/s3c24x0.h 35 boot_init.o: boot_init.c /work/system/u-boot-1.1.6/include/common.h \ 36 /work/system/u-boot-1.1.6/include/config.h \ 37 /work/system/u-boot-1.1.6/include/configs/100ask24x0.h \ 38 /work/system/u-boot-1.1.6/include/cmd_confdefs.h \ 39 /work/system/u-boot-1.1.6/include/linux/bitops.h \ 40 /work/system/u-boot-1.1.6/include/asm/bitops.h \ 41 /work/system/u-boot-1.1.6/include/linux/types.h \ 42 /work/system/u-boot-1.1.6/include/linux/config.h \ 43 /work/system/u-boot-1.1.6/include/linux/posix_types.h \ 44 /work/system/u-boot-1.1.6/include/linux/stddef.h \ 45 /work/system/u-boot-1.1.6/include/asm/posix_types.h \ 46 /work/system/u-boot-1.1.6/include/asm/types.h \ 47 /work/system/u-boot-1.1.6/include/linux/string.h \ 48 /work/system/u-boot-1.1.6/include/asm/string.h \ 49 /work/system/u-boot-1.1.6/include/asm/ptrace.h \ 50 /work/system/u-boot-1.1.6/include/asm/proc/ptrace.h \ 51 /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/include/stdarg.h \ 52 /work/system/u-boot-1.1.6/include/part.h \ 53 /work/system/u-boot-1.1.6/include/ide.h \ 54 /work/system/u-boot-1.1.6/include/flash.h \ 55 /work/system/u-boot-1.1.6/include/image.h \ 56 /work/system/u-boot-1.1.6/include/asm/u-boot.h \ 57 /work/system/u-boot-1.1.6/include/asm/global_data.h \ 58 /work/system/u-boot-1.1.6/include/asm/mach-types.h \ 59 /work/system/u-boot-1.1.6/include/asm/setup.h \ 60 /work/system/u-boot-1.1.6/include/asm/u-boot-arm.h \ 61 /work/system/u-boot-1.1.6/include/s3c2410.h \ 62 /work/system/u-boot-1.1.6/include/s3c24x0.h
version
version: @echo -n "#define U_BOOT_VERSION \"U-Boot " > $(VERSION_FILE); \ echo -n "$(U_BOOT_VERSION)" >> $(VERSION_FILE); \ echo -n $(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion \ $(TOPDIR)) >> $(VERSION_FILE); \ echo "\"" >> $(VERSION_FILE)
$(SUBDIRS)依赖
# The "tools" are needed early, so put this first # Don't include stuff already done in $(LIBS) SUBDIRS = tools \ examples \ post \ post/cpu .PHONY : $(SUBDIRS)
$(SUBDIRS)目标执行:进入所有目标文件夹执行makefile文件
$(SUBDIRS):
$(MAKE) -C $@ all
LIBS依赖
LIBS = lib_generic/libgeneric.a LIBS += board/$(BOARDDIR)/lib$(BOARD).a LIBS += cpu/$(CPU)/lib$(CPU).a ifdef SOC LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).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 += rtc/librtc.a LIBS += dtt/libdtt.a LIBS += drivers/libdrivers.a LIBS += drivers/nand/libnand.a LIBS += drivers/nand_legacy/libnand_legacy.a LIBS += drivers/usb/libusb.a LIBS += drivers/sk98lin/libsk98lin.a LIBS += common/libcommon.a LIBS += $(BOARDLIBS) LIBS := $(addprefix $(obj),$(LIBS)) .PHONY : $(LIBS)
LIBS执行命令:依次进入LIBS目标文件夹 执行makefile ,
$(dir NAMES…)取目录函数,
$(subst FROM,TO,TEXT)
函数名称:字符串替换函数—subst。
函数功能:把字串“TEXT”中的“FROM ”字符替换为“TO”。
返回值:替换后的新字符串
$(LIBS):
$(MAKE) -C $(dir $(subst $(obj),,$@))
LDSCRIPT:
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds //board/100ask24x0/u-boot.lds