【u-boot分析】
#make ITSN_s3c44b0_config
执行Makefile中的下面语句:
ITSN_s3c44b0_config : unconfig
@./mkconfig$(@:_config=) arm s3c44b0 s3c44b0 itsn
替换: ./mkconfig ITSN_s3c44b0 arm s3c44b0 s3c44b0 itsn
对应参数 $0 $1 $2 $3 $4 $5
./mkconfig表示当前目录下的mkconfig脚本文件,内容如下:
#!/bin/sh -e
# Script to create header files and linksto configure
# U-Boot for a specific board.
#
# Parameters: Target Architecture CPU Board
#
# (C) 2002 DENX Software Engineering,Wolfgang Denk <wd@denx.de>
#
APPEND=no #Default: Create new config file
while [ $# -gt 0 ] ; do #参数个数大于0
case"$1" in #分析参数ITSN_s3c44b0,看该参数有无--、-a、*
--)shift ; break ;;
-a)shift ; APPEND=yes ;;
*) break ;;
esac
done
[ $# -lt 4 ] && exit 1 #参数个数小于4则退出
[ $# -gt 5 ] && exit 1 #注意:[$# -lt 4 ] || exit 1则表示前面的条件成立”||”后面的就不执行
#可以这里理解[]为if(),&&为then,||为else。
echo "Configuring for $1board..."
#上面语句替换为:echo "Configuring for ITSN_s3c44b0 board..."
cd ./include
#
# Create link to architecture specificheaders
#
rm -f asm #删除asm文件
ln -s asm-$2 asm # ln -s asm-arm asm
rm -f asm-$2/arch # rm -f asm-arm/arch
ln -s arch-$3 asm-$2/arch # ln -sarch-s3c44b0 asm-arm/arch
if [ "$2" = "arm" ] ;then
rm-f asm-$2/proc
ln-s proc-armv asm-$2/proc
fi
#
# Create include file for Make
#
echo "ARCH = $2" > config.mk #创建config.mk文件,并且ARCH = arm加入到文件中
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >>config.mk
[ "$5" ] && echo"VENDOR = $5" >> config.mk
# config.mk(注意:是cd到了include目录中)中最终的内容为:
# ARCH =arm
# CPU = s3c44b0
# BOARD = s3c44b0
# VENDOR = itsn
#
# Create board specific header file
#
if [ "$APPEND" = "yes"] # Append to existing config file
then
echo>> config.h
else
>config.h # Create new config file
fi
echo "/* Automatically generated - donot edit */" >>config.h
echo "#include <configs/$1.h>">>config.h
#最后config.h的内容为:
# /* Automatically generated - do not edit*/
# #include <configs/ITSN_s3c44b0.h>
exit 0
【注意:include/configs/ITSN_s3c44b0.h文件中就配置相关参数】
在#make ITSN_s3c44b0_config后,在include目录下生成了config.mk和config.h两个文件。
在Makefile文件中会被包含进去:includeinclude/config.mk
config.mk文件在的参数将被引用:
如:
OBJS = cpu/$(CPU)/start.oà OBJS = cpu/s3c44b0/start.o
LIBS = lib_generic/libgeneric.a
LIBS+=board/$(BOARDDIR)/lib$(BOARD).aàLIBS+=board/itsn/s3c44b0/libs3c44b0.a
LIBS +=cpu/$(CPU)/lib$(CPU).aà LIBS += cpu/s3c44b0/libs3c44b0.a
LIBS +=lib_$(ARCH)/lib$(ARCH).aà LIBS += lib_arm /libarm.a
……
接下来就执行:
#make
执行make时就会找到当前目录下的Makefile文件执行:all: xxx
ALL = u-boot.srec u-boot.bin System.map
all: $(ALL)
u-boot.srec: u-boot
$(OBJCOPY)${OBJCFLAGS} -O srec $< $@
u-boot.bin: u-boot
$(OBJCOPY)${OBJCFLAGS} -O binary $< $@
u-boot.img: 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' include/version.h | \
sed-e 's/"[ ]*$$/ for $(BOARD)board"/') \
-d$< $@
u-boot.dis: u-boot
$(OBJDUMP)-d $< > $@
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)$(PLATFORM_LIBS) --end-group \
-Map u-boot.map -o u-boot
分析一下上面代码:
1、$(LD)à在该目录下的config.mk中定义的变量为LD = $(CROSS_COMPILE)ld
在该目录下的Makefile中又定义了$(CROSS_COMPILE)变量
ifeq ($(ARCH),arm)
#itsn modify
#CROSS_COMPILE =arm-linux-
CROSS_COMPILE = arm-elf-
Endif
……
export CROSS_COMPILE
所以$(LD)=arm-elf-ld命令,arm-elf-ld命令的参数由$(LDFLAGS)变量提供。
2、$(LDFLAGS)à在该目录下的config.mk中定义的变量为LDFLAGS += -Bstatic \
-T $(LDSCRIPT) -Ttext$(TEXT_BASE) $(PLATFORM_LDFLAGS)
在该config.mk中变量LDSCRIPT :=$(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
其中$( TOPDIR)被定义在该目录下的Makefile中:
TOPDIR :=$(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd;fi)
#TOPDIR := $(shell pwd)
export TOPDIR
其中$( BOARDDIR)被定义在该目录下的config.mk中:
ifdef VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD) # $(BOARD)变量又在我们mkconfig生成的config.mk文件中
endif
注意:VENDOR被定义了的,所以BOARDDIR=itsn/s3c44b0 |
最后LDSCRIPT :=$(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
替换为:LDSCRIPT := /u-boot/board/itsn/s3c44b0/u-boot.lds
$(TEXT_BASE)变量则在$(TOPDIR)/board/$(BOARDDIR)/config.mk中定义的。
TEXT_BASE = 0x0C700000
变量$(PLATFORM_LDFLAGS)在$(TOPDIR)/config.mk中定义为:PLATFORM_LDFLAGS =
最后LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext$(TEXT_BASE) \
$(PLATFORM_LDFLAGS)
替换为:LDFLAGS += -Bstatic –T /u-boot/board/itsn/s3c44b0/u-boot.lds–Ttext 0x0C700000
$(LD) $(LDFLAGS)变换为: arm-elf-ld -Bstatic –T /u-boot/board/itsn/s3c44b0/u-boot.lds –Ttext 0x0C700000 |
在$(TOPDIR)/Makefile中定义了$(OBJS)和$(LIBS):
OBJS = cpu/$(CPU)/start.oà OBJS = cpu/s3c44b0/start.o
LIBS = lib_generic/libgeneric.a
LIBS+=board/$(BOARDDIR)/lib$(BOARD).aàLIBS+=board/itsn/s3c44b0/libs3c44b0.a
LIBS +=cpu/$(CPU)/lib$(CPU).aà LIBS += cpu/s3c44b0/libs3c44b0.a
LIBS +=lib_$(ARCH)/lib$(ARCH).aà LIBS += lib_arm /libarm.a
……
变量$( PLATFORM_LIBS)定义在$(TOPDIR)/config.mk中
PLATFORM_LIBS +=--no-warn-mismatch -L $(shell dirname `$(CC) $(CFLAGS)-print-libgcc-file-name`) -lgcc
u-boot.lds内容为:
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering,wd@denx.de.
*
*/
OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start) //入口标识
SECTIONS
{
. = 0; /*这里将表示链接地址为0+ Ttext =0x0C700000*/
. = ALIGN(4);
.text :
{
cpu/s3c44b0/start.o (.text) //代码开始处为cpu/s3c44b0/start.s
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) } //u-boot自己定义的一个段
__u_boot_cmd_end = .;
armboot_end_data = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}