-----------------九鼎x210开发板的Uboot学习笔记------------------
------------------------------------------------
-----------------主Makefile分析-----------------
------------------------------------------------
1: 主Makefile分析
(1)第一部分:确定了Uboot的版本号
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 4
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
#version_autogenerated.h 经过编译后才会有 内容是一个宏定义 宏定义的值就是我们配置的uboot的版本号
#U_BOOT_VERSION=1.3.4XYZ 最终版本号
(2)第二部分:得到CPU架构 并且将内核版本统一为i386
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/)
#shell中的|叫做管道 作用是将前一个式子的输出作为后一个式子的输入再进行处理。
#例如第一个-e s/i.86/i386/ .是万能匹配符 意思就是将得到的 i.86全部替换成 i386
#在这里使各种cpu版本统一
#HOSTARCH这个名字:HOST是主机,就是当前在做开发用的这台电脑就叫主机;ARCH是architecture(架构)的缩写,表示CPU的架构。所以HOSTARCH就表示主机的CPU的架构。
(3)第三部分:得到HOSTOS即内核版本号 并将其由大写转为小写 导出为外部变量
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
export HOSTARCH HOSTOS
(4)第四部分:实现 make -s 静默编译
# Allow for silent builds
#如果编译时make后面不加s则 XECHO =echo
#MAKEFLAGS是我们输入的环境变量
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
(5)第五部分:实现 make -O=BUILD_DIR 输出文件夹编译 或者是 原地编译
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
# 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),)
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
#LNDIR/OBJTREE:编译出的.o文件的根目录(默认下等于当前目录)。TOPDIR/SRCTREE源码目录,也就是makefile所在的目录。(在默认编译下二者相等 在O=XXX下二者不相等)
(6)第六部分:包含主目录下的mkconfig
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
(7)第七部分:为确保万一 在这里再次定义obj src
# $(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
总结: 虽然在TOPDIR下的config.mk中已经进行了定义 但为了确保万一 在这里进行处理
(8)第八部分:再次确定排除 CDPATH的干扰
unexport CDPATH
(9)第九部分:根据ARCH(cpu的架构)确定编译链接工具的前缀(前缀在安装交叉编译工具链时已经完成前期工作)
#这里进入($(ARCH),arm)进程;最终CROSS_COMPILE = CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi- 然后导出
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
总结:
CROSS_COMPILE在源码的136-182行来确定。CROSS_COMPILE是被ARCH所确定的,只要配置了ARCH=arm,那么我们就只能在ARM的那个分支去设置CROSS_COMPILE的值。这个设置值只要能保证找到那个交叉编译工具链即可,不一定非得是全路径的,相对路径也可以。(如果已经将工具链导出到环境变量,并且设置了符号链接,这样CROSS_COMPILE = arm-linux-就可以)
实际运用时,我们可以在Makefile中去更改设置CROSS_COMPILE的值,也可以在编译时用make CROSS_COMPILE=xxxx来设置,而且编译时传参的方法可以覆盖Makefile里面的设置。
(10)第十部分:包含TOPDIR下的config.mk
# load other configuration
include $(TOPDIR)/config.mk
(11)第十一部分:根据指定的CPU,确定最先编译的是 start.S文件
#########################################################################
# U-Boot objects....order is important (i.e. start must be first)
OBJS = cpu/$(CPU)/start.o
(12) 第十二部分:针对不同的CPU、开发板,调用它们各自目录下的Makefile生成相应的库。
(13) 第十三部分:unconfig部分 unconfig是一个伪目标 后面会多次调用者个伪目标
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep \
$(obj)board/$(VENDOR)/$(BOARD)/config.mk
#使我们配置过一次开发板后 还能继续配置
(14) 第十三部分:实现x210_sd_config
x210_sd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
#TEXT_BASE 是将来uboot下载的内存地址 (这里是一个虚拟地址 映射到 23E00000)
#$(mkconfig) 表明调用了 mkconfig脚本 $@ 表示makefile中的目标 在这里也就是指代 x210_sd_config
# : 表示依赖 _config= 表示第一个参数 也就是将x210_sd_config中的_config用空代替 得到第一个参数 x210_sd
$0 ./mkconfig
$1 x210_sd
$2 arm
$3 s5pc11x
$4 x210
$5 samsung
$6 s5pc110
(14) make distclean:清除上次make生成的文件
clean:
@rm -f $(obj)examples/82559_eeprom $(obj)examples/eepro100_eeprom \
$(obj)examples/hello_world $(obj)examples/interrupt \
$(obj)examples/mem_to_mem_idma2intr \
$(obj)examples/sched $(obj)examples/smc91111_eeprom \
$(obj)examples/test_burst $(obj)examples/timer
@rm -f $(obj)tools/bmp_logo $(obj)tools/easylogo/easylogo \
$(obj)tools/env/{fw_printenv,fw_setenv} \
$(obj)tools/envcrc \
$(obj)tools/gdb/{astest,gdbcont,gdbsend} \
$(obj)tools/gen_eth_addr $(obj)tools/img2srec \
$(obj)tools/mkimage $(obj)tools/mpc86x_clk \
$(obj)tools/ncb $(obj)tools/ubsha1
@rm -f $(obj)board/cray/L1/{bootscript.c,bootscript.image} \
$(obj)board/netstar/{eeprom,crcek,crcit,*.srec,*.bin} \
$(obj)board/trab/trab_fkt $(obj)board/voiceblue/eeprom \
$(obj)board/{integratorap,integratorcp}/u-boot.lds \
$(obj)board/{bf533-ezkit,bf533-stamp,bf537-stamp,bf561-ezkit}/u-boot.lds \
$(obj)cpu/blackfin/bootrom-asm-offsets.[chs]
@rm -f $(obj)include/bmp_logo.h
@rm -f $(obj)nand_spl/{u-boot-spl,u-boot-spl.map,System.map}
@rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map}
@rm -f $(obj)api_examples/demo $(VERSION_FILE)
@find $(OBJTREE) -type f \
\( -name 'core' -o -name '*.bak' -o -name '*~' \
-o -name '*.o' -o -name '*.a' \) -print \
| xargs rm -f
clobber: clean
@find $(OBJTREE) -type f \( -name .depend \
-o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \
-print0 \
| xargs -0 rm -f
@rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
$(obj)cscope.* $(obj)*.*~
@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
@rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,md5.c,sha1.c,inca-swap-bytes}
@rm -f $(obj)tools/{image.c,fdt.c,fdt_ro.c,fdt_rw.c,fdt_strerror.c,zlib.h}
@rm -f $(obj)tools/{fdt_wip.c,libfdt_internal.h}
@rm -f $(obj)cpu/mpc824x/bedbug_603e.c
@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
@rm -f $(obj)include/regs.h
@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
@[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -lname "*" -print | xargs rm -f
@[ ! -d $(obj)api_examples ] || find $(obj)api_examples -lname "*" -print | xargs rm -f
ifeq ($(OBJTREE),$(SRCTREE))
mrproper \
distclean: clobber unconfig
else
mrproper \
distclean: clobber unconfig
rm -rf $(obj)*
endif
总结: distclean调用 clobber unconfig 这两个伪目标
uboot主目录下的makefile总结 :主makefile 实现了
(1)确定uboot版本号
(2)到CPU架构 并且将内核版本统一为i386
(3)得到HOSTOS即内核版本号 并将其由大写转为小写 导出为外部变量
(4)实现 make -s 静默编译
(5)实现 make -O=BUILD_DIR 输出文件夹编译 或者是 原地编译
(6)包含主目录下的mkconfig
(7)为确保万一 在这里再次定义obj src
(8)再次确定排除 CDPATH的干扰
(9)根据ARCH(cpu的架构)确定编译链接工具的前缀(前缀在安装交叉编译工具链时已经完成前期工作)
(10)包含TOPDIR目录下的config.mk
(11)根据指定的CPU,确定最先编译的是 start.S文件
(12)针对不同的CPU、开发板,调用它们各自目录下的Makefile生成相应的库。
(13)实现x210_sd_config
(14)make distclean:清除上次make生成的文件
主makefile包含了主目录下的mkconfig和config.mk 同时也包含了include下的config.mk 和 autoconf.mk.dep
(1)sinclude $(obj)include/autoconf.mk.dep
(2)MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
(3)include $(obj)include/config.mk
(4)include $(TOPDIR)/config.mk
------------------------------------------------
-----------------主mkconfig分析-----------------
------------------------------------------------
2: 主目录下的mkconfig分析
首先明确 : 主makefile实现x210_sd_config部分便将$1~$6 传入了mkconfig中
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
shift命令: 变量号码偏移功能,简单来说就是移动变量
(1)根据穿入的变量选择执行的路径,并存到./include/config.mk文件中
#由46行可知 这是在 ./include路径下进行操作
# Create include file for Make
#一个 > 是创建文件 >>是追加文件
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
(2)建立板相关的 ./include/config.h文件
#由46行可知 这是在 ./include路径下进行操作
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h
(3)建立指向其他文件的软链接(软连接又叫符号链接: ln -s创建 其本质是一个文件,文件中的内容是指向文件的路径名 硬链。硬链接由ln命令创建 就是传统意义上的链接 可以一个指向多个文件)
-------------------------------------------------
-----------------主config.mk分析-----------------
-------------------------------------------------
3: 主目录下的config.mk分析
(1)确定生成可执行文件过程中需要的各种工具,如编译器(arm-linux-gcc)、连接器(arm-linux-ld)、反汇编器(arm-linux-objdump)等
ifeq ($(ARCH),arm)
ifeq ($(CROSS_COMPILE),powerpc-netbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
endif
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
(2)确定CPU、板相关的配置文件,存在于各个目录下的config.mk
# Load generated board configuration
sinclude $(OBJTREE)/include/autoconf.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
(3)确定编译、链接、转换等过程的操作选项
(4)根据步骤3确定的编译连接选项生成需要的文件
------------------------------------------------
-----------------主Makefile分析-----------------
------------------------------------------------
1: 主Makefile分析
(1)第一部分:确定了Uboot的版本号
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 4
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
#version_autogenerated.h 经过编译后才会有 内容是一个宏定义 宏定义的值就是我们配置的uboot的版本号
#U_BOOT_VERSION=1.3.4XYZ 最终版本号
(2)第二部分:得到CPU架构 并且将内核版本统一为i386
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/)
#shell中的|叫做管道 作用是将前一个式子的输出作为后一个式子的输入再进行处理。
#例如第一个-e s/i.86/i386/ .是万能匹配符 意思就是将得到的 i.86全部替换成 i386
#在这里使各种cpu版本统一
#HOSTARCH这个名字:HOST是主机,就是当前在做开发用的这台电脑就叫主机;ARCH是architecture(架构)的缩写,表示CPU的架构。所以HOSTARCH就表示主机的CPU的架构。
(3)第三部分:得到HOSTOS即内核版本号 并将其由大写转为小写 导出为外部变量
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
export HOSTARCH HOSTOS
(4)第四部分:实现 make -s 静默编译
# Allow for silent builds
#如果编译时make后面不加s则 XECHO =echo
#MAKEFLAGS是我们输入的环境变量
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
(5)第五部分:实现 make -O=BUILD_DIR 输出文件夹编译 或者是 原地编译
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
# 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),)
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
#LNDIR/OBJTREE:编译出的.o文件的根目录(默认下等于当前目录)。TOPDIR/SRCTREE源码目录,也就是makefile所在的目录。(在默认编译下二者相等 在O=XXX下二者不相等)
(6)第六部分:包含主目录下的mkconfig
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
(7)第七部分:为确保万一 在这里再次定义obj src
# $(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
总结: 虽然在TOPDIR下的config.mk中已经进行了定义 但为了确保万一 在这里进行处理
(8)第八部分:再次确定排除 CDPATH的干扰
unexport CDPATH
(9)第九部分:根据ARCH(cpu的架构)确定编译链接工具的前缀(前缀在安装交叉编译工具链时已经完成前期工作)
#这里进入($(ARCH),arm)进程;最终CROSS_COMPILE = CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi- 然后导出
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
总结:
CROSS_COMPILE在源码的136-182行来确定。CROSS_COMPILE是被ARCH所确定的,只要配置了ARCH=arm,那么我们就只能在ARM的那个分支去设置CROSS_COMPILE的值。这个设置值只要能保证找到那个交叉编译工具链即可,不一定非得是全路径的,相对路径也可以。(如果已经将工具链导出到环境变量,并且设置了符号链接,这样CROSS_COMPILE = arm-linux-就可以)
实际运用时,我们可以在Makefile中去更改设置CROSS_COMPILE的值,也可以在编译时用make CROSS_COMPILE=xxxx来设置,而且编译时传参的方法可以覆盖Makefile里面的设置。
(10)第十部分:包含TOPDIR下的config.mk
# load other configuration
include $(TOPDIR)/config.mk
(11)第十一部分:根据指定的CPU,确定最先编译的是 start.S文件
#########################################################################
# U-Boot objects....order is important (i.e. start must be first)
OBJS = cpu/$(CPU)/start.o
(12) 第十二部分:针对不同的CPU、开发板,调用它们各自目录下的Makefile生成相应的库。
(13) 第十三部分:unconfig部分 unconfig是一个伪目标 后面会多次调用者个伪目标
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep \
$(obj)board/$(VENDOR)/$(BOARD)/config.mk
#使我们配置过一次开发板后 还能继续配置
(14) 第十三部分:实现x210_sd_config
x210_sd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
#TEXT_BASE 是将来uboot下载的内存地址 (这里是一个虚拟地址 映射到 23E00000)
#$(mkconfig) 表明调用了 mkconfig脚本 $@ 表示makefile中的目标 在这里也就是指代 x210_sd_config
# : 表示依赖 _config= 表示第一个参数 也就是将x210_sd_config中的_config用空代替 得到第一个参数 x210_sd
$0 ./mkconfig
$1 x210_sd
$2 arm
$3 s5pc11x
$4 x210
$5 samsung
$6 s5pc110
(14) make distclean:清除上次make生成的文件
clean:
@rm -f $(obj)examples/82559_eeprom $(obj)examples/eepro100_eeprom \
$(obj)examples/hello_world $(obj)examples/interrupt \
$(obj)examples/mem_to_mem_idma2intr \
$(obj)examples/sched $(obj)examples/smc91111_eeprom \
$(obj)examples/test_burst $(obj)examples/timer
@rm -f $(obj)tools/bmp_logo $(obj)tools/easylogo/easylogo \
$(obj)tools/env/{fw_printenv,fw_setenv} \
$(obj)tools/envcrc \
$(obj)tools/gdb/{astest,gdbcont,gdbsend} \
$(obj)tools/gen_eth_addr $(obj)tools/img2srec \
$(obj)tools/mkimage $(obj)tools/mpc86x_clk \
$(obj)tools/ncb $(obj)tools/ubsha1
@rm -f $(obj)board/cray/L1/{bootscript.c,bootscript.image} \
$(obj)board/netstar/{eeprom,crcek,crcit,*.srec,*.bin} \
$(obj)board/trab/trab_fkt $(obj)board/voiceblue/eeprom \
$(obj)board/{integratorap,integratorcp}/u-boot.lds \
$(obj)board/{bf533-ezkit,bf533-stamp,bf537-stamp,bf561-ezkit}/u-boot.lds \
$(obj)cpu/blackfin/bootrom-asm-offsets.[chs]
@rm -f $(obj)include/bmp_logo.h
@rm -f $(obj)nand_spl/{u-boot-spl,u-boot-spl.map,System.map}
@rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map}
@rm -f $(obj)api_examples/demo $(VERSION_FILE)
@find $(OBJTREE) -type f \
\( -name 'core' -o -name '*.bak' -o -name '*~' \
-o -name '*.o' -o -name '*.a' \) -print \
| xargs rm -f
clobber: clean
@find $(OBJTREE) -type f \( -name .depend \
-o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \
-print0 \
| xargs -0 rm -f
@rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
$(obj)cscope.* $(obj)*.*~
@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
@rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,md5.c,sha1.c,inca-swap-bytes}
@rm -f $(obj)tools/{image.c,fdt.c,fdt_ro.c,fdt_rw.c,fdt_strerror.c,zlib.h}
@rm -f $(obj)tools/{fdt_wip.c,libfdt_internal.h}
@rm -f $(obj)cpu/mpc824x/bedbug_603e.c
@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
@rm -f $(obj)include/regs.h
@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
@[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -lname "*" -print | xargs rm -f
@[ ! -d $(obj)api_examples ] || find $(obj)api_examples -lname "*" -print | xargs rm -f
ifeq ($(OBJTREE),$(SRCTREE))
mrproper \
distclean: clobber unconfig
else
mrproper \
distclean: clobber unconfig
rm -rf $(obj)*
endif
总结: distclean调用 clobber unconfig 这两个伪目标
uboot主目录下的makefile总结 :主makefile 实现了
(1)确定uboot版本号
(2)到CPU架构 并且将内核版本统一为i386
(3)得到HOSTOS即内核版本号 并将其由大写转为小写 导出为外部变量
(4)实现 make -s 静默编译
(5)实现 make -O=BUILD_DIR 输出文件夹编译 或者是 原地编译
(6)包含主目录下的mkconfig
(7)为确保万一 在这里再次定义obj src
(8)再次确定排除 CDPATH的干扰
(9)根据ARCH(cpu的架构)确定编译链接工具的前缀(前缀在安装交叉编译工具链时已经完成前期工作)
(10)包含TOPDIR目录下的config.mk
(11)根据指定的CPU,确定最先编译的是 start.S文件
(12)针对不同的CPU、开发板,调用它们各自目录下的Makefile生成相应的库。
(13)实现x210_sd_config
(14)make distclean:清除上次make生成的文件
主makefile包含了主目录下的mkconfig和config.mk 同时也包含了include下的config.mk 和 autoconf.mk.dep
(1)sinclude $(obj)include/autoconf.mk.dep
(2)MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
(3)include $(obj)include/config.mk
(4)include $(TOPDIR)/config.mk
------------------------------------------------
-----------------主mkconfig分析-----------------
------------------------------------------------
2: 主目录下的mkconfig分析
首先明确 : 主makefile实现x210_sd_config部分便将$1~$6 传入了mkconfig中
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
shift命令: 变量号码偏移功能,简单来说就是移动变量
(1)根据穿入的变量选择执行的路径,并存到./include/config.mk文件中
#由46行可知 这是在 ./include路径下进行操作
# Create include file for Make
#一个 > 是创建文件 >>是追加文件
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
(2)建立板相关的 ./include/config.h文件
#由46行可知 这是在 ./include路径下进行操作
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h
(3)建立指向其他文件的软链接(软连接又叫符号链接: ln -s创建 其本质是一个文件,文件中的内容是指向文件的路径名 硬链。硬链接由ln命令创建 就是传统意义上的链接 可以一个指向多个文件)
-------------------------------------------------
-----------------主config.mk分析-----------------
-------------------------------------------------
3: 主目录下的config.mk分析
(1)确定生成可执行文件过程中需要的各种工具,如编译器(arm-linux-gcc)、连接器(arm-linux-ld)、反汇编器(arm-linux-objdump)等
ifeq ($(ARCH),arm)
ifeq ($(CROSS_COMPILE),powerpc-netbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
PLATFORM_CPPFLAGS+= -D__ARM__
endif
endif
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
(2)确定CPU、板相关的配置文件,存在于各个目录下的config.mk
# Load generated board configuration
sinclude $(OBJTREE)/include/autoconf.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
(3)确定编译、链接、转换等过程的操作选项
(4)根据步骤3确定的编译连接选项生成需要的文件