1 VERSION = 1            # 主版本号
2 PATCHLEVEL = 3        # 次版本号
3 SUBLEVEL = 4        # 次次版本号
4 EXTRAVERSION =        # 外部版本号
5 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)    #变量形式为:1.2.3.xx
6 VERSION_FILE = $(obj)include/version_autogenerated.h
1 HOSTARCH := $(shell uname -m | \    # | 表示管道,作用:将前一个的输出作为后一个的输入
2     sed -e s/i.86/i386/ \            # sed 是一个字符串替换的工具
3         -e s/sun4u/sparc64/ \        # -e表示在一行中执行多个sed命令,s表示用后面的信息替换前面的信息.
4         -e s/arm.*/arm/ \            # 例如:s/i.86/i386/,表示将 i.86 替换成 i386,
5         -e s/sa110/arm/ \            # shell uname -m 得到电脑的CPU版本号,为i686
6         -e s/powerpc/ppc/ 7         -e s/ppc64/ppc/ 8         -e s/macppc/ppc/)
1 HOSTOS := $(shell uname -s | tr ‘[:upper:]‘ ‘[:lower:]‘ | \        # shell uname -s 得到系统名 Linux
2         sed -e ‘s/\(cygwin\).*/cygwin/‘)                        # tr ‘[:upper:]‘ ‘[:lower:]‘ 把字符全部转换成小写,为 linux
3 
4 export    HOSTARCH HOSTOS
1 #########################################################################
2 # Allow for silent builds
3 ifeq (,$(findstring s,$(MAKEFLAGS)))    # findstring是一个函数,功能是从 $(MAKEFLAGS) 中查找字符 s
4 XECHO = echo                            # 如果没有找到,则打印编译信息
5 else            
6 XECHO = :                                # 如果没有找到,则把 XECHO设为空,不打印,从而实现静默编译
7 endif
8 
 1 #########################################################################
 2 #
 3 # U-boot build supports producing a object files to the separate external
 4 # directory. Two use cases are supported:
 5 #
 6 # 1) Add O= to the make command line
 7 # ‘make O=/tmp/build all‘
 8 #
 9 # 2) Set environement variable BUILD_DIR to point to the desired location
10 # ‘export BUILD_DIR=/tmp/build‘
11 # ‘make‘
12 #
13 # The second approach can also be used with a MAKEALL script
14 # ‘export BUILD_DIR=/tmp/build‘
15 # ‘./MAKEALL‘
16 #
17 # Command line ‘O=‘ setting overrides BUILD_DIR environent variable.
18 #
19 # When none of the above methods is used the local build is performed and
20 # the object files are placed in the source directory.
21 #
1 ifdef O
2 ifeq ("$(origin O)", "command line")    # $(origin O) 中origin是函数名,$(origin O)的功能是返回变量O的来源
3 BUILD_DIR := $(O)                        # 如果make时输入:make O=/tmp/build,那么makefile会认为定义了变量O,
4 endif                                    # $(O) 的值为:/tmp/build
5 endif
6 
7 ifneq ($(BUILD_DIR),)                    # 如果变量BUILD_DIR不为空,
8 saved-output := $(BUILD_DIR)            # 则变量saved-output的值为BUILD_DIR,即saved-output的值也是输出文件夹路径
1 # Attempt to create a output directory.
2 $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})    # 如果该文件夹不存在,则创建 $(BUILD_DIR)
1 # Attempt to create a output directory.
2 $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})    # 如果该文件夹不存在,则创建 $(BUILD_DIR)
3 
4 # Verify if it was successful.
5 BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)        # 确保输出文件夹路径创建成功,&&的功能是连续执行两句语句,
6                                                         # 当cd $(BUILD_DIR)执行完后,调用pwd命令,即打印当前路径赋值给BUILD_DIR;
7 
8 $(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))    # $(if xxx,yyy,zzz)是makefile的判断函数,
9 endif # ifneq ($(BUILD_DIR),)                                                    # 如果xxx为真,则执行yyy并返回值,否则执行zzz并返回值,
1 OBJTREE        := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))# 将来要编译的.o文件的目录,即输出目录
2 SRCTREE        := $(CURDIR)                                # 要编译的源代码的目录,CURDIR(即current direction,当前源码所在的目录)
3 TOPDIR        := $(SRCTREE)                                # TOPDIR 的值为 SRCTREE 的值即当前源码所在目录
4 LNDIR        := $(OBJTREE)                                # LNDIR(应该是放链接产生的文件)的值和OBJTREE相同
5 export    TOPDIR SRCTREE OBJTREE
1 MKCONFIG    := $(SRCTREE)/mkconfig                        # CURIDR变量,这是一个MAKEFILE的内嵌变量,代表当前路径,将变量MKCONFIG的
2 export MKCONFIG                                            # 值设置为当前源码目录下的mkconfig文件,并将其导出至全局
 1 # $(obj) and (src) are defined in config.mk but here in main Makefile
 2 # we also need them before config.mk is included which is the case for
 3 # some targets like unconfig, clean, clobber, distclean, etc.
 4 ifneq ($(OBJTREE),$(SRCTREE))                            # 判断 $(OBJTREE) 与 $(SRCTREE) 是否相等
 5 obj := $(OBJTREE)/
 6 src := $(SRCTREE)/
 7 else
 8 obj :=
 9 src :=
10 endif
11 export obj src
12 
13 # Make sure CDPATH settings don‘t interfere
14 unexport CDPATH
1 # $2:= arm
2 # $3:= s5pc11x
3 # $4:= x210
4 # $5:= samsumg
5 # $6:= s5pc11x
 1 ifeq ($(ARCH),powerpc)    # 这三句是powerpc架构的名称转换
 2 ARCH = ppc
 3 endif
 4 
 5 # $(wildcard xxx) 参数xxx是一个文件名格式(可使用通配符),这个函数的返回值是一列和格式匹配且真实存在的文件的名称。
 6 # 但是这句应该没什么意义,因为连endif都没有
 7 ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
 8 
 9 # load ARCH, BOARD, and CPU configuration
10 include $(obj)include/config.mk                            # config.mk这个文件其实uboot源码中是不存在的,它是由配
11 export    ARCH CPU BOARD VENDOR SOC                        # 置过程中由mkconfig这个脚本创建的,他们的值在后面会设
1 x210_sd_config :    unconfig
2     @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
3     @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
 1 ifndef CROSS_COMPILE                                    # ARCH 的值,会直接影响 CROSS_COMPILE 的值
 2 ifeq ($(HOSTARCH),$(ARCH))
 3 CROSS_COMPILE =
 4 else
 5 ifeq ($(ARCH),ppc)
 6 CROSS_COMPILE = ppc_8xx-
 7 endif
 8 ifeq ($(ARCH),arm)                                        # 由 ARCH 来确定 CROSS_COMPILE 的值
 9 #CROSS_COMPILE = arm-linux-                    # 如果linux中的交叉编译工具链导出到环境变量,并设置了符号链接,则可以用此方法
10 #CROSS_COMPILE = /usr/local/arm/4.4.1-eabi-cortex-a8/usr/bin/arm-linux-
11 #CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
12 CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
13 endif
$(TOPDIR)/config.mk(185行)
1 export    CROSS_COMPILE
2 
3 # load other configuration
4 include $(TOPDIR)/config.mk        # 导入TOPDIR路径下的config.mk文件(将另一个Makefile文件导入,将在原地展开)
 1 #
 2 # Include the make variables (CC, etc...)
 3 #
 4 AS    = $(CROSS_COMPILE)as                # 汇编工具 
 5 LD    = $(CROSS_COMPILE)ld                # 链接工具
 6 CC    = $(CROSS_COMPILE)gcc                # 编译工具
 7 CPP    = $(CC) -E                            # 预处理
 8 AR    = $(CROSS_COMPILE)ar                # 归档工具
 9 NM    = $(CROSS_COMPILE)nm                # 列出object文件中的符号
10 LDR    = $(CROSS_COMPILE)ldr                # 
11 STRIP    = $(CROSS_COMPILE)strip            # 
12 OBJCOPY = $(CROSS_COMPILE)objcopy        # 转换可执行文件格式工具
13 OBJDUMP = $(CROSS_COMPILE)objdump        # 反汇编工具 
14 RANLIB    = $(CROSS_COMPILE)RANLIB        # 产生归档文件索引
 1 #########################################################################
 2 
 3 # Load generated board configuration
 4 sinclude $(OBJTREE)/include/autoconf.mk
 5 
 6 ifdef    ARCH
 7 sinclude $(TOPDIR)/$(ARCH)_config.mk    # include architecture dependend rules
 8 endif
 9 ifdef    CPU
10 sinclude $(TOPDIR)/cpu/$(CPU)/config.mk    # include  CPU    specific rules
11 endif
12 ifdef    SOC
13 sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk    # include  SoC    specific rules
14 endif
15 ifdef    VENDOR
16 BOARDDIR = $(VENDOR)/$(BOARD)
17 else
18 BOARDDIR = $(BOARD)
19 endif
20 ifdef    BOARD
21 sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk    # include board specific rules
22 endif
23 
24 #########################################################################
1 ifndef LDSCRIPT
2 #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
3 ifeq ($(CONFIG_NAND_U_BOOT),y)                                # 在autoconfig.h中查找,其中并没有这个定义,我们用的是inand
4 LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
5 else
6 LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
7 endif
8 endif
1 x210_sd_config :    unconfig
2     @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
3     @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
 1 #########################################################################
 2 
 3 ifndef REMOTE_BUILD
 4 
 5 %.s:    %.S
 6     $(CPP) $(AFLAGS) -o $@ $<
 7 %.o:    %.S
 8     $(CC) $(AFLAGS) -c -o $@ $<
 9 %.o:    %.c
10     $(CC) $(CFLAGS) -c -o $@ $<
11 
12 else
13 
14 $(obj)%.s:    %.S
15     $(CPP) $(AFLAGS) -o $@ $<
16 $(obj)%.o:    %.S
17     $(CC) $(AFLAGS) -c -o $@ $<
18 $(obj)%.o:    %.c
19     $(CC) $(CFLAGS) -c -o $@ $<
20 endif
 1 x210_nand_config :    unconfig
 2     @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
 3     @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
 4 
 5 x210_sd_config :    unconfig
 6     @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
 7     @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
 8 
 9 smdkv210single_rev02_config :    unconfig
10     @$(MKCONFIG) $(@:_config=) arm s5pc11x smdkc110 samsung s5pc110
11     @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/smdkc110/config.mk
1 unconfig:
2     @rm -f $(obj)include/config.h $(obj)include/config.mk 3         $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp 4         $(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep 5         $(obj)board/$(VENDOR)/$(BOARD)/config.mk
1 x210_sd_config :    unconfig
2     @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
3     @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
 1 APPEND=no    # Default: Create new config file
 2 BOARD_NAME=""    # Name to print in make output
 3 
 4 while [ $# -gt 0 ] ; do
 5     case "$1" in
 6     --) shift ; break ;;
 7     -a) shift ; APPEND=yes ;;
 8     -n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
 9     *)  break ;;                                    # 跳出while循环
10     esac
11 done
1 [ "${BOARD_NAME}" ] || BOARD_NAME="$1"                # BOARD_NAME 为空,给 BOARD_NAME 赋值为 x210_sd
2 
3 [ $# -lt 4 ] && exit 1                                # 如果 $# 的值小于4 或大于6,则退出mkconfig,返回1
4 [ $# -gt 6 ] && exit 1                                # exit 退出程序并返回一个值
 1 if [ "$SRCTREE" != "$OBJTREE" ] ; then
 2     mkdir -p ${OBJTREE}/include
 3     mkdir -p ${OBJTREE}/include2
 4     cd ${OBJTREE}/include2
 5     rm -f asm
 6     ln -s ${SRCTREE}/include/asm-$2 asm
 7     LNPREFIX="../../include2/asm/"
 8     cd ../include
 9     rm -rf asm-$2
10     rm -f asm
11     mkdir asm-$2
12     ln -s asm-$2 asm                                # 在include目录下创建asm文件,指向asm-arm
13 else                                                # 默认路径下编译
14     cd ./include
15     rm -f asm
16     ln -s asm-$2 asm                                # # 在include目录下创建asm文件,指向asm-arm
17 fi
创建的符号链接:
1 else                                                # 默认路径下编译
2     cd ./include
3     rm -f asm
4     ln -s asm-$2 asm                                # # 在include目录下创建asm文件,指向asm-arm
5 fi
1 rm -f asm-$2/arch
2 
3 if [ -z "$6" -o "$6" = "NULL" ] ; then
4     ln -s ${LNPREFIX}arch-$3 asm-$2/arch
5 else
6     ln -s ${LNPREFIX}arch-$6 asm-$2/arch            # 在inlcude/asm-arm下创建一个arch文件,指向include/asm-arm/arch-s5pc110
7 fi
1 # create link for s5pc11x SoC
2 if [ "$3" = "s5pc11x" ] ; then
3         rm -f regs.h
4         ln -s $6.h regs.h                            # ln -s ${LNPREFIX}arch-$6 asm-$2/arch
5         rm -f asm-$2/arch                            # 删除 62行 创建的arch  
6         ln -s arch-$3 asm-$2/arch                    # 在include目录下创建regs.h文件,指向include/s5pc110.h
7 fi
1 if [ "$2" = "arm" ] ; then
2     rm -f asm-$2/proc
3     ln -s ${LNPREFIX}proc-armv asm-$2/proc            # 在include/asm-arm下创建一个proc文件,指向include/asm-arm/proc-armv
4 fi
 1 #
 2 # Create include file for Make
 3 #
 4 echo "ARCH   = $2" >  config.mk                                        # ARCH   = $2 = arm
 5 echo "CPU    = $3" >> config.mk                                        # CPU    = $3 = s5pc11x
 6 echo "BOARD  = $4" >> config.mk                                        # BOARD  = $4 = x210
 7 
 8 [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk    # VENDOR = $5 = samsung
 9 
10 [ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk    # SOC    = $6 = s5pc110
 1 #
 2 # Create board specific header file
 3 #
 4 if [ "$APPEND" = "yes" ]    # Append to existing config file
 5 then
 6     echo >> config.h
 7 else
 8     > config.h        # Create new config file
 9 fi
10 echo "/* Automatically generated - do not edit */" >>config.h
11 echo "#include <configs/$1.h>" >>config.h
12 
13 exit 0
1 ifeq ($(CONFIG_NAND_U_BOOT),y)                                # 在autoconfig.h中查找,其中并没有这个定义,我们用的是inand
2 LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
3 else
4 LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
5 endif
6 endif
1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")    
2 /*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
3 OUTPUT_ARCH(arm)                        // 输出架构
4 ENTRY(_start)                            // 用来指定整个程序的入口地址,相当于c语言中的mian()
1 x210_sd_config :    unconfig
2     @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
3     @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
 1 .text      :                        // 代码段
 2     {
 3       cpu/s5pc11x/start.o    (.text)
 4       cpu/s5pc11x/s5pc110/cpu_init.o    (.text)
 5       board/samsung/x210/lowlevel_init.o    (.text)
 6           cpu/s5pc11x/onenand_cp.o      (.text)                 
 7           cpu/s5pc11x/nand_cp.o (.text)                     
 8           cpu/s5pc11x/movi.o (.text) 
 9           common/secure_boot.o (.text) 
10       common/ace_sha1.o (.text)
11       cpu/s5pc11x/pmic.o (.text)        // 前16K的程序中用到的文件,必须放在前面,优先编译
12       *(.text)
13     }
 1  = ALIGN(4);
 2     .rodata : { *(.rodata) }            // 只读数据段
 3 
 4     . = ALIGN(4);
 5     .data : { *(.data) }                // 普通数据段
 6 
 7     . = ALIGN(4);
 8     .got : { *(.got) }                    // 自定义段
 9 
10     __u_boot_cmd_start = .;
11     .u_boot_cmd : { *(.u_boot_cmd) }    // 自定义段
12     __u_boot_cmd_end = .;
13 
14     . = ALIGN(4);
15     .mmudata : { *(.mmudata) }            // 自定义段
原文:http://www.cnblogs.com/icefree/p/7696820.html