U-Boot移植之前期分析(上)

来源:互联网 发布:淘宝意外险 编辑:程序博客网 时间:2024/05/18 01:47

        老是看别人移植uboot,用别人移植好的uboot,今天终于下定决心自己移植一个uboot来玩玩,好歹我也是个软件开发人员啊。

        第一步:去ftp://ftp.denx.de/pub/u-boot/网站下载个uboot工程源码,为了防止环境出问题,我决定用个老一点的,于是就下了:u-boot-1.1.6.tar.bz2。

        第二步:解压源码:tar  jxvf  u-boot-1.1.6.tar.bz2。

        第三步:建立source insight工程

        好了完成以上三步之后,我们需要的前提条件都准备好了,下面在着手移植前需要大概了解一下u-boot的整体目录结构、配置编译及启动流程。

        一、整体目录:大体可以分为以下四类

        1. 平台相关或开发板相关的:board、cpu、lib_arm等(lib_xxx)

        2. 通用的函数:include、lib_generic、common

        3. 通用的设备驱动程序:disk、drivers、dtt、fs、nand_spl、net、post、rtc

        4. 工具、示例程序及文档:doc、examples、tools

       二、u-boot的配置编译过程(红色标记是关键部分)

       1. 顶层目录下makefile的分析过程

VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 6
### 添加子版本信息
EXTRAVERSION =(2014-04-27)
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
###版本信息输出文件
VERSION_FILE = $(obj)include/version_autogenerated.h
### 定义主机系统架构
# uname -m => i686
# “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 
# uname -s | tr '[:upper:]' '[:lower:]'  =>  linux
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
   sed -e 's/\(cygwin\).*/cygwin/')
###输出变量
export HOSTARCH HOSTOS

###设定编译输出目录 
#$(origin O) => undefine
#函数$( origin, variable) 输出的结果是一个字符串,输出结果由变量variable定义的方式决定,
#若variable在命令行中定义过,则origin函数返回值为"command line"。假若在命令行中执行了
#“export BUILD_DIR=/tmp/build”的命令,则“$(origin O)”值为“command line”,而BUILD_DIR被设置为“/tmp/build”。
ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif
#若${BUILD_DIR}表示的目录没有定义,则创建该目录。
#$(BUILD_DIR) $(saved-output) => 空
ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
# Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
#若$(BUILD_DIR)为空,则将其赋值为当前目录路径(源代码目录)。并检查$(BUILD_DIR)目录是否存在。
$(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脚本。 
#CURDIR => 顶层目录
#SRCTREE => 顶层目录
#LNDIR OBJTREE => 输出目录即顶层目录
### OBJTREE和LNDIR为存放生成文件的目录,TOPDIR与SRCTREE为源码所在目录
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE

### 顶层目录下的配置文件
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG

### 本地编译不会执行这几行代码
ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD := 1
export REMOTE_BUILD
endif
# $(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
#########################################################################
ifeq ($(OBJTREE)/include/config.mk,$(wildcard $(OBJTREE)/include/config.mk))
# load ARCH, BOARD, and CPU configuration
include $(OBJTREE)/include/config.mk
export ARCH CPU BOARD VENDOR SOC

.......

#确定编译工具

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

#确定链接选项指定链接文件

# load other configuration
include $(TOPDIR)/config.mk

{

###注:此处是$(TOPDIR)/config.mk下比较重要的内容

.......

ifdefVENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
endif

......

ifeq ($(CONFIG_NAND_U_BOOT),y)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
else
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
endif

......

LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)

}

#uboot编译连接的第一个文件

OBJS  = cpu/$(CPU)/start.o

.......

#uboot编译过程中会编译的库文件

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)

#make时编译执行的目录

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

#调用相应子目录下的makefile
$(OBJS):
$(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))
$(LIBS):
$(MAKE) -C $(dir $(subst $(obj),,$@))
$(SUBDIRS):
$(MAKE) -C $@ all

#make MY_JZ2440_config首先要执行的命令:用于删除上一次的配置信息

#########################################################################
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp

#make MY_JZ2440_config时执行的操作

#重点是:@$(MKCONFIG) $(@:_config=) arm arm920t MY_JZ2440 sumsung s3c24x0 

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  add by lhbo
#  MY_JZ2440_config
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MY_JZ2440_config : unconfig
##  step0:unconfig是用于清楚上一次的config信息等
##  step1:输出一些基本信息
@echo "=============================================="
@echo "=================made by lhbo================="
@echo "=============================================="
@echo "UBOOT Version : $(U_BOOT_VERSION)" 
@echo "HOST ARCH     : $(HOSTARCH)"
@echo "HOST OS       : $(HOSTOS)"
@echo "BUILD_DIR     : $(BUILD_DIR)"
@echo "obj           : $(obj)"
@echo "TOPDIR        : $(TOPDIR)"
@echo "SRCTREE       : $(SRCTREE)"
@echo "OBJTREE       : $(OBJTREE)"
@echo "MKCONFIG      : $(MKCONFIG)"
@echo "=============================================="
##  step2:调用执行配置脚本
##  target ARCH CPU BOARD VENDOR SOC
@$(MKCONFIG) $(@:_config=) arm arm920t MY_JZ2440 sumsung s3c24x0 

        注:2. 顶层目录下mkconfig的分析过程 和 三、u-boot启动流程 内容请见博文“U-Boot移植之前期分析(下)”

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 两岁宝宝认被子盖怎么办 小孩吃多了发烧怎么办 两岁宝宝拉蛔虫怎么办 吃了长蛆的东西怎么办 被蜱虫咬了又找不到虫子怎么办 木家具生黑虫子怎么办 吃了发霉的面包怎么办 种的韭菜有蛆怎么办 活狗身上长蛆虫怎么办 狗身上会有蛆虫怎么办 狗身上长满了蛆怎么办 房间墙上有很多小虫子怎么办 床上有许多小虫子怎么办? 店里有许多小虫子怎么办 房间潮湿有很多小虫子怎么办 家里潮湿墙上发霉长小虫怎么办? 房间有小飞虫子怎么办 狗被灭虫剂喷了怎么办 吃鸡玩久了手机屏幕很涩怎么办 超东卧室太阳晒怎么办 床头上的布破了怎么办 老年机全静音了怎么办 老年机手机不亮怎么办 70岁老人耳朵聋怎么办 血压太低了头晕怎么办 血压高忽然变低怎么办 血压高眼睛红了怎么办 高血压200降不下去.怎么办 高血压吃药降不下来怎么办 合肥房子卖了户口怎么办 吃了粽子胃难受怎么办 突然血压高怎么办需要吃药吗? 胃一阵阵疼然后拉肚子怎么办 橱子和墙壁不平怎么办 复印选项是英文不认识怎么办 防盗门锁与门框结合不好怎么办 仿瓷涂料墙壁脏了怎么办 油笔画到墙纸上怎么办 水笔画在墙纸上怎么办 屋里有股石灰味怎么办 厨房太阳对着晒怎么办