uboot1.1.6顶层makefile详解

发布者:和谐相伴最新更新时间:2024-10-21 来源: cnblogs关键字:6  顶层  makefile 手机看文章 扫描二维码
随时随地手机看文章

VERSION = 1//主版本号
PATCHLEVEL = 1//次版本号
SUBLEVEL = 6//修正版本号
EXTRAVERSION =//版本号扩展
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)//这个Uboot的版本为1.1.6
VERSION_FILE = $(obj)include/version_autogenerated.h

HOSTARCH := $(shell uname -m |
 sed -e s/i.86/i386/
     -e s/sun4u/sparc64/
     -e s/arm.*/arm/
     -e s/sa110/arm/
     -e s/powerpc/ppc/
     -e s/macppc/ppc/)
首先执行uname -m得到I686,通过管道传送给sed命令,然后sed命令将执行sed -e s/i.86/i386/,将I686替换成i386,最后的结果是HOSTARCH=i386.
I686 表示Ubuntu, sed命令是替换命令

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' |
     sed -e 's/(cygwin).*/cygwin/')
首先执行uname -s 查看开发平台的系统,结果为Linux,然后通过管道传送给tr命令,tr命令利用字符类[:lower:]和[:upper:]将Linux字符串转化为linux,然后再利用sed命令.最后的结果是HOSTOS=linux

export HOSTARCH HOSTOS
这些变量传递给下一层的Makefile

Uboot支持将目标文件生成在外部的文件夹中,有两种命令可以实现。
1,加入O=命令
2,设定环境变量BUILD_DIR
如果以上两种方式都没有定义,那么它将会被存放在源码目录下
ifdef O
ifeq ('$(origin O)', 'command line')
BUILD_DIR := $(O)
endif
endif
上面的意思是如果定义了O命令,并且O=指定的目录和command line指定的目录一样
BUILD_DIR就为O=定义的目录
origin函数不像其它的函数,他并不操作变量的值,只是告诉你这个变量从哪里来

ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
再判断BUILD_DIR是否为0,若不为0,则save-output即保存BUILD_DIR指定的输出目录

# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
build_dir是不是一个目录 ,如果没有就创建, [ ] 就是个条件判断语句

BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
先打开这个目录,再调用Pwd显示当前路径,在将这个路径值赋给BUILD_DIR
$(if $(BUILD_DIR),,$(error output directory '$(saved-output)' does not exist))
endif # ifneq ($(BUILD_DIR),)
如果BUILD_DIR还不存在的话,则输出saved-output中的目录does not exist


OBJTREE  := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE  := $(CURDIR)
TOPDIR  := $(SRCTREE)
LNDIR  := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
OPDIR SRCTREE OBJTREE这三个目录会给下层的makefile调用,需要在这里指定并export
OBJTREE和LNDIR为存放生成文件的目录,TOPDIR与SRCTREE为源码所在目录

MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
定义变量MKCONFIG:这个变量指向一个脚本,即顶层源码目录的mkconfig。

ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD := 1
export REMOTE_BUILD
endif
如果输出目录与源码目录不等,则设定REMOTE_BUILD项,并导出

ifneq ($(OBJTREE),$(SRCTREE))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src
如果输出目录OBJTREE与SRCTREE即当前的Uboot目录不等的话,对obj和src进行赋值,否则则obj,src为空。
obj src会在主目录中的config.mk定义,但在主makefile包含config.mk之前也需要,譬如unconfig, clean, clobber, distclean

ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk))
在分析这个及以下命令之前,我们需要了解在在编译U-BOOT之前,先要执行# make smdk6410_config
smdk6410_config是Makefile的一个目标,定义如下:
smdk6410_config : unconfig
 @$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410
unconfig:
 @rm -f $(obj)include/config.h $(obj)include/config.mk
  $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp
首先执行unconfig,obj src为上面所定义的,这个命令清理上一次执行make *_config时生成的头文件和makefile的包含文件。主要是include/config.h 和include/config.mk文件。

然后再执行@$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410
MKCONFIG 是顶层目录下的mkcofig脚本文件,后面五个是传入的参数。顶层目录下的mkcofig稍后分析
主要生成生成Makefile包含文件include/config.mk,用五个传入的参数定义五个变量
ARCH   = arm
CPU    = s3c64xx
BOARD  = smdk6410
VENDOR = samsung
SOC    = s3c6410

生成include/config.h头文件,只有一行:
#include 'config/smdk6410.h'


# load ARCH, BOARD, and CPU configuration
include $(OBJTREE)/include/config.mk
export ARCH CPU BOARD VENDOR SOC
包含include/config.mk,导出ARCH CPU BOARD VENDOR SOC这五个变量

ifndef CROSS_COMPILE
ifeq ($(ARCH),arm)//ARCH   = arm
CROSS_COMPILE = arm-linux-
endif
endif

CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
export CROSS_COMPILE

指定交叉编译器前缀,我只写出了与ARM相关的交叉编译前缀
/usr/local/arm/4.2.2-eabi/usr/bin/这个目录是安装交叉编译器的目录

# load other configuration
include $(TOPDIR)/config.mk
包含顶层目录下的config.mk,这个文件里面主要定义了交叉编译器及选项和编译规则
稍后分析顶层目录的config.mk

下面就是Uboot需要的目标文件和库文件,$(CPU)已经指定了CPU    = s3c64xx
与之相关的VENDOR = samsung

# U-Boot objects....order is important (i.e. start must be first)

OBJS  = cpu/$(CPU)/start.o
ifeq ($(CPU),i386)
OBJS += cpu/$(CPU)/start16.o
OBJS += cpu/$(CPU)/reset.o
endif
ifeq ($(CPU),ppc4xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc85xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc86xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),bf533)
OBJS += cpu/$(CPU)/start1.o cpu/$(CPU)/interrupt.o cpu/$(CPU)/cache.o
OBJS += cpu/$(CPU)/cplbhdlr.o cpu/$(CPU)/cplbmgr.o cpu/$(CPU)/flush.o
endif

OBJS := $(addprefix $(obj),$(OBJS))
addprefix为增加前缀函数

库文件,由各个目录下的makefile生成,链接时需要这些文件
这些文件涉及到的目录有lib_generic,board,cpu,lib_arm,fs,net,disk,rtc,dtt,drivers,post,common
将与平台相关的进行下面替换
$(ARCH)   = arm
$(CPU)    = s3c64xx
$(BOARD)  = smdk6410
$(VENDOR) = samsung
$(SOC)    = s3c6410

LIBS  = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
BOARDDIR好像为VENDOR = samsung
LIBS += cpu/$(CPU)/lib$(CPU).a
ifdef SOC
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
endif
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a
 fs/reiserfs/libreiserfs.a fs/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
# add to support onenand. by scsuh
LIBS += drivers/onenand/libonenand.a
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/qe.a
endif
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
LIBS += $(BOARDLIBS)

LIBS := $(addprefix $(obj),$(LIBS))
.PHONY : $(LIBS)


加入GCC的库,CC和CFLAGS都是make的隐含变量,CC表示C编译器,cflags表示执行CC时的命令行参数
# Add GCC lib
PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc


# The 'tools' are needed early, so put this first
# Don't include stuff already done in $(LIBS)
SUBDIRS = tools
   examples
   post
   post/cpu
.PHONY : $(SUBDIRS)
.PHONY是什么伪目标,不是很懂

ifeq ($(CONFIG_NAND_U_BOOT),y)
NAND_SPL = nand_spl
U_BOOT_NAND = $(obj)u-boot-nand.bin
endif

__OBJS := $(subst $(obj),,$(OBJS))
__LIBS := $(subst $(obj),,$(LIBS))
$(subst text, to, from)字符串替换函数,将$(obj)中的$(OBJS)置空

下面最终生成各种镜像文件
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
最后要生成的文件,U_BOOT_NAND在前面定义了,为u-boot-nand.bin

all依赖于$(ALL) 最终生成镜像文件,注意各种依赖关系
all:  $(ALL)

$(obj)u-boot.hex: $(obj)u-boot
  $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@

$(obj)u-boot.srec: $(obj)u-boot
  $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@

$(obj)u-boot.bin: $(obj)u-boot
  $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
  $(OBJDUMP) -d $< > $<.dis

$(obj)u-boot.img: $(obj)u-boot.bin
  ./tools/mkimage -A $(ARCH) -T firmware -C none
  -a $(TEXT_BASE) -e 0
  -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) |
   sed -e 's/'[  ]*$$/ for $(BOARD) board'/')
  -d $< $@

$(obj)u-boot.dis: $(obj)u-boot
  $(OBJDUMP) -d $< > $@

$(obj)u-boot:  depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
  UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed  -n -e 's/.*(__u_boot_cmd_.*)/-u1/p'|sort|uniq`;
  cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS)
   --start-group $(__LIBS) --end-group $(PLATFORM_LIBS)
   -Map u-boot.map -o u-boot

$(OBJS):
  $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))

$(LIBS):
  $(MAKE) -C $(dir $(subst $(obj),,$@))

$(SUBDIRS):
  $(MAKE) -C $@ all

$(NAND_SPL): version
  $(MAKE) -C nand_spl/board/$(BOARDDIR) all

$(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin
  cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin

version:
  @echo -n '#define U_BOOT_VERSION 'U-Boot ' > $(VERSION_FILE);
  echo -n '$(U_BOOT_VERSION)' >> $(VERSION_FILE);
  echo -n $(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion
    $(TOPDIR)) >> $(VERSION_FILE);
  echo ''' >> $(VERSION_FILE)

gdbtools:
  $(MAKE) -C tools/gdb all || exit 1

updater:
  $(MAKE) -C tools/updater all || exit 1

env:
  $(MAKE) -C tools/env all || exit 1

depend dep:
  for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done

tags ctags:
  ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include
    lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH)
    fs/cramfs fs/fat fs/fdos fs/jffs2
    net disk rtc dtt drivers drivers/sk98lin common
   ( -name CVS -prune ) -o ( -name '*.[ch]' -print )`

etags:
  etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include
    lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH)
    fs/cramfs fs/fat fs/fdos fs/jffs2
    net disk rtc dtt drivers drivers/sk98lin common
   ( -name CVS -prune ) -o ( -name '*.[ch]' -print )`

$(obj)System.map: $(obj)u-boot
  @$(NM) $< |
  grep -v '(compiled)|(.o$$)|( [aUw] )|(..ng$$)|(LASH[RL]DI)' |
  sort > $(obj)System.map
下面接着分析
unconfig:
 @rm -f $(obj)include/config.h $(obj)include/config.mk
  $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp
这句话已经分析过了,就是在mkconfig是先执行的操作,即删除上一次makeXXX时存在的头文件和包含文件

接下来很长一段是与平台和开发板相关的xxx_config定义,譬如在执行make smdk6410_config时
会找到如下定义:
smdk6410_config : unconfig
 @$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410

最后是clean命令的定义
clean:
 find $(OBJTREE) -type f
  ( -name 'core' -o -name '*.bak' -o -name '*~'
  -o -name '*~' -o -name '.depend*'
  -o -name '*.o'  -o -name '*.a'  ) -print
  | xargs rm -f
 rm -f u-boot*
 rm -f $(obj)examples/hello_world $(obj)examples/timer
       $(obj)examples/eepro100_eeprom $(obj)examples/sched
       $(obj)examples/mem_to_mem_idma2intr $(obj)examples/82559_eeprom
       $(obj)examples/smc91111_eeprom $(obj)examples/interrupt
       $(obj)examples/test_burst
 rm -f $(obj)tools/img2srec $(obj)tools/mkimage $(obj)tools/envcrc
  $(obj)tools/gen_eth_addr
 rm -f $(obj)tools/mpc86x_clk $(obj)tools/ncb
 rm -f $(obj)tools/easylogo/easylogo $(obj)tools/bmp_logo
 rm -f $(obj)tools/gdb/astest $(obj)tools/gdb/gdbcont $(obj)tools/gdb/gdbsend
 rm -f $(obj)tools/env/fw_printenv $(obj)tools/env/fw_setenv
 rm -f $(obj)board/cray/L1/bootscript.c $(obj)board/cray/L1/bootscript.image
 rm -f $(obj)board/netstar/eeprom $(obj)board/netstar/crcek $(obj)board/netstar/crcit
 rm -f $(obj)board/netstar/*.srec $(obj)board/netstar/*.bin
 rm -f $(obj)board/trab/trab_fkt $(obj)board/voiceblue/eeprom
 rm -f $(obj)board/integratorap/u-boot.lds $(obj)board/integratorcp/u-boot.lds
 rm -f $(obj)include/bmp_logo.h
 rm -f $(obj)nand_spl/u-boot-spl $(obj)nand_spl/u-boot-spl.map

[1] [2]
关键字:6  顶层  makefile 引用地址:uboot1.1.6顶层makefile详解

上一篇:uboot1.1.6顶层mkconfig详解
下一篇:8.时钟初始化

推荐阅读最新更新时间:2026-03-21 22:43

uboot1.1.6顶层makefile详解
VERSION = 1//主版本号 PATCHLEVEL = 1//次版本号 SUBLEVEL = 6//修正版本号 EXTRAVERSION =//版本号扩展 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)//这个Uboot的版本为1.1.6 VERSION_FILE = $(obj)include/version_autogenerated.h HOSTARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -
[单片机]
1_5.3.3_内核配置裁剪及启动流程_内核启动流程分析之Makefile_P
分析Makefile,主要是: 找到第1个文件,从这个文件入手分析启动流程; 链接脚本,分析文件分布情况。 涉及的文件分类如下: kbuild Makefile 首先来看子目录下面的Makefile,也就是kbuild Makefile,每个子目录下面都会有一个Makefile,它们的主要功能是设置该目录的文件的编译选项。 选取一个子目录下的Makefile来研究一下。 其中大部分的内容是设置文件的编译选项。 假设有两个文件a.c和b.c,如果需要单独的将它们编译进内核,可以使用如下语句: obj-y += a.o b.o 那么,如果要将这两个文件编成一个模块呢? 在内核的Document/kbui
[单片机]
<font color='red'>1</font>_5.3.3_内核配置裁剪及启动流程_内核启动流程分析之<font color='red'>Makefile</font>_P
中国汽车发展顶层设计思路 - 万钢主席2025百人会核心内容总结
万钢是中国 电动汽车 战略的重要奠基人和长期推动者,其身份与影响力体现在: 原科技部部长2007-2018年,科技部任内大力推动“863电动汽车专项”、 智能网联汽车 研发全国政协副主席拥有国家层级的宏观视角,推动 新能源 和科技政策顶层设计中国科协主席汇聚科技界智力资源,形成政策与产业之间的桥梁工程背景曾长期在德国奥迪、上汽工作,深谙汽车工程与技术路径。 他不仅是政策制定者,更是“懂技术、懂产业、懂国际”的汽车发展战略实干家。2025中国电动汽车百人会论坛上,万钢代表中国科协,围绕“实现汽车产业的高质量发展”,发表了系统性的演讲。 这份演讲算是中国汽车发展顶层设计思路。 以下是对万钢在2025中国电动汽车百人会
[汽车电子]
电力辅助服务市场顶层设计更完善
中国储能网讯: 新政策按照“谁受益、谁承担”的原则,进一步完善了辅助服务考核补偿机制,明确跨省跨区发电机组参与辅助服务的责任义务、参与方式和补偿分摊原则,建立用户参与的分担共享机制。 2021年12月24日,国家能源局发布了新修订的《电力并网运行管理规定》和《电力辅助服务管理办法》(以下简称“两份文件”),时隔十五年,两份文件重新修订,将开启我国电力辅助服务市场顶层设计的新构架。 业内认为,新修订的两份文件对并网主体的调度运行机制进行了大幅调整,适应了新能源大规模发展和电力市场改革的现实需求,对于压实各并网主体安全稳定责任,激励各主体发挥调节潜能具有积极作用。特别值得注意的是,新版《电力辅助服务管理办法》确立的
[新能源]
TQ210——S5PV210 uboot顶层config.mk分析
# # (C) Copyright 2000-2006 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # See file CREDITS for list of people who contributed to this # project. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Soft
[单片机]
缺乏顶层设计的增量配电
几天前,国家电网公司(下称国网)发布《进一步支持和推进业务增量配电业务改革的意见》(下简称《意见》),明确提出要支持、参与和推动增量配电改革。 该《意见》距离国网上一次发文提及增量配电业务,仅隔一个月。 所不同的是,从这份新发布的两千多字的文件中,行业似乎嗅到了国网态度的明显转变。“支持、推进、积极配合”等带有鲜明主观态度的字眼不断“挑逗”着增量配电企业和观望资本的神经。 “增量配电”一词已诞生4年零15天。作为新电改的产物,中共中央、国家发改委、国家能源局等重要部门,先后围绕这个新生名词下发了共20余个文件以推进其改革进程。 受政策鼓舞,“增量配电”受到各路资本热捧,一时间,大大小小的增量配电企业相继成立。但随
[新能源]
智能汽车顶层设计出炉,万亿市场规模待挖掘
智能汽车的发展战略终于尘埃落地。 近日,发改委、工信部、财政部等11部委联合印发《智能汽车创新发展战略》(下称“战略”)。战略指出,到2025年,中国标准智能汽车的技术创新、产业生态、基础设施、法规标准、产品监管和网络安全体系基本形成。到2035年,中国标准智能汽车体系全面建成。 “战略指明了方向,这将加快智能汽车的发展。”中国汽车流通协会副秘书长郎学红今日对第一汽车频道记者表示,关键技术的突破对智能汽车发展意义重大,而5G应用将起到推动作用。 调整目标 关于智能汽车的发展,2018年1月发改委就曾出台征求意见稿,其提出,到2020年智能汽车新车占比达到50%;大城市、高速公路的车用无线通信网络(LTE-V2X)覆
[汽车电子]
智能汽车<font color='red'>顶层</font>设计出炉,万亿市场规模待挖掘
欧盟打响顶层开始的AI科技战,新政或将硅谷巨头逼到墙角?
近日,谷歌母公司 Alphabet CEO 桑达尔·皮查伊、苹果 AI 高级副总裁约翰·詹南德雷亚,以及脸书 CEO 马克·扎克伯格……一时间,布鲁塞尔群贤毕至,只因为欧盟要对 AI 动手了。    他们期望游说欧盟高官在制定 AI 规则时网开一面。毕竟,欧盟委员会执行副主席玛格丽特·维斯塔格,这位铁娘子此前的隐私、反垄断、税收三板斧暴击,已经重创其锐气。    所以,这次 AI 监管时,他们必须据理力争,这不是分蛋糕,而是生死存亡。    其实,早在 1 月份,相关“白皮书”的草稿已经流出,称欧盟甚至考虑过 3-5 年内公共场所禁用人脸识别,以规避技术风险。    欧盟之严苛,再次令业界哗然,但这背后也许打响的是一场从顶层设计开
[嵌入式]
欧盟打响<font color='red'>顶层</font>开始的AI科技战,新政或将硅谷巨头逼到墙角?
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved