GNU ARM汇编--(十七)u-boot的makefile和mkconfig解读
阅读碰到的头等问题:Makefile和shell脚本看不懂...
本文引用地址://m.amcfsurvey.com/article/201611/321714.htm说起来做linux也很久了,Makefile和shell脚本都接触过,但真的都是略懂而已.因为公司的Makefile和shell简单的一眼望的对穿,很初级的写法,简单的应用.再随便在网上下个老外的开源代码,那个Makefile和shell复杂啊.一不留神想起来了qt的qmake根据工程文件生成的Makefile也是很简单,但qmake是人家老外写的.不说其他语言了,只看Makefile和shell,中外的差距就在那了.
这次准备移植u-boot到tq2440上,选用的u-boot版本是u-boot-2012.07.
下面是我对u-boot配置和编译的makefile mkconfig config.mk等文件的解读,有些解读我是在源档上添加文字注释的,有些是另外写的,解读难免有误,若有读者发现了,希望能够指出,在下感激不尽!
在编译u-boot的过程,就是make xxx_config和make两步
以make smdk2410_config为例:
当以smdk2410_config为目标时,makefile中前面一些变量的定义和其他文件的引用也是有的,这个在原档中添加了有关注释:
在makefile中有:
- 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
- %_config::unconfig
- echo$@
- $(MKCONFIG)-A$(@:_config=)
%是个通配符,make xxx_config都是这个目标.目标的依赖是unconfig,unconfig的命令是删除一些文件,而这些文件正是从make xxx_config过程中产生的.unconfig就是清理配置的.
我们来看@$(MKCONFIG) -A $(@:_config=)
其实执行的是mkconfig -A smdk2410
我们可以在该行上面添加一行:echo $@
则会输出smdk2410_config,因为$@就是指目标
$(@:_config=)是变量的替换引用
格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。
所以smdk2410_config末尾的_config去除了.
下面就是执行mkconfig脚本了,mkconfig -A smdk2410
给出添加注释的mkconfig文件:
- #!/bin/sh-e
- #Scripttocreateheaderfilesandlinkstoconfigure
- #U-Bootforaspecificboard.
- #
- #Parameters:TargetArchitectureCPUBoard[VENDOR][SOC]
- #
- #(C)2002-2010DENXSoftwareEngineering,WolfgangDenk
- #
- APPEND=no#Default:Createnewconfigfile
- BOARD_NAME=""#Nametoprintinmakeoutput
- TARGETS=""
- arch=""
- cpu=""
- board=""
- vendor=""
- soc=""
- options=""
- echo$#
- if[$#-eq2-a("$1"="-A")];then
- #Automaticmode
- line=`egrep-i"^[[:space:]]*${2}[[:space:]]"boards.cfg`||{
- echo"make:***Noruletomaketarget`$2_config.Stop.">&2
- exit1
- }
- set${line}
- echo${line}
- echo$#
- #adddefaultboardnameifneeded
- [$#=3]&&set${line}${1}
- #####################################
- #我们执行脚本的命令是mkconfig-Asmdk2410,$#表示的是参数的个数,$1表示的是第一个参数
- #line就是在boards.cfg文件中smdk2410的那行,而-i表示忽略大小写
- #在boards.cfg文件中,有
- #TargetARCHCPUBoardnameVendorSoCOptions
- #smdk2410armarm920t-samsungs3c24x0
- #set${line}
- #set也可用于在脚本内部给出其运行参数,所以这个时候参数就变为"smdk2410armarm920t-samsungs3c24x0"
- #这个时候参数个数就变成6个了
- ######################################
- elif["${MAKEFLAGS+set}${MAKELEVEL+set}"="setset"];then
- #onlywarnwhenusingaconfigtargetintheMakefile
- cat<<-EOF
- warning:Pleasemigratetoboards.cfg.Failuretodosowill
- meanremovalofyourboardinthenextrelease.
- EOF
- sleep5
- fi
- echo$1
- while[$#-gt0];do
- case"$1"in
- --)shift;break;;
- -a)shift;APPEND=yes;;
- -n)shift;BOARD_NAME="${1%_config}";shift;;
- -t)shift;TARGETS="`echo$1|seds:_::g`${TARGETS}";shift;;
- *)break;;
- esac
- done
- ################################################
- #因为$1的值为smdk2410,所以case找不到对应的
- #################################################
- [$#-lt4]&&exit1
- [$#-gt7]&&exit1
- ##################################################
- #对参数个数做检查,小于4个或大于7个就退出
- ##################################################
- #Stripalloptionsand/or_configsuffixes
- CONFIG_NAME="${1%_config}"
- ####################
- #CONFIG_NAME的值为smdk2410
- #########################
- echoconfig_
- echo${CONFIG_NAME}
- ["${BOARD_NAME}"]||BOARD_NAME="${1%_config}"
- echoboard
- echo${BOARD_NAME}
- ###########################################
- #如果BOARD_NAME在之前已经被设定了,就不做任何动作;如果为空,就设定为smdk2410.这里设定为smdk2410
- ############################################
- arch="$2"
- cpu="$3"
- if["$4"="-"];then
- board=${BOARD_NAME}
- else
- board="$4"
- fi
- ######################################################
- #设定arch变量的值为arm
- #cpu变量的值为arm920t
- #因为第四个变量为"-",所以board变量的值为smdk2410
- #######################################################
- [$#-gt4]&&["$5"!="-"]&&vendor="$5"
- [$#-gt5]&&["$6"!="-"]&&soc="$6"
- #############################################################
- #设定verdor变量的值为samsung
- #设定soc变量的值为s3c24x0
- #############################################################
- [$#-gt6]&&["$7"!="-"]&&{
- #checkifwehaveaboardconfignameintheoptionsfield
- #theoptionsfieldmavehaveaboardconfignameandalist
- #ofoptions,bothseparatedbyacolon(:);theoptionsare
- #separatedbycommas(,).
- #
- #Checkforboardname
- tmp="${7%:*}"
- if["$tmp"];then
- CONFIG_NAME="$tmp"
- fi
- #Checkifweonlyhaveacolon...
- if["${tmp}"!="$7"];then
- options=${7#*:}
- TARGETS="`echo${options}|seds:,::g`${TARGETS}"
- fi
- }
- #################################################
- #因为我们的变量个数就是6个,这一段不执行
- #################################################
- echo${ARCH}
- echo${arch}
- if["${ARCH}"-a"${ARCH}"!="${arch}"];then
- echo"Failed:$ARCH=${ARCH},shouldbe${arch}for${BOARD_NAME}"1>&2
- exit1
- fi
- ####################################################
- #ARCH是在顶层makefile中定义的,在此刻还是为空的。
- #如果ARCH已经有值了,那么就检测ARCH和arch是否匹配了.
- ####################################################
- if["$options"];then
- echo"Configuringfor${BOARD_NAME}-Board:${CONFIG_NAME},Options:${options}"
- else
- echo"Configuringfor${BOARD_NAME}board..."
- fi
- ###########################################################################
- #我们没有定义options变量,所以输出Configuringforsmdk2410board...
- ###########################################################################
- #
- #Createlinktoarchitecturespecificheaders
- #
- echo${SRCTREE}
- echo${OBJTREE}
- if["$SRCTREE"!="$OBJTREE"];then
- mkdir-p${OBJTREE}/include
- mkdir-p${OBJTREE}/include2
- cd${OBJTREE}/include2
- rm-fasm
- ln-s${SRCTREE}/arch/${arch}/include/asmasm
- LNPREFIX=${SRCTREE}/arch/${arch}/include/asm/
- cd../include
- mkdir-pasm
- else
- cd./include
- rm-fasm
- ln-s../arch/${arch}/include/asmasm
- fi
- #############################################################################
- #在makefile中我们已经知道SRCTREE和OBJTREE都是当前目录,所以这里执行else
- #进入./include目录,删除asm链接,并重新建立链接asm,指向arch/arm/include/asm
- #############################################################################
- rm-fasm/arch
- #########################################################################
- #删除include目录下的asm下的arch链接文件
- ########################################################################
- ss=
- echo${ss}
- if[-z"${ss}"];then
- echo"null"
- else
- echo"notnull"
- fi
- echo${LNPREFIX}
- if[-z"${soc}"];then
- ln-s${LNPREFIX}arch-${cpu}asm/arch
- else
- ln-s${LNPREFIX}arch-${soc}asm/arch
- fi
- ##########################################################
- #-z用来检测字符串是否为空,为空返回真
- #这里我们的soc不为空,执行else
- #将asm/arch链向arch-s3c24x0,看一下arch-s3c24x0目录,里面都是s3c24x0相关的头文件
- ##########################################################
- if["${arch}"="arm"];then
- rm-fasm/proc
- ln-s${LNPREFIX}proc-armvasm/proc
- fi
- ###########################################################
- #删除asm/proc链接文件
- #将asm/proc链向proc-armv目录,该目录下是四个头文件:domain.hprocessor.hptrace.hsystem.h
- #############################################################
- #
- #CreateincludefileforMake
- #
- echo"ARCH=${arch}">config.mk
- echo"CPU=${cpu}">>config.mk
- echo"BOARD=${board}">>config.mk
- ["${vendor}"]&&echo"VENDOR=${vendor}">>config.mk
- ["${soc}"]&&echo"SOC=${soc}">>config.mk
- ######################################################################
- #上面几句的作用在注释中描述的很清楚
- #include/config.mk的文件如下:
- #ARCH=arm
- #CPU=arm920t
- #BOARD=smdk2410
- #VENDOR=samsung
- #SOC=s3c24x0
- ######################################################################
- #AssignboarddirectorytoBOARDIRvariable
- if[-z"${vendor}"];then
- BOARDDIR=${board}
- else
- BOARDDIR=${vendor}/${board}
- fi
- echo${BOARDDIR}
- #######################################################################
- #因为vendor变量不为空,所以执行else
- #BOARDDIR的值为samsung/s3c24x0
- ########################################################################
- #
- #Createboardspecificheaderfile
- #
- if["$APPEND"="yes"]#Appendtoexistingconfigfile
- then
- echo>>config.h
- else
- >config.h#Createnewconfigfile
- fi
- ########################################################################
- #在文件的最开头可以看到APPEND为no,所以这里我们在include文件夹下建立config.h文件
- #######################################################################
- echo"/*Automaticallygenerated-donotedit*/">>config.h
- echo${TARGETS}
- foriin${TARGETS};do
- i="`echo${i}|sed/=/{s/=//;q;};{s/$/1/;}`"
- echo"#defineCONFIG_${i}">>config.h;
- done
- ###################################################
- #这里我们TARGETS为空,上面不执行了
- ##################################################
- echo"#defineCONFIG_SYS_ARCH"${arch}"">>config.h
- echo"#defineCONFIG_SYS_CPU"${cpu}"">>config.h
- echo"#defineCONFIG_SYS_BOARD"${board}"">>config.h
- ["${vendor}"]&&echo"#defineCONFIG_SYS_VENDOR"${vendor}"">>config.h
- ["${soc}"]&&echo"#defineCONFIG_SYS_SOC"${soc}"">>config.h
- cat<
>config.h - #defineCONFIG_BOARDDIRboard/$BOARDDIR
- #include
- #include
- #include
- #include
- #include
- EOF
- ######################################################
- #生成config.h文件如下:
- #/*Automaticallygenerated-donotedit*/
- ##defineCONFIG_SYS_ARCH"arm"
- ##defineCONFIG_SYS_CPU"arm920t"
- ##defineCONFIG_SYS_BOARD"smdk2410"
- ##defineCONFIG_SYS_VENDOR"samsung"
- ##defineCONFIG_SYS_SOC"s3c24x0"
- ##defineCONFIG_BOARDDIRboard/samsung/smdk2410
- ##include
- ##include
- ##include
- ##include
- ##include
- #####################################################
- exit0
make xxx_config后,主要的变化是多了几个文件:
1.include/asm --> arch/arm/include/arm
2.include/asm/arch --> arch-s3c24x0
3.include/asm/proc --> proc-armv
4.在include目录下新建了config.mk文件,文件内容是ARCH CPU BOARD VENDOR SOC的定义
5.在include目录下新建了config.h文件
接着看make:
给出部分makefile中的注释,主要是一些变量的定义:
评论