操作系统:ubuntu10.04
前言:
要完成自己的uboot,首先要熟悉广泛使用的Uboot的架构,实现。
而看linux的大项目的源码,切入点基本都是从makefile开始。
1,makefile详解:
如果对makefile有疑惑的请看:
*makefile 博文链接
-
(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 Software Foundatio; either version 2 of
-
# the License, or (at your option) any later version.
-
#
-
# This program is distributed in the hope that it will be useful,
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-
# GNU General Public License for more details.
-
#
-
# You should have received a copy of the GNU General Public License
-
# along with this program; if not, write to the Free Software
-
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-
# MA 02111-1307 USA
-
#
-
-
VERSION = 1
-
PATCHLEVEL = 1
-
SUBLEVEL = 6
-
EXTRAVERSION =
-
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-
VERSION_FILE = $(obj)include/version_autogenerated.h
-
-
#########################################################################
-
#@定义主机系统架构@:
-
# “sed –e”表示后面跟的是一串命令脚本,而表达式“s/abc/def/”表示要从标准输入中,
-
# 查找到内容为“abc”的,然后替换成“def”。其中“abc”表达式用可以使用“.”作为通配符。
-
# 命令“uname –m”将输出主机CPU的体系架构类型。作者的电脑使用Intel Core2系列的CPU,
-
# 因此“uname –m”输出“i686”。 “i686”可以匹配命令“sed -e s/i.86/i386/”中的“i.86”,
-
# 因此在作者的机器上执行Makefile,HOSTARCH 将被设置成“i386” 。
-
#########################################################################
-
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 –s”输出主机内核名字,作者使用Linux发行版Ubuntu11.10,因此“uname –s”结果是“Linux”。
-
# “tr '[:upper:]' '[:lower:]'”作用是将标准输入中的所有大写字母转换为响应的小写字母。
-
# 因此执行结果是将HOSTOS 设置为“linux”。
-
#########################################################################
-
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
-
sed -e 's/\(cygwin\).*/cygwin/')
-
-
#导出变量HOSTARCH HOSTOS SHELL,使别的文件可以使用这些变量
-
export HOSTARCH HOSTOS
-
-
# Deal with colliding definitions from tcsh etc.
-
VENDOR=
-
-
#########################################################################
-
#
-
# U-boot build supports producing a object files to the separate external
-
# directory. Two use cases are supported:
-
#
-
# 1) Add O= to the make command line
-
# 'make O=/tmp/build all'
-
#
-
# 2) Set environement variable BUILD_DIR to point to the desired location
-
# 'export BUILD_DIR=/tmp/build'
-
# 'make'
-
#
-
# The second approach can also be used with a MAKEALL script
-
# 'export BUILD_DIR=/tmp/build'
-
# './MAKEALL'
-
#
-
# Command line 'O=' setting overrides BUILD_DIR environent variable.
-
#
-
# When none of the above methods is used the local build is performed and
-
# the object files are placed in the source directory.
-
#
-
-
#########################################################################
-
#@设定编译输出目录@:
-
# 函数$( origin, variable) 输出的结果是一个字符串,输出结果由变量variable定义的方式决定,
-
# 若variable在命令行中定义过,则origin函数返回值为"command line"。
-
# 假若在命令行中执行了“export BUILD_DIR=/tmp/build”的命令,则“$(origin O)”值为“command line”,
-
# 而BUILD_DIR被设置为“/tmp/build”。
-
#
-
# 假若在命令行中执行了“make xx_config”的命令,则“$(origin O)”输出值不为为“command line”,
-
# 故BUILD_DIR没有被操作。
-
#########################################################################
-
ifdef O
-
ifeq ("$(origin O)", "command line")
-
BUILD_DIR := $(O)
-
endif
-
endif
-
-
#判断 BUILD_DIR 变量是否不为空,当前 BUILD_DIR 为 空,条件为假。
-
ifneq ($(BUILD_DIR),)
-
saved-output := $(BUILD_DIR)
-
-
#若${BUILD_DIR}表示的目录没有被创建,则创建该目录。
-
# Attempt to create a output directory.
-
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
-
-
#若$(BUILD_DIR)为创建失败或不存在,则将其赋值为当前目录路径(源代码目录)。
-
#并检查$(BUILD_DIR)目录是否存在。
-
#Pwd命令用以获取当前路径
-
# Verify if it was successful.
-
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
-
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
-
endif # ifneq ($(BUILD_DIR),)
-
-
#########################################################################
-
#CURDIR变量指示Make当前的工作目录,由于当前Make在U-Boot顶层目录执行Makefile,
-
#因此CURDIR此时就是U-Boot顶层目录。
-
#执行完上面的代码后, SRCTREE,src变量就是U-Boot代码顶层目录,而OBJTREE,obj变量就是输出目录,
-
#若没有定义BUILD_DIR环境变量,则SRCTREE,src变量与OBJTREE,obj变量都是U-Boot源代码目录。
-
#而MKCONFIG则表示U-Boot根目录下的mkconfig脚本。
-
#if函数计算OBJTREE的值,如果BUILD_DIR不为空,if函数的值就是BUILD_DIR,否则是CURDIR.
-
#CURDIR是个环境变量。代表当前文件的目录,即uboot根目录,设为 : ./。
-
# CURDIR = ./
-
# OBJTREE = ./
-
# SPLTREE = ./spl
-
# SRCTREE = ./
-
# TOPDIR = ./
-
# LNDIR = ./
-
#导出变量TOPDIR SRCTREE OBJTREE SPLTREE,使别的文件可以使用这些变量
-
#########################################################################
-
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
-
SRCTREE := $(CURDIR)
-
TOPDIR := $(SRCTREE)
-
LNDIR := $(OBJTREE)
-
export TOPDIR SRCTREE OBJTREE
-
-
# MKCONFIG = ./mkconfig
-
#导出变量MKCONFIG
-
MKCONFIG := $(SRCTREE)/mkconfig
-
export MKCONFIG
-
-
#########################################################################
-
#判断变量OBJTREE 与 SRCTREE 是否不相等,OBJTREE为./,SRCTREE为./,条件为假。
-
#########################################################################
-
ifneq ($(OBJTREE),$(SRCTREE))
-
REMOTE_BUILD := 1
-
export REMOTE_BUILD
-
endif
-
-
#########################################################################
-
#判断变量OBJTREE 与 SRCTREE 是否不相等,OBJTREE为./,SRCTREE为./,条件为假。
-
#则 obj 为 空
-
# src 为 空
-
#导出变量 obj src
-
#########################################################################
-
# $(obj) and (src) are defined in config.mk but here in main Makefile
-
# we also need them before config.mk is included which is the case for
-
# some targets like unconfig, clean, clobber, distclean, etc.
-
ifneq ($(OBJTREE),$(SRCTREE))
-
obj := $(OBJTREE)/
-
src := $(SRCTREE)/
-
else
-
obj :=
-
src :=
-
endif
-
export obj src
-
-
#########################################################################
-
#########################################################################
-
#使用“$(wildcard *.c) ”来获取工作目录下的所有的.c 文件列表
-
#在当前例子中,则是为了找到 ./include/config.mk
-
#判断是否找到 ./include/config.mk
-
#########################################################################
-
ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk))
-
-
#########################################################################
-
#包含 ./include/config.mk
-
# ARCH = arm
-
# CPU = arm920t
-
# BOARD = 100ask24x0
-
# VENDOR =
-
# SOC = s3c24x0
-
#########################################################################
-
# load ARCH, BOARD, and CPU configuration
-
include $(OBJTREE)/include/config.mk
-
export ARCH CPU BOARD VENDOR SOC
-
-
#########################################################################
-
#若主机架构与开发板结构相同,就使用主机的编译器,而不是交叉编译器
-
#当前 HOSTARCH 为 i386
-
#当前 ARCH 为 arm
-
#条件为假,则 CROSS_COMPILE 为交叉编译器,即 CROSS_COMPILE = arm-linux-
-
#########################################################################
-
ifndef CROSS_COMPILE
-
ifeq ($(HOSTARCH),ppc)
-
CROSS_COMPILE =
-
else
-
ifeq ($(ARCH),ppc)
-
CROSS_COMPILE = powerpc-linux-
-
endif
-
-
ifeq ($(ARCH),arm)
-
CROSS_COMPILE = arm-linux-
-
endif
-
-
ifeq ($(ARCH),i386)
-
ifeq ($(HOSTARCH),i386)
-
CROSS_COMPILE =
-
else
-
CROSS_COMPILE = i386-linux-
-
endif
-
endif
-
-
ifeq ($(ARCH),mips)
-
CROSS_COMPILE = mips_4KC-
-
endif
-
-
ifeq ($(ARCH),nios)
-
CROSS_COMPILE = nios-elf-
-
endif
-
-
ifeq ($(ARCH),nios2)
-
CROSS_COMPILE = nios2-elf-
-
endif
-
-
ifeq ($(ARCH),m68k)
-
CROSS_COMPILE = m68k-elf-
-
endif
-
-
ifeq ($(ARCH),microblaze)
-
CROSS_COMPILE = mb-
-
endif
-
-
ifeq ($(ARCH),blackfin)
-
CROSS_COMPILE = bfin-elf-
-
endif
-
-
ifeq ($(ARCH),avr32)
-
CROSS_COMPILE = avr32-
-
endif
-
endif
-
#($(HOSTARCH),ppc)
-
endif
-
#ifndef CROSS_COMPILE
-
-
export CROSS_COMPILE
-
-
#包含 ./config.mk 文件,其主要是一些变量和函数的定义,编译链接的参数设置以及依赖规则.
-
# load other configuration
-
include $(TOPDIR)/config.mk
-
-
#########################################################################
-
# U-Boot objects....order is important (i.e. start must be first)
-
-
#OBJS = cpu/arm920t/start.o
-
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),mpc83xx)
-
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
-
-
#########################################################################
-
#加前缀,如
-
#$(addprefix src/,foo bar)
-
#结果:src/foo src/bar
-
#当前 obj :=
-
#OBJS := cpu/arm920t/start.o
-
#########################################################################
-
OBJS := $(addprefix $(obj),$(OBJS))
-
-
LIBS = lib_generic/libgeneric.a
-
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
-
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
-
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)
-
#确保可以对LIBS进行操作
-
-
# 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)
-
-
#########################################################################
-
#如果CONFIG_NAND_U_BOOT变量是否等于 y,当前没有定义CONFIG_NAND_U_BOOT变量,条件为假。
-
#则不执行条件中的代码
-
#########################################################################
-
ifeq ($(CONFIG_NAND_U_BOOT),y)
-
NAND_SPL = nand_spl
-
U_BOOT_NAND = $(obj)u-boot-nand.bin
-
endif
-
-
-
#如果对 makefile中subst 函数有疑问的请看:http://blog.chinaunix.net/uid-28458801-id-4080763.html
-
#__OBJS := cpu/arm920t/start.o
-
#__LIBS := lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a
-
# cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a
-
# fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
-
# net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a
-
# drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a
-
# common/libcommon.a
-
__OBJS := $(subst $(obj),,$(OBJS))
-
__LIBS := $(subst $(obj),,$(LIBS))
-
-
#########################################################################
-
#########################################################################
-
-
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
-
-
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 $< $@
-
-
$(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_.*\)/-u\1/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
未完,待续。。。
阅读(1085) | 评论(0) | 转发(0) |