博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

飞翔,嵌入式linux

linux嵌入式系统必将大行于天下。专注于linux嵌入式系统的搭键,专注于高效稳定软件的开发,专注底层程序调试技术。
  feixiang.cublog.cn

关于作者
姓名:飞翔
Email:loughsky@sina.com
职业:IT
年龄:32
位置:北京
个性介绍:专注在嵌入式操作系统,以及高效程序调试
|| << >> ||
我的分类


U-Boot Hacking
最近又在试着将U-Boot移植到一个硬件配置类似于smdk2410的开发板(深圳优龙ST2410)上,但尚未成功。但对于U-Boot的又有了新的认识,记录于此。
本文以u-boot-1.1.4为例进行分析,其源代码可以在ftp://ftp.denx.de/pub/u-boot/处下载。U-Boot的配置以make smdk2410_config为例,交叉编译工具链使用cross-2.95.3。
首先来看看在u-boot-1.1.4目录下make smdk2410_config命令的执行过程。Makefile第1506行开始处有:
[code]
smdk2410_config : unconfig
        @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0      
[/code]
而unconfig依赖的内容出现在Makefile的第210行:
[code]
unconfig :
        @rm -f include/config.h include/config.mk board/*/config.tmp
[/code]
可以看到unconfig中的命令内容是强制删除上次配置过程中生成的一些配置文件。
我们再回到smdk2410_config中来,它所执行的命令则是u-boot-1.1.4/mkconfig这个shell脚本,并给这个脚本传递了6个参数,依次是smdk2410, arm, arm920t, smdk2410, NULL和s3c24x0。查看mkconfig脚本的内容,第6行的注释给出了这些参数的意义:Target Architecture CPU Board [VENDOR] [SOC],并且可以看出最后两个参数的值可以是NULL。
第24行会使得终端命令行显示“Configuring for smdk2410 board...”:
[code]
echo "Configuring for $1 board..."
[/code]
第26行使得当前工作目录转换到u-boot-1.1.4/include目录:
[code]
cd ./include
[/code]
第31行到第44行的代码用于建立针对特定体系结构的头文件目录的符号链接:
[code]
rm -f asm
ln -s asm-$2 asm
rm -f asm-$2/arch
if [ -z "$6" -o "$6" = "NULL" ] ; then
        ln -s arch-$3 asm-$2/arch
else
        ln -s arch-$6 asm-$2/arch
fi
if [ "$2" = "arm" ] ; then
        rm -f asm-$2/proc
        ln -s proc-armv asm-$2/proc
fi
[/code]
以上这段代码执行完毕之后将建立的符号链接有:
include/asm -> include/asm-arm
include/asm-arm/arch -> include/asm-arm/arch-s3c24x0
include/asm-arm/proc -> include/asm-arm/proc-armv
接下来的第49行到第55行的代码利用echo命令生成include/config.mk文件并使用传递的6个参数来填充其中的内容:
[code]
echo "ARCH   = $2" >  config.mk
echo "CPU    = $3" >> config.mk
echo "BOARD  = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk
[/code]
最后的第60行到第67行的代码同样利用了echo命令来生成include/config.h文件:
[code]
if [ "$APPEND" = "yes" ] # Append to existing config file
then
 echo >> config.h
else
 > config.h  # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h
[/code]
 
执行完毕了make smdk2410_config命令之后,接下来就可以使用make命令来编译U-Boot了,最终生成我们将要烧写到Flash中的二进制映像文件u-boot.bin。这里编译U-Boot我们直接使用了make命令,相当于执行的是Makefile中的all目标,下面就来看看这个all目标的执行流程。
第143行说明了all目标的依赖是ALL变量的内容:
[code]
all:        $(ALL)
[/code]
之前的第141行对ALL变量进行了赋值:
[code]
ALL = u-boot.srec u-boot.bin System.map
[/code]
从而all目标的依赖实际上是u-boot.srec,u-boot.bin和System.map。由于我们最终需要的是u-boot.bin这个二进制映像文件,那么我们首先来看看u-boot.bin这个同名的依赖又是什么。
第151行和第152行的代码告诉我们u-boot.bin又依赖于u-boot:
[code]
u-boot.bin: u-boot
        $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
[/code]
建立u-boot的规则出现在第164行到168行:
[code]
u-boot:  depend $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
        UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
        $(LD) $(LDFLAGS) $$UNDEF_SYM $(OBJS) \
        --start-group $(LIBS) --end-group $(PLATFORM_LIBS) \
        -Map u-boot.map -o u-boot
[/code]
可以看到u-boot的依赖有depend,$(SUBDIRS),$(OBJS),$(LIBS),$(LDSCRIPT),接着一一分解。
depend在第179行:
[code]
depend dep:
        @for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir .depend ; done
[/code]
$(SUBDIRS)在第173行:
[code]
$(SUBDIRS):
        $(MAKE) -C $@ all
[/code]
对$(OBJS)的赋值从第92行开始,可以看到它的具体内容是由$(CPU)变量的值决定的:
[code]
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
[/code]
对$(LIBS)的赋值从第107行开始,可以看到它的具体内容是由$(CPU)变量的值决定的:
[code]
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/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
.PHONY : $(LIBS)
[/code]
可以看到$(LIBS)变量的值都是和$(CPU),$(SOC)有关的以及通用的静态链接库。这些静态链接库的建立由第170行开始的目标来完成:
[code]
$(LIBS):
        $(MAKE) -C `dirname $@`
[/code]

 原文地址 http://blog.chinaunix.net/u/5192/showart_244932.html
发表于: 2007-06-25,修改于: 2007-06-25 17:55,已浏览1215次,有评论0条 推荐 投诉


网友评论
 发表评论