GNU ARM匯編--(十七)u-boot的makefile和mkconfig解讀
閱讀碰到的頭等問(wèn)題:Makefile和shell腳本看不懂...
本文引用地址:http://m.butianyuan.cn/article/201611/321714.htm說(shuō)起來(lái)做linux也很久了,Makefile和shell腳本都接觸過(guò),但真的都是略懂而已.因?yàn)楣镜腗akefile和shell簡(jiǎn)單的一眼望的對(duì)穿,很初級(jí)的寫(xiě)法,簡(jiǎn)單的應(yīng)用.再隨便在網(wǎng)上下個(gè)老外的開(kāi)源代碼,那個(gè)Makefile和shell復(fù)雜啊.一不留神想起來(lái)了qt的qmake根據(jù)工程文件生成的Makefile也是很簡(jiǎn)單,但qmake是人家老外寫(xiě)的.不說(shuō)其他語(yǔ)言了,只看Makefile和shell,中外的差距就在那了.
這次準(zhǔn)備移植u-boot到tq2440上,選用的u-boot版本是u-boot-2012.07.
下面是我對(duì)u-boot配置和編譯的makefile mkconfig config.mk等文件的解讀,有些解讀我是在源檔上添加文字注釋的,有些是另外寫(xiě)的,解讀難免有誤,若有讀者發(fā)現(xiàn)了,希望能夠指出,在下感激不盡!
在編譯u-boot的過(guò)程,就是make xxx_config和make兩步
以make smdk2410_config為例:
當(dāng)以smdk2410_config為目標(biāo)時(shí),makefile中前面一些變量的定義和其他文件的引用也是有的,這個(gè)在原檔中添加了有關(guān)注釋:
在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=)
%是個(gè)通配符,make xxx_config都是這個(gè)目標(biāo).目標(biāo)的依賴是unconfig,unconfig的命令是刪除一些文件,而這些文件正是從make xxx_config過(guò)程中產(chǎn)生的.unconfig就是清理配置的.
我們來(lái)看@$(MKCONFIG) -A $(@:_config=)
其實(shí)執(zhí)行的是mkconfig -A smdk2410
我們可以在該行上面添加一行:echo $@
則會(huì)輸出smdk2410_config,因?yàn)?@就是指目標(biāo)
$(@:_config=)是變量的替換引用
格式為“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是:替換變量“VAR”中所有“A”字符結(jié)尾的字為“B”結(jié)尾的字。
所以smdk2410_config末尾的_config去除了.
下面就是執(zhí)行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}
- #####################################
- #我們執(zhí)行腳本的命令是mkconfig-Asmdk2410,$#表示的是參數(shù)的個(gè)數(shù),$1表示的是第一個(gè)參數(shù)
- #line就是在boards.cfg文件中smdk2410的那行,而-i表示忽略大小寫(xiě)
- #在boards.cfg文件中,有
- #TargetARCHCPUBoardnameVendorSoCOptions
- #smdk2410armarm920t-samsungs3c24x0
- #set${line}
- #set也可用于在腳本內(nèi)部給出其運(yùn)行參數(shù),所以這個(gè)時(shí)候參數(shù)就變?yōu)?smdk2410armarm920t-samsungs3c24x0"
- #這個(gè)時(shí)候參數(shù)個(gè)數(shù)就變成6個(gè)了
- ######################################
- 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
- ################################################
- #因?yàn)?1的值為smdk2410,所以case找不到對(duì)應(yīng)的
- #################################################
- [$#-lt4]&&exit1
- [$#-gt7]&&exit1
- ##################################################
- #對(duì)參數(shù)個(gè)數(shù)做檢查,小于4個(gè)或大于7個(gè)就退出
- ##################################################
- #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在之前已經(jīng)被設(shè)定了,就不做任何動(dòng)作;如果為空,就設(shè)定為smdk2410.這里設(shè)定為smdk2410
- ############################################
- arch="$2"
- cpu="$3"
- if["$4"="-"];then
- board=${BOARD_NAME}
- else
- board="$4"
- fi
- ######################################################
- #設(shè)定arch變量的值為arm
- #cpu變量的值為arm920t
- #因?yàn)榈谒膫€(gè)變量為"-",所以board變量的值為smdk2410
- #######################################################
- [$#-gt4]&&["$5"!="-"]&&vendor="$5"
- [$#-gt5]&&["$6"!="-"]&&soc="$6"
- #############################################################
- #設(shè)定verdor變量的值為samsung
- #設(shè)定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
- }
- #################################################
- #因?yàn)槲覀兊淖兞總€(gè)數(shù)就是6個(gè),這一段不執(zhí)行
- #################################################
- 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已經(jīng)有值了,那么就檢測(cè)ARCH和arch是否匹配了.
- ####################################################
- if["$options"];then
- echo"Configuringfor${BOARD_NAME}-Board:${CONFIG_NAME},Options:${options}"
- else
- echo"Configuringfor${BOARD_NAME}board..."
- fi
- ###########################################################################
- #我們沒(méi)有定義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中我們已經(jīng)知道SRCTREE和OBJTREE都是當(dāng)前目錄,所以這里執(zhí)行else
- #進(jìn)入./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用來(lái)檢測(cè)字符串是否為空,為空返回真
- #這里我們的soc不為空,執(zhí)行else
- #將asm/arch鏈向arch-s3c24x0,看一下arch-s3c24x0目錄,里面都是s3c24x0相關(guān)的頭文件
- ##########################################################
- if["${arch}"="arm"];then
- rm-fasm/proc
- ln-s${LNPREFIX}proc-armvasm/proc
- fi
- ###########################################################
- #刪除asm/proc鏈接文件
- #將asm/proc鏈向proc-armv目錄,該目錄下是四個(gè)頭文件: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}
- #######################################################################
- #因?yàn)関endor變量不為空,所以執(zhí)行else
- #BOARDDIR的值為samsung/s3c24x0
- ########################################################################
- #
- #Createboardspecificheaderfile
- #
- if["$APPEND"="yes"]#Appendtoexistingconfigfile
- then
- echo>>config.h
- else
- >config.h#Createnewconfigfile
- fi
- ########################################################################
- #在文件的最開(kāi)頭可以看到APPEND為no,所以這里我們?cè)趇nclude文件夾下建立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為空,上面不執(zhí)行了
- ##################################################
- 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后,主要的變化是多了幾個(gè)文件:
1.include/asm --> arch/arm/include/arm
2.include/asm/arch --> arch-s3c24x0
3.include/asm/proc --> proc-armv
4.在include目錄下新建了config.mk文件,文件內(nèi)容是ARCH CPU BOARD VENDOR SOC的定義
5.在include目錄下新建了config.h文件
接著看make:
給出部分makefile中的注釋,主要是一些變量的定義:
評(píng)論