tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——配置过程(一)

          刚开拿到u-boot源码,我首先想到看的是readme文件,但这个文件很长且我英文水平有限,只能大概的了解他的意思:介绍了 u-boot 的历史, 版本命名规则, 目录组织架构,软件配置,如何添加一个新的板子等。对于linux下的工程,编译配置的开始肯定是根目录下的makefile , 但对于makefile我也只是了解基本的知识,所以开始之前,我又去恶补了一下makfile相关的知识,下面的分析会对makefile规则进行解释,现在正式开始分析:

       对u-boot-2014.04源代码解压,打开根目录下的makefile,从上至下开始:(第8-12行)

VERSION = 2014
PATCHLEVEL = 04
SUBLEVEL =
EXTRAVERSION =
NAME =

     定义了几个变量,从字面上看应该是跟u-boot的版本有关。( 第20-24行

# Do not:
# o  use make's built-in rules and variables
#    (this increases performance and avoids hard-to-debug behaviour);
# o  print "Entering directory ...";
MAKEFLAGS += -rR --no-print-directory

    操作符“+=”的作用是给变量(“+=”前面的MAKEFLAGS)追加值。如果变量(“+=”前面的MAKEFLAGS)之前没有定义过,那么,“+=”会自动变成“=”; 如果前面有变量(“+=”前面的MAKEFLAGS)定义,那么“+=”会继承于前次操作的赋值符;如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符在执行make时的命令行选项参数被通过变量 “MAKEFLAGS”传递给子目录下的make程序。对于这个变量除非使用指示符“unexport”对它们进行声明,它们在整个make的执行过程中始终被自动的传递给所有的子make。还有个特殊变量SHELL与MAKEFLAGS一样,默认情况(没有用“unexport”声明)下在整个make的执行过程中被自动的传递给所有的子make。(第27-30行

unexport LC_ALL
LC_COLLATE=C
LC_NUMERIC=C
export LC_COLLATE LC_NUMERIC

    对于 27 的解释是:避免有趣的字符集 的依赖关系,不是很清楚什么作用,后面三行是导出LC_COLLATE LC_NUMERIC 两个变量第51-56行

ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

“ifdef”是条件关键字。语法是ifdef <variable-name>;<text-if-true>; else <text-if-false>; endif ifdef只检验一个变量是否被赋值,它并不会去推导这个变量,并不会把变量扩展到当前位置。 
“ifeq”与“ifdef”类似。 “ifeq”语法是ifeq (<arg1>;, <arg2>;),功能是比较参数“arg1”和“arg2”的值是否相同。
 函数origin并不操作变量的值,只是告诉你你的这个变量是哪里来的。
 语法是: $(origin <variable>;)
      origin函数的返回值有:
        “undefined”从来没有定义过、“default”是一个默认的定义、“environment”是一个环境变量、
        “file”这个变量被定义在Makefile中、“command line”这个变量是被命令行定义的、
        “override”是被override指示符重新定义的、“automatic”是一个命令运行中的自动化变量
 应用变量的语法是:$(变量名)。如KBUILD_VERBOSE = $(V)中的$(V)。 KBUILD_VERBOSE的值根据在命令行中是否定义了变量V,
 当没有定义时,默认为V=O,输出为short version;可以用make V=1 来输出全部的命令。
 ifndef与ifdef语法类似,但功能恰好相反。ifndef是判断变量是不是没有被赋值。第68-73行

ifeq ("$(origin C)", "command line")
  KBUILD_CHECKSRC = $(C)
endif
ifndef KBUILD_CHECKSRC
  KBUILD_CHECKSRC = 0
endif

   跟上面类似,这里不在分析第78-84行

ifdef SUBDIRS
  KBUILD_EXTMOD ?= $(SUBDIRS)
endif

ifeq ("$(origin M)", "command line")
  KBUILD_EXTMOD := $(M)
endif
    操作符“:=”与操作符“+=”的功能相同,只是操作符“:=”后面的用来定义变量(KBUILD_EXTMOD)的变量M只能是前面定义好的, 如果操作符“?=”前面的变量KBUILD_EXTMOD没有定义过,那么就将SUBDIRS赋给KBUILD_EXTMOD;如果定义过,则语句KBUILD_EXTMOD ?= $(SUBDIRS)什么也不做。第104-146行
ifeq ($(KBUILD_SRC),)

# OK, Make called in directory where kernel src resides
# Do we want to locate output files in a separate directory?
ifeq ("$(origin O)", "command line")
  KBUILD_OUTPUT := $(O)
endif

ifeq ("$(origin W)", "command line")
  export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W)
endif

# That's our default target when none is given on the command line
PHONY := _all
_all:

# Cancel implicit rules on top Makefile
$(CURDIR)/Makefile Makefile: ;

ifneq ($(KBUILD_OUTPUT),)
# Invoke a second make in the output directory, passing relevant variables
# check that the output directory actually exists
saved-output := $(KBUILD_OUTPUT)
KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
								&& /bin/pwd)
$(if $(KBUILD_OUTPUT),, \
     $(error output directory "$(saved-output)" does not exist))

PHONY += $(MAKECMDGOALS) sub-make

$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
	@:

sub-make: FORCE
	$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
	KBUILD_SRC=$(CURDIR) \
	KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile \
	$(filter-out _all sub-make,$(MAKECMDGOALS))

# Leave processing to above invocation of make
skip-makefile := 1
endif # ifneq ($(KBUILD_OUTPUT),)
endif # ifeq ($(KBUILD_SRC),)

     _all:为变量PHONY追加_all
         Makefile的规则:
            目标:依赖文件 命令1 命令2
           没有依赖文件的目标称为“伪目标”。伪目标并不是一个文件,只是一个标签。
由于伪目标不是一个文件,所以make无法生成它的依赖关系和决定它是否要执行,只有在命令行中输入(即显示地指明)这个“目标”才能让其生效,此处为"make _all"。

     saved-output := $(KBUILD_OUTPUT)
     KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
     函数shell是make与外部环境的通讯工具,它用于命令的扩展。shell函数起着调用shell命令(cd $(KBUILD_OUTPUT) && /bin/pwd)和返回命令输出结果的参数的作用。 Make仅仅处理返回结果,再返回结果替换调用点之前,make将每一个换行符或者一对回车/换行符处理为单个空格;如果返回结果最后是换行符(和回车符),make将把它们去掉。

   $(if $(KBUILD_OUTPUT),, \
   $(error output directory "$(saved-output)" does not exist))
函数if对在函数上下文中扩展条件提供了支持(相对于GNU make makefile文件中的条件语句,例如ifeq指令。)if函数的语法是:$(if <condition>,<then-part>) 或是 $(if <condition>,<then-part>,<else-part>)。 如果条件$(KBUILD_OUTPUT)为真(非空字符串),那么两个逗号之间的空字符(注意连续两个逗号的作用)将会是整个函数的返回值, 如果$(KBUILD_OUTPUT)为假(空字符串),那么$(error output directory "$(saved-output)" does not exist)会是整个函数的返回值, 此时如果<else-part>没有被定义,那么,整个函数返回空字串。
    函数error的语法是:$(error <text ...>;)
    函数error的功能是:产生一个致命的错误,output directory "$(saved-output)" does not exist是错误信息。注意,error函数不会在一被使用就会产生错误信息,所以如果你把其定义在某个变量中,并在后续的脚本中使用这个变量,那么也是可以的。
   命令“$(if $(KBUILD_OUTPUT),, \”中最后的“\”的作用是:紧接在“\”下面的“哪一行”的命令是“\”所在行的命令的延续。 如果要让前一个命令的参数等应用与下一个命令,那么这两个命令应该写在同一行,如果一行写不下两个命令,可以在第一行末尾添上符号"\",然后在下一行接着写。如果是几个命令写在同一行,那么后面的命令是在前面命令的基础上执行。如 cd /   ls 这两个命令写在同一行,那么ls显示的是根目录/下的文件和文件夹。

   PHONY += $(MAKECMDGOALS)

将变量KBUILD_OUTPUT的值追加给变量saved-output,

   $(filter-out _all,$(MAKECMDGOALS)) _all:
   $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
   KBUILD_SRC=$(CURDIR) \
   KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@
   反过滤函数——filter-out,语法是:$(filter-out <pattern...>;,<text>;)
  函数filter-out的功能是:去掉$(MAKECMDGOALS)中符合规则_all的所有字符串后,剩下的作为返回值。 函数filter-out调用与伪目标_all在同一行。伪目标_all下面的以tab开头的三行是命令,因为每行最后都有"\",所以这三行命令应该是写在同一行的,即后面的命令要受到处于它之前的那些命令的影响。
  $(if $(KBUILD_VERBOSE:1=),@) 含义是如果$(KBUILD_VERBOSE:1=) 不为空,则等于$@ 
自动化变量"$@"表示规则中的目标文件集,在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。 自动化变量还有"$<"、"$%"、"$<"等。 宏变量$(MAKE)的值为make命令和参数(参数可省)。 执行命令KBUILD_SRC=$(CURDIR)的结果是把变量CURDIR的值赋给变量KBUILD_SRC。CURDIR这个变量是Makefile提供的,代表了make当前的工作路径。 

    skip-makefile := 1
    endif # ifneq ($(KBUILD_OUTPUT),)
    endif # ifeq ($(KBUILD_SRC),) 给变量skip-makefile追加值1. 命令endif # ifneq ($(KBUILD_OUTPUT),)的意思是这一行的endif与ifneq ($(KBUILD_OUTPUT),)相对应,其实它本身已经解释清楚了,我只是让他变得明显一点而已。命令endif # ifeq ($(KBUILD_SRC),)的意思是这一行的endif与ifeq ($(KBUILD_SRC),)相对应。第149-1390行

ifeq ($(skip-makefile),)

# If building an external module we do not care about the all: rule
# but instead _all depend on modules
PHONY += all
ifeq ($(KBUILD_EXTMOD),)
_all: all
else
.......
endif	# skip-makefile
   在这个ifeq所包含的语句中,比较长,所以我们留在下节进行分析,在这节分析中,有什么错误的,请大家指出,这样才能共同进步。






  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值