Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5497300
  • 博文数量: 579
  • 博客积分: 1548
  • 博客等级: 上尉
  • 技术积分: 16621
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-12 15:29
个人简介

http://www.csdn.net/ http://www.arm.com/zh/ https://www.kernel.org/ http://www.linuxpk.com/ http://www.51develop.net/ http://linux.chinaitlab.com/ http://www.embeddedlinux.org.cn http://bbs.pediy.com/

文章分类

全部博文(579)

文章存档

2018年(18)

2015年(91)

2014年(159)

2013年(231)

2012年(80)

分类: 嵌入式

2014-01-15 18:44:07

操作系统:ubuntu10.04 


前言:
    要完成自己的uboot,首先要熟悉广泛使用的Uboot的架构,实现。
    而看linux的大项目的源码,切入点基本都是从makefile开始。

1,makefile详解:
    如果对makefile有疑惑的请看:*makefile 博文链接  

点击(此处)折叠或打开

  1. (C) Copyright 2000-2006
  2. # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  3. #
  4. # See file CREDITS for list of people who contributed to this
  5. # project.
  6. #
  7. # This program is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU General Public License as
  9. # published by the Free Software Foundatio; either version 2 of
  10. # the License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. # MA 02111-1307 USA
  21. #

  22. VERSION = 1
  23. PATCHLEVEL = 1
  24. SUBLEVEL = 6
  25. EXTRAVERSION =
  26. U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
  27. VERSION_FILE = $(obj)include/version_autogenerated.h

  28. #########################################################################
  29. #@定义主机系统架构@:
  30. # “sed –e”表示后面跟的是一串命令脚本,而表达式“s/abc/def/”表示要从标准输入中,
  31. # 查找到内容为“abc”的,然后替换成“def”。其中“abc”表达式用可以使用“.”作为通配符。
  32. # 命令“uname –m”将输出主机CPU的体系架构类型。作者的电脑使用Intel Core2系列的CPU,
  33. # 因此“uname –m”输出“i686”。 “i686”可以匹配命令“sed -e s/i.86/i386/”中的“i.86”,
  34. # 因此在作者的机器上执行Makefile,HOSTARCH 将被设置成“i386” 。
  35. #########################################################################
  36. HOSTARCH := $(shell uname -m | \
  37.     sed -e s/i.86/i386/ \
  38.      -e s/sun4u/sparc64/ \
  39.      -e s/arm.*/arm/ \
  40.      -e s/sa110/arm/ \
  41.      -e s/powerpc/ppc/ \
  42.      -e s/macppc/ppc/)

  43. #########################################################################
  44. #@定义主机操作系统类型@:
  45. # “uname –s”输出主机内核名字,作者使用Linux发行版Ubuntu11.10,因此“uname –s”结果是“Linux”。
  46. # “tr '[:upper:]' '[:lower:]'”作用是将标准输入中的所有大写字母转换为响应的小写字母。
  47. # 因此执行结果是将HOSTOS 设置为“linux”。
  48. #########################################################################
  49. HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
  50.      sed -e 's/\(cygwin\).*/cygwin/')

  51.         #导出变量HOSTARCH HOSTOS SHELL,使别的文件可以使用这些变量
  52. export HOSTARCH HOSTOS

  53. # Deal with colliding definitions from tcsh etc.
  54. VENDOR=

  55. #########################################################################
  56. #
  57. # U-boot build supports producing a object files to the separate external
  58. # directory. Two use cases are supported:
  59. #
  60. # 1) Add O= to the make command line
  61. # 'make O=/tmp/build all'
  62. #
  63. # 2) Set environement variable BUILD_DIR to point to the desired location
  64. # 'export BUILD_DIR=/tmp/build'
  65. # 'make'
  66. #
  67. # The second approach can also be used with a MAKEALL script
  68. # 'export BUILD_DIR=/tmp/build'
  69. # './MAKEALL'
  70. #
  71. # Command line 'O=' setting overrides BUILD_DIR environent variable.
  72. #
  73. # When none of the above methods is used the local build is performed and
  74. # the object files are placed in the source directory.
  75. #

  76. #########################################################################
  77. #@设定编译输出目录@:
  78. # 函数$( origin, variable) 输出的结果是一个字符串,输出结果由变量variable定义的方式决定,
  79. # 若variable在命令行中定义过,则origin函数返回值为"command line"
  80. # 假若在命令行中执行了“export BUILD_DIR=/tmp/build”的命令,则“$(origin O)”值为“command line”,
  81. # 而BUILD_DIR被设置为“/tmp/build”。
  82. #
  83. # 假若在命令行中执行了“make xx_config”的命令,则“$(origin O)”输出值不为为“command line”,
  84. # 故BUILD_DIR没有被操作。
  85. #########################################################################
  86. ifdef O
  87. ifeq ("$(origin O)", "command line")
  88. BUILD_DIR := $(O)
  89. endif
  90. endif

  91. #判断 BUILD_DIR 变量是否不为空,当前 BUILD_DIR 为 空,条件为假。
  92. ifneq ($(BUILD_DIR),)
  93. saved-output := $(BUILD_DIR)

  94. #若${BUILD_DIR}表示的目录没有被创建,则创建该目录。
  95. # Attempt to create a output directory.
  96. $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})

  97. #若$(BUILD_DIR)为创建失败或不存在,则将其赋值为当前目录路径(源代码目录)。
  98. #并检查$(BUILD_DIR)目录是否存在。
  99. #Pwd命令用以获取当前路径
  100. # Verify if it was successful.
  101. BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
  102. $(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
  103. endif # ifneq ($(BUILD_DIR),)

  104. #########################################################################
  105. #CURDIR变量指示Make当前的工作目录,由于当前Make在U-Boot顶层目录执行Makefile,
  106. #因此CURDIR此时就是U-Boot顶层目录。
  107. #执行完上面的代码后, SRCTREE,src变量就是U-Boot代码顶层目录,而OBJTREE,obj变量就是输出目录,
  108. #若没有定义BUILD_DIR环境变量,则SRCTREE,src变量与OBJTREE,obj变量都是U-Boot源代码目录。
  109. #而MKCONFIG则表示U-Boot根目录下的mkconfig脚本。
  110. #if函数计算OBJTREE的值,如果BUILD_DIR不为空,if函数的值就是BUILD_DIR,否则是CURDIR.
  111. #CURDIR是个环境变量。代表当前文件的目录,即uboot根目录,设为 : ./
  112. # CURDIR = ./
  113. # OBJTREE = ./
  114. # SPLTREE = ./spl
  115. # SRCTREE = ./
  116. # TOPDIR = ./
  117. # LNDIR = ./
  118. #导出变量TOPDIR SRCTREE OBJTREE SPLTREE,使别的文件可以使用这些变量
  119. #########################################################################
  120. OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
  121. SRCTREE := $(CURDIR)
  122. TOPDIR := $(SRCTREE)
  123. LNDIR := $(OBJTREE)
  124. export TOPDIR SRCTREE OBJTREE

  125. # MKCONFIG = ./mkconfig
  126. #导出变量MKCONFIG
  127. MKCONFIG := $(SRCTREE)/mkconfig
  128. export MKCONFIG

  129. #########################################################################
  130. #判断变量OBJTREE 与 SRCTREE 是否不相等,OBJTREE为./,SRCTREE为./,条件为假。
  131. #########################################################################
  132. ifneq ($(OBJTREE),$(SRCTREE))
  133. REMOTE_BUILD := 1
  134. export REMOTE_BUILD
  135. endif

  136. #########################################################################
  137. #判断变量OBJTREE 与 SRCTREE 是否不相等,OBJTREE为./,SRCTREE为./,条件为假。
  138. #则 obj 为 空
  139. # src 为 空
  140. #导出变量 obj src
  141. #########################################################################
  142. # $(obj) and (src) are defined in config.mk but here in main Makefile
  143. # we also need them before config.mk is included which is the case for
  144. # some targets like unconfig, clean, clobber, distclean, etc.
  145. ifneq ($(OBJTREE),$(SRCTREE))
  146. obj := $(OBJTREE)/
  147. src := $(SRCTREE)/
  148. else
  149. obj :=
  150. src :=
  151. endif
  152. export obj src

  153. #########################################################################
  154. #########################################################################
  155. #使用“$(wildcard *.c) ”来获取工作目录下的所有的.c 文件列表
  156. #在当前例子中,则是为了找到 ./include/config.mk
  157. #判断是否找到 ./include/config.mk
  158. #########################################################################
  159. ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk))

  160. #########################################################################
  161. #包含 ./include/config.mk
  162. # ARCH = arm
  163. # CPU = arm920t
  164. # BOARD = 100ask24x0
  165. # VENDOR =
  166. # SOC = s3c24x0
  167. #########################################################################
  168. # load ARCH, BOARD, and CPU configuration
  169. include $(OBJTREE)/include/config.mk
  170. export ARCH CPU BOARD VENDOR SOC

  171. #########################################################################
  172. #若主机架构与开发板结构相同,就使用主机的编译器,而不是交叉编译器
  173. #当前 HOSTARCH 为 i386
  174. #当前 ARCH 为 arm
  175. #条件为假,则 CROSS_COMPILE 为交叉编译器,即 CROSS_COMPILE = arm-linux-
  176. #########################################################################
  177. ifndef CROSS_COMPILE
  178. ifeq ($(HOSTARCH),ppc)
  179. CROSS_COMPILE =
  180. else
  181.     ifeq ($(ARCH),ppc)
  182.     CROSS_COMPILE = powerpc-linux-
  183.     endif
  184.     
  185.     ifeq ($(ARCH),arm)
  186.     CROSS_COMPILE = arm-linux-
  187.     endif
  188.     
  189.     ifeq ($(ARCH),i386)
  190.         ifeq ($(HOSTARCH),i386)
  191.         CROSS_COMPILE =
  192.         else
  193.         CROSS_COMPILE = i386-linux-
  194.         endif
  195.     endif
  196.     
  197.     ifeq ($(ARCH),mips)
  198.     CROSS_COMPILE = mips_4KC-
  199.     endif
  200.     
  201.     ifeq ($(ARCH),nios)
  202.     CROSS_COMPILE = nios-elf-
  203.     endif
  204.     
  205.     ifeq ($(ARCH),nios2)
  206.     CROSS_COMPILE = nios2-elf-
  207.     endif
  208.     
  209.     ifeq ($(ARCH),m68k)
  210.     CROSS_COMPILE = m68k-elf-
  211.     endif
  212.     
  213.     ifeq ($(ARCH),microblaze)
  214.     CROSS_COMPILE = mb-
  215.     endif
  216.     
  217.     ifeq ($(ARCH),blackfin)
  218.     CROSS_COMPILE = bfin-elf-
  219.     endif
  220.     
  221.     ifeq ($(ARCH),avr32)
  222.     CROSS_COMPILE = avr32-
  223.     endif
  224. endif
  225. #($(HOSTARCH),ppc)
  226. endif
  227. #ifndef CROSS_COMPILE

  228. export CROSS_COMPILE

  229. #包含 ./config.mk 文件,其主要是一些变量和函数的定义,编译链接的参数设置以及依赖规则.
  230. # load other configuration
  231. include $(TOPDIR)/config.mk

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

  234. #OBJS = cpu/arm920t/start.o
  235. OBJS = cpu/$(CPU)/start.o

  236. ifeq ($(CPU),i386)
  237. OBJS += cpu/$(CPU)/start16.o
  238. OBJS += cpu/$(CPU)/reset.o
  239. endif

  240. ifeq ($(CPU),ppc4xx)
  241. OBJS += cpu/$(CPU)/resetvec.o
  242. endif

  243. ifeq ($(CPU),mpc83xx)
  244. OBJS += cpu/$(CPU)/resetvec.o
  245. endif

  246. ifeq ($(CPU),mpc85xx)
  247. OBJS += cpu/$(CPU)/resetvec.o
  248. endif

  249. ifeq ($(CPU),mpc86xx)
  250. OBJS += cpu/$(CPU)/resetvec.o
  251. endif

  252. ifeq ($(CPU),bf533)
  253. OBJS += cpu/$(CPU)/start1.o cpu/$(CPU)/interrupt.o cpu/$(CPU)/cache.o
  254. OBJS += cpu/$(CPU)/cplbhdlr.o cpu/$(CPU)/cplbmgr.o cpu/$(CPU)/flush.o
  255. endif

  256. #########################################################################
  257. #加前缀,如
  258. #$(addprefix src/,foo bar)
  259. #结果:src/foo src/bar
  260. #当前 obj :=
  261. #OBJS := cpu/arm920t/start.o
  262. #########################################################################
  263. OBJS := $(addprefix $(obj),$(OBJS))

  264. LIBS = lib_generic/libgeneric.a
  265. LIBS += board/$(BOARDDIR)/lib$(BOARD).a
  266. LIBS += cpu/$(CPU)/lib$(CPU).a

  267. ifdef SOC
  268. LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
  269. endif

  270. LIBS += lib_$(ARCH)/lib$(ARCH).a
  271. LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
  272.     fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
  273. LIBS += net/libnet.a
  274. LIBS += disk/libdisk.a
  275. LIBS += rtc/librtc.a
  276. LIBS += dtt/libdtt.a
  277. LIBS += drivers/libdrivers.a
  278. LIBS += drivers/nand/libnand.a
  279. LIBS += drivers/nand_legacy/libnand_legacy.a
  280. LIBS += drivers/sk98lin/libsk98lin.a
  281. LIBS += post/libpost.a post/cpu/libcpu.a
  282. LIBS += common/libcommon.a
  283. LIBS += $(BOARDLIBS)

  284. LIBS := $(addprefix $(obj),$(LIBS))
  285. .PHONY : $(LIBS)
  286. #确保可以对LIBS进行操作

  287. # Add GCC lib
  288. PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc

  289. # The "tools" are needed early, so put this first
  290. # Don't include stuff already done in $(LIBS)
  291. SUBDIRS = tools \
  292.      examples \
  293.      post \
  294.      post/cpu
  295. .PHONY : $(SUBDIRS)

  296. #########################################################################
  297. #如果CONFIG_NAND_U_BOOT变量是否等于 y,当前没有定义CONFIG_NAND_U_BOOT变量,条件为假。
  298. #则不执行条件中的代码
  299. #########################################################################
  300. ifeq ($(CONFIG_NAND_U_BOOT),y)
  301. NAND_SPL = nand_spl
  302. U_BOOT_NAND = $(obj)u-boot-nand.bin
  303. endif


  304. #如果对 makefile中subst 函数有疑问的请看:http://blog.chinaunix.net/uid-28458801-id-4080763.html
  305. #__OBJS := cpu/arm920t/start.o
  306. #__LIBS := lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a
  307. # cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a
  308. # fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
  309. # net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a
  310. # drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a
  311. # common/libcommon.a
  312. __OBJS := $(subst $(obj),,$(OBJS))
  313. __LIBS := $(subst $(obj),,$(LIBS))

  314. #########################################################################
  315. #########################################################################

  316. ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)

  317. all: $(ALL)

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

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

  322. $(obj)u-boot.bin: $(obj)u-boot
  323.         $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

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

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

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

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

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

  341. $(SUBDIRS):
  342.         $(MAKE) -C $@ all

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






未完,待续。。。


阅读(7493) | 评论(1) | 转发(7) |
给主人留下些什么吧!~~

jtou1002015-05-14 16:38:11

写得真好,如果能在文章的前面或者后面把makefile所完成的功能做一个简单的总结就完美了