由于u-boot比较庞大,所以我们分开来分析,对于一个大型的项目我们想快速的了解其代码架构和内容,最方便的方法就是分析Makefile,所以我用uboot-1.1.6来分析Makefile。通过对u-boot的分析想要得到以下内容:
1. U-boot的入口
2. 链接地址
由顶层Readme文件说明,可以知道如果要使用开发板board/,就先执行
make
命令进行配置,然后执行_config make all
,就可以生成如下3个文件
- U-Boot.bin: 二进制可执行文件,它就是直接烧入NandFlash、NORFlash的文件
- U-Boot:ELF格式的可执行文件
- U-Boot.srec:Motorola S-Record格式的可执行文件
搜索
100ask24x0_config
make 100ask24x0_config
的时候,就相当执行这条命令: @$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
@代表的是目标100ask24x0_config, 那么$(@:_config=)就是将100ask24x0_config中的_config替换为空,得到100ask24x0
#!/bin/sh -e
## 上面这句指定执行该脚本所使用的解释器, -e相当于使用/bin/bash
# Script to create header files and links to configure
# U-Boot for a specific board.
#
# Parameters: Target Architecture CPU Board [VENDOR] [SOC]
#
# (C) 2002-2006 DENX Software Engineering, Wolfgang Denk
#
# mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
# $0 $1 $2 $3 $4 $5 $6
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
#分析传入的参数里面有没有 "--",“-a”等
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done
#判断BOARD_NAME有没有定义,如果没有则为:$1,其中$1为传入的第一个参数,依次类推
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
#判断参数的个数,不合条件就退出
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
#打印这一句话
echo "Configuring for ${BOARD_NAME} board..."
#
# Create link to architecture specific headers
#
#判断源代码目录和目标文件目录是否一致
#如果这两个不相等,可以看一下makefile文件,这两个是从makefile里面来的
if [ "$SRCTREE" != "$OBJTREE" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/include/asm-$2 asm
LNPREFIX="../../include2/asm/"
cd ../include
rm -rf asm-$2
rm -f asm
mkdir asm-$2
ln -s asm-$2 asm
else
#两个相等,程序进入这个分支
cd ./include
rm -f asm
#建立一个asm的链接文件,它指向asm-;配置的时候临时生成指向某一个架构,如果为i386架构,则为asm-i386
ln -s asm-$2 asm #ln -s asm-arm asm
fi
rm -f asm-$2/arch # rm -f asm-arm/arch
#如果第六个参数为NULL或者为空 LNPREFIX没有被定义
if [ -z "$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
#我们这里执行这个分支
#建立一个链接文件,指向${LNPREFIX}arch-$6,其中$6为传进来的参数
ln -s ${LNPREFIX}arch-$6 asm-$2/arch # ln -s arch-s3c24x0 asm-arm/arch
fi
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc # ln -s proc-armv asm-arm/proc
fi
#
# Create include file for Make
#
#新建一个config.mk文件,> 表示新建
# >新建 >>追加
echo "ARCH = $2" > config.mk
#在config.mk追加, >> 表示追加
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
#判断第5个参数,追加 VENDOR = xx
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
#判断第6个参数,追加 SOC = xx
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
#
# 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
#把以下内容追加到config.h文件中去
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include $1 .h>" >>config.h
#其中 #include 就是生成的配置文件
exit 0
# mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
# $0 $1 $2 $3 $4 $5 $6
1. 开发板名称BOARD_NAME = $1 = 100ask24x0
2. 创建于开发板相关的头文件的链接,如下:
ln -s asm-arm($2) asm
ln -s arch-s3c24x0($6) asm-arm($2)/arch
ln -s proc-armv asm-arm($2)/proc # 如果$2不是arm的话,此行没有
3. 创建顶层Makefile包含的文件include/config.mk,如下所示:
ARCH = $2 = arm
CPU = $3 = arm920t
BOARD = $4 = 100ask24x0
VENDOR = $5 = NULL # $5为空,或者是NULL的话,此行没有
SOC = $6 = s3c24x0 # $6为空,或者是NULL的话,此行没有
4. 创建开发板相关头文件include/config.h
/* Automatically generated - do not edit */
#include
,里面存放的就是
的配置信息。include/configs/.h
来裁减、设置 U-Boot。include $(OBJTREE)/include/config.mk
注:在我们执行make的时候其将会生成第一个目标也就是all,以all为突破口我们找到all.
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 $< $@
而u-boot.srec u-boot.bin又依赖于u-boot
$(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
make
/ make all
然后找到和这条命令相似的命令,通过得到的命令我们可以顺利的找到其在编译过程中所用到的链接器脚本arm-linux-ld -Bstatic -T /work/system/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000 $UNDEF_SYM cpu/arm920t/start.o \
打开u-boot-1.1.6/board/100ask24x0/u-boot.lds
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering,
*
* 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 Foundation; 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
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)//入口地址_start
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text : //代码段排布
{
cpu/arm920t/start.o (.text) //先是该代码,最先连接运行
board/100ask24x0/boot_init.o (.text)
*(.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_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
cpu/arm920t/start.o
,在cpu/arm920t/start.S我们可以轻松找到其所有代码的入口.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
...................
board/100ask24x0/config.mk:25:TEXT_BASE = 0x33F80000
TEXT_BASE = 0x33F80000