uboot顶层makefile详解2.docx
- 文档编号:9723798
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:22
- 大小:24.72KB
uboot顶层makefile详解2.docx
《uboot顶层makefile详解2.docx》由会员分享,可在线阅读,更多相关《uboot顶层makefile详解2.docx(22页珍藏版)》请在冰豆网上搜索。
uboot顶层makefile详解2
#
#(C)Copyright2000-2006版权所有:
2000~2006
#WolfgangDenk,DENXSoftwareEngineering,wd@denx.de.WolfgangDenk一个开发人员的名字DENXSoftwareEngineering公司名称wd@denx.de邮箱
#
#SeefileCREDITSforlistofpeoplewhocontributedtothis可以看看CREDITS,里面有为uboot做出贡献的所有开发人员
#project.
#
#Thisprogramisfreesoftware;youcanredistributeitand/or这个程序是一个自由软件,你可以重新发布它,或者在自由软件基金组织所颁布的
#modifyitunderthetermsoftheGNUGeneralPublicLicenseasGNUGPL(GNU公共许可协议)的前提下修改它;注意,不论是第二版的GPL还是
#publishedbytheFreeSoftwareFoundatio;eitherversion2of任何更新的版本,都可以,这由你选择。
#theLicense,or(atyouroption)anylaterversion.
#
#Thisprogramisdistributedinthehopethatitwillbeuseful,我们之所以发布这个程序,是希望它能够对你有用,但是我们不做任何担保;
#butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof不保证任何的可销售性和任何给予特殊目的的合适性。
想要了解详细内容,
#MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe你可以参考GNUGPL。
#GNUGeneralPublicLicenseformoredetails.
#
#YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense你应该已经得到了GNUGeneralPublicLicense的一个拷贝,因为它就包含在
#alongwiththisprogram;ifnot,writetotheFreeSoftware这个工程的源代码包中。
如果没有,你可以写信给自由软件基金组织,以获取一份。
#Foundation,Inc.,59TemplePlace,Suite330,Boston,
#MA02111-1307USA
#
VERSION=1
PATCHLEVEL=1
SUBLEVEL=6
EXTRAVERSION=
U_BOOT_VERSION=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)#1.1.6版
VERSION_FILE=$(obj)include/version_autogenerated.h#版本文件
#uname命令将正在使用的操作系统名写到标准输出中
#-m显示硬件运行系统的机器ID号
#定义变量,HOSTARCH里面存储的是机器ID号,即主机架构类型
HOSTARCH:
=$(shelluname-m|\#可以把shell脚本写到makefile里面,这是make中的shellfunction,相当于shell中的命令替换。
sed-es/i.86/i386/\#shelluname-m获得机器硬件名称
-es/sun4u/sparc64/\#sed-es/arm.*/arm/的意思是把前缀为arm的所有模式替换为arm。
结合前面的uname命令来理解就是:
-es/arm.*/arm/\#把uname-m的结果(主机架构类型或者称为机器ID号)通过管道传递给sed命令,然后把前缀为arm的所有模式替换为arm。
-es/sa110/arm/\#sed的语法:
sed[-n]Script[File...]
-es/powerpc/ppc/\#sed[-n][-eScript]...[-fScriptFile]...[File...]
-es/macppc/ppc/)#sed命令根据编辑脚本,去修改指定的File文件(这里file是作为一个输入参数的)的行,并将其写到标准输出。
#sed命令包含很多功能,用于选择要修改的行(请注意,sed是针对行进行操作的),并只对选择的行作更改。
#sed命令使用两个工作空间来保留修改的行:
保留选定行的"模式空间"和暂时存储行的"保留空间"。
#这里的编辑脚本由单独的子命令构成,每个单独的行对应着一个子命令。
sed子命令的格式如下:
[address-range]function[modifiers],即:
[地址范围]函数[修改符]
#sed命令通过将一个输入行读入模式空间,依次应用所有的sed子命令(这些子命令的地址选择了该行),
#并将模式空间写到标准输出来处理每个输入的File输入文件(file就是输入参数)。
然后清除模式空间,并对输入的File中指定的每行重复该过程。
#一些sed子命令使用保留空间来保存后继检索的所有的,或部分的模式空间。
#当命令包含地址(行号或搜索模式)时,该命令只会对被寻址的行起作用。
否则,该命令适用于所有的行。
#注意,这里的参数"-e"的意思是:
使用Script变量作为编辑脚本。
如果你只使用一个-e标志并且不使用-f标志,则可以省略-e标志。
#注意,这里的"sed-es/arm.*/arm/"表示把前缀为arm的所有模式替换为arm,也就是seds/pattern/replacement/flags
#用replacement字符串代替在模式空间中首次出现的pattern参数。
除了空格或换行符,在s子命令之后显示的任何字符都能代替/(斜杠)分隔符。
#uname-s表示:
显示系统名,标志缺省为开,即uname命令不带任何参数的输出和加参数-s输出相同,即Linux
#tr是一个shell命令,可以实现许多sed的功能,这里tr'[:
upper:
]''[:
lower:
]'的意思是把管道中的Linux中的大写字母L转换成小写字母l
#下面这句话的意思是定义变量HOSTOS,HOSTOS里面存放的是主机安装的,并且当前正在运行的操作系统。
HOSTOS:
=$(shelluname-s|tr'[:
upper:
]''[:
lower:
]'|\
sed-e's/\(cygwin\).*/cygwin/')#这一句的意思是检测出主机安装的,并且当前正在运行的操作系统名,并把这个系统名中的大写字母转换为小写字母,
#然后在通过sed流编辑器匹配所有的,这个系统名中出现的"\(cygwin\).*"模式,然后再用"cygwin"模式替换。
#exportHOSTARCHHOSTOS的意思是输出两个makefile变量HOSTARCH和HOSTOS
exportHOSTARCHHOSTOS
#Dealwithcollidingdefinitionsfromtcshetc.用来处理来自tcsh的互相冲突的定义等等
#一般来说,shell可以分成两类。
第一类是由 Bourne shell 衍生出来的包括
#sh,ksh,bash,与zsh。
第二类是由 C shell 衍生出来的,包括 csh 与
#tcsh。
除此之外还有一个rc,有人认为该自成一类,有人认为该归类在Bourne shell。
VENDOR=#开发商
#########################################################################
#
#U-bootbuildsupportsproducingaobjectfilestotheseparateexternal
#U-boot的编译过程可以支持向一个自己定义的路径生成最终的目标文件
#directory.Twousecasesaresupported:
#这里提供了两种用法:
#
#1)AddO=tothemakecommandline#第一种用法:
通过在终端执行命令makeO=/dir(即你指定的生成的目标文件的存放目录)
#'makeO=/tmp/buildall'
#
#2)SetenvironementvariableBUILD_DIRtopointtothedesiredlocation#第二种用法:
通过设置环境变量来指定目标文件存放目录,如下所示:
#'exportBUILD_DIR=/tmp/build'
#'make'
#
#ThesecondapproachcanalsobeusedwithaMAKEALLscript#第二种方法也可以写成一个MAKEALL脚本,然后执行MAKEALL,如下所示:
#'exportBUILD_DIR=/tmp/build'
#'./MAKEALL'
#
#Commandline'O='settingoverridesBUILD_DIRenvironentvariable.#命令行'O='设置会覆盖环境变量BUILD_DIR的设置
#
#Whennoneoftheabovemethodsisused,thelocalbuildisperformedand#如果都不采用上面两种方法,那么目标文件放到源码顶层目录,也就是U-BOOT顶层目录
#theobjectfilesareplacedinthesourcedirectory.
#
#理解了上面一段英文,这里就不难理解了
#方法1:
ifdefO#如果变量'O'已经被定义过
ifeq("$(originO)","commandline")#如果变量'O'在命令行中定义过
BUILD_DIR:
=$(O)#就把变量'O'的值(目标文件存放目录)赋给BUILD_DIR
endif
endif
#方法2
ifneq($(BUILD_DIR),)#如果变量BUILD_DIR不为空,即环境变量BUILD_DIR被定义过
saved-output:
=$(BUILD_DIR)#那么把它的值赋给saved-output
#Attempttocreateaoutputdirectory.#生成一个输出路径,即目标文件存放目录BUILD_DIR
$(shell[-d${BUILD_DIR}]||mkdir-p${BUILD_DIR})
#shell[-d${BUILD_DIR}]是什么意思?
是不是生成一个目录的意思?
#Verifyifitwassuccessful.测试目录是否创建成功
BUILD_DIR:
=$(shellcd$(BUILD_DIR)&&/bin/pwd)#这又是什么意思,说明对shell还不够理解!
$(if$(BUILD_DIR),,$(erroroutputdirectory"$(saved-output)"doesnotexist))
#这里用了一个if函数,意思是如果如果$(BUILD_DIR)非空,则什么都不执行(返回空),否则执行error函数,输出错误信息
endif
#ifneq($(BUILD_DIR),)#意思是:
如果没有定义目标文件存放目录
#Makefile中定义了源码以及生成目标文件存放的目录,目标文件存放目录BUILD_DIR可以通过makeO=dir指定。
如果没有指定,则设定为源码顶层目录。
#一般编译的时候不指定输出目录,则BUILD_DIR为空。
其他目录变量如下:
OBJTREE:
=$(if$(BUILD_DIR),$(BUILD_DIR),$(CURDIR))#如果$(BUILD_DIR)不为空,则返回$(BUILD_DIR),并赋给OBJTREE,即自己定制的目标存放目录
SRCTREE:
=$(CURDIR)#把当前源码所在目录$(CURDIR)赋给SRCTREE
TOPDIR:
=$(SRCTREE)#把当前源码所在目录$(CURDIR)赋给SRCTREE
LNDIR:
=$(OBJTREE)#存放生成的目录文件
exportTOPDIRSRCTREEOBJTREE
MKCONFIG:
=$(SRCTREE)/mkconfig#MKCONFIG指向源码所在目录(U-BOOT顶层目录)下的mkconfig配置文件
exportMKCONFIG
#在编译UBOOT之前,我们先要执行:
#makesmdk2410_config
#从本Makefile的下文可以判断出smdk2410_config为Makefile的一个目标。
#smdk2410_config:
unconfig的意思是为smdk2410开发板建立一个编译项。
#显然,执行#makesmdk2410_config时,先执行unconfig目标(不指定输出目标时,obj,src变量均为空),unconfig下面的命令主要任务是清理上
#一次执行make*_config时生成的头文件和makefile的包含文件。
#主要是include/config.h和include/config.mk
#然后执行命令:
@$(MKCONFIG)$(@:
_config=)armarm920tsmdk2410NULLs3c24x0
#arm表示CPU的构架是基于ARM体系的
#arm920t表示CPU的类型是arm920t
#smdk2410表示开发板的型号
#NULL表示开发商或者经销商的名称,这里为空
#s3c24x0表示基于S3C2410的片上系统
#MKCONFIG指向UBOOT顶层目录下的mkconfig脚本配置文件,后面五个字符串是传入的参数(好像$(@:
_config=)也是一个参数)。
#下面来分析一下mkconfig这个脚本配置文件,点击链接:
ifneq($(OBJTREE),$(SRCTREE))#当目标存放目录不是U-BOOT顶层目录(源码目录)时
REMOTE_BUILD:
=1#定义变量REMOTE_BUILD:
=1这个变量算是一个flag吧
exportREMOTE_BUILD
endif
#$(obj)and(src)aredefinedinconfig.mk(顶层目录下)buthereinmainMakefile
#wealsoneedthembeforeconfig.mkisincludedwhichisthecasefor
#sometargetslikeunconfig,clean,clobber,distclean,etc.
#$(obj)and$(src)都被定义在顶层目录下的config.mk脚本配置文件里面,
#但是在这个主Makefile里面,我们同样需要他们,
#因为在主Makefile文件包含config.mk之前,$(obj)and$(src)偶尔地会成为这些目标的case:
#unconfig,clean,clobber,distclean,etc
ifneq($(OBJTREE),$(SRCTREE))#当目标存放目录不是U-BOOT顶层目录(源码目录)时
obj:
=$(OBJTREE)/#定义变量obj,让其等于目标存放目录
src:
=$(SRCTREE)/#定义变量src,让其等于uboot顶层目录
else
obj:
=#否则,这两个变量都定义为空
src:
=
endif
exportobjsrc
#########################################################################
ifeq($(OBJTREE)/include/config.mk,$(wildcard$(OBJTREE)/include/config.mk))#这句话让人费解!
#通配符在规则中可以自动扩展,但设置在变量中或在函数的参数中通配符一般不能正常扩展。
#如果您需要在这些场合扩展通配符,您应该使用函数wildcard,格式如下:
#$(wildcardpattern...)
#loadARCH,BOARD,andCPUconfiguration
#加载ARCH,BOARD,andCPU配置
include$(OBJTREE)/include/config.mk#这时候,才开始包含/include/config.mk的
exportARCHCPUBOARDVENDORSOC
#指定交叉编译器前缀
ifeq($(ARCH),arm)
CROSS_COMPILE=arm-linux-
#这里你可以把交叉编译器的安装路径加到arm-linux-之前,比如你的交叉编译器安装路径是/root/u-boot/usr/local/arm/3.3.2/bin/
#你可以这样定义CROSS_COMPILE=/root/u-boot/usr/local/arm/3.3.2/bin/arm-linux-
#这样一来,你在终端进行编译的时候就不用指定CROSS_COMPILE=arm-linux-了
#但请注意:
在编译内核的时候,交叉编译器必须安装在/usr/local/arm下,否则会发生错误!
!
!
!
!
endif
exportCROSS_COMPILE
#loadotherconfiguration加载其他设置,这里是包含顶层目录下的config.mk配置文件,这个文件主要做了三个工作:
#1、定义了交叉编译器2、定义了编译选项3、定义了编译规则
#对本文件具体的分析,请查看链接:
include$(TOPDIR)/config.mk
#########################################################################
#U-Bootobjects....orderisimportant(i.e.startmustbefirst)
#uboot目标...书写顺序很重要,比如start.o必须排在第一位
#########################################################################
OBJS=cpu/$(CPU)/start.o
#start.o必须放在目标文件的第一位,因为uboot执行的第一段代码就是start.S
#具体原因可以查看链接脚本/u-boot-1.1.6/board/smdk2410/u-boot.lds,点击连接:
.....................................
OBJS:
=$(addprefix$(obj),$(OBJS))#这句的意思是把目标文件存放路径以前缀的形式加到start.O之前,然后再赋给OBJS
#以下是编译UBOOT需要的库文件
LIBS=lib_generic/libgeneric.a
LIBS+=board/$(BOARDDIR)/lib$(BOARD).a#严重平台依赖的
LIBS+=cpu/$(CPU)/lib$(CPU).a#严重平台依赖的
ifdefSOC
LIBS+=cpu/$(CPU)/$(SOC)/lib$(SOC).a#严重平台依赖的
endif
LIBS+=lib_$(ARCH)/lib$(ARCH).a#严重平台依赖的
LIBS+=fs/cramfs/libcramfs.afs/fat/libfat.afs/fdos/libfdos.afs/jffs2/libjffs2.a\
fs/reiserfs/libreiserfs.afs/ext2/libext2fs.a
LIBS+=net/libnet.a
LIBS+=disk/libdisk.a
LIBS+=rtc/librtc.a
LIBS+=dtt/libdtt.a
LIBS+=drivers/libdrivers.a
LIBS+=drivers/nand/libnand.a
LIBS+=drivers/nand_legacy/libnand_legacy.a
LIBS+=drivers/sk98lin/libsk98lin.a
LIBS+=post/libpost.apost/cpu/libcpu.a
LIBS+=common/libcommon.a
LIBS+=$(BOARDLIBS)
LIBS:
=$(addprefix$(obj),$(LIBS))
.PHONY:
$(LIBS)#这是一个伪目标
#根据所生成的include/config.mk文件定义的几个变量ARCH,CPU,BOARD,SOC,我们可以
#确定硬件平台依赖的目录文件。
smdk2410平台相关(依赖)目录以及对应生成的库文件如下:
#board/smdk2410/:
库文件board/smdk2410/libsmdk2410.a
#cpu/arm920t/:
库文件cpu/arm920t/libarm920t.a
#cpu/arm920t/s3c24x0:
库文件cpu/a
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- uboot 顶层 makefile 详解