目录
u-boot(二)makefile
引入
如果要分析uboot结构以及如何链接的话,最好的方法就是去分析它的makefile。我们是怎么编译的?先执行配置make 100ask24x0_config
,然后编译make
.所以在顶层目录下的Makefile
一定存在这个100ask24x0_config
.我们就从这里入手
目录结构(1.1.6)
common
中,比如common中的cmd_nand.会调用驱动层的driver
中的nand/nandbase.c
,再去调用平台级别cpu
,以及单板的(IO等)board.分为四层结构如下:--------------------------------------------------
lib_generic common
--------------------------------------------------
post net fs disk
--------------------------------------------------
dtt nand_spl rtc drivers
--------------------------------------------------
board cpu lib_xxx
目录 | 说明 |
---|---|
lib_generic | 通用的库文件(crc)等 |
common | 通用程序,命令在这里 |
include | 头文件和配置文件 |
asm-arm | |
config | |
↑↑↑↑↑↑↑↑↑↑↑ | -------用户接口------- |
disk | 硬盘接口 |
net | 网络驱动 |
fs | 文件系统 |
↑↑↑↑↑↑↑↑↑↑↑ | -------中间层------- |
dtt | 温度等其他传感器驱动 |
rtc | 时钟 |
nand_spl | nand启动相关 |
drivers | 驱动程序 |
↑↑↑↑↑↑↑↑↑↑↑ | --------驱动层-------- |
cpu | 针对具体cpu |
Lib_xxx | 架构通用的文件 |
board | 开发板相关的,Io等相关 |
↑↑↑↑↑↑↑↑↑↑↑ | ------CPU相关,单板相关------- |
doc | 文档 |
example | 测试程序 |
tools | 制作u-boot格式映象工具等 |
顶层的mkconfig 配置了交叉编译工具的版本,链接参数等
配置文件
100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
执行make 100ask24x0_config 就相当于执行 mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0,
上述命令以及参数分别对应 $0 $1 $2 $3 $4 $5 $6
# Parameters: Target Architecture CPU Board [VENDOR] [SOC]
其中顶层mkconfig是一个shell脚本文件, 它会根据上面参数配置交叉编译工具的版本,链接参数等等。
###################################################################################
# #
# 首先是进行单板的配置 #
# make 100ask24x0_config #
# #
###################################################################################
100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
##################################################################################
#unconfig 执行的操作如下,可以先不去管它
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp
##################################################################################
#当前目录
SRCTREE := $(CURDIR)
# 当前目录下的mkconfig文件
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
##################################################################################
# $@表示目标,在$()中的@也表示目标,接下去的是字符串替换,也就是将目标中的_config 替换为空
# 开头@ 表示不回显
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
#也就是相当于
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
# 也就是调用外部shell脚本了
100ask24x0
include/asm | include/asm-arm |
---|---|
include/asm-arm/arch | include/asm-arm/arch-s3c24x0 |
include/asm-arm/proc | include/asm-arm/proc-armv |
include/config.mk
,包含cpu,soc等信息ARCH = arm
CPU = arm920t
BOARD = 100ask24x0
SOC = s3c24x0
include/config.h
,开发板相关头文件,这个文件用来配置裁剪uboot,所以如果要在board目录下新建一个开发板的目录,需要在include/configs下建立$1.h头文件,此处$1 = 100ask24x0,所以包含configs/100ask24x0.h/* Automatically generated - do not edit */
#include
uboot还没有类似linux一样的可视化配置界面(比如使用 make menuconfig来配置),要手动修改配置文件,从上述第4步骤我们可以发现,单板的具体配置是在include/configs/
中配置的,有以下两类配置,由两类宏进行配置:
CFG_"
,用于设置malloc缓冲池大小,u-boot命令选项,下载文件的默认加载地址,FLASH起始地址等。可以这样认为,"CONFIG_"除了设置一些参数外,主要用来设置Uboot的功能、选择使用文件中的哪一部分;而"CFG_"用来设置更细节的参数。
编译阶段
重新来看根目录的makefile
include $(OBJTREE)/include/config.mk
export ARCH CPU BOARD VENDOR SOC
#ARCH = arm
#CPU = arm920t
#BOARD = 100ask24x0
#SOC = s3c24x0
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
cpu/arm920t/start.o
OBJS = cpu/$(CPU)/start.o
BOARDDIR=100ask24x0,BOARD=100ask24x0,CPU=arm920t
IBS = 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/usb/libusb.a
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += common/libcommon.a
LIBS += $(BOARDLIBS)
LIBS := $(addprefix $(obj),$(LIBS))
.PHONY : $(LIBS)
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
all: $(ALL)
$(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(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
UNDEF_SYM=`arm-linux-objdump -x 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 |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd /home/book/Desktop/u-boot/u-boot-1.1.6 &&
arm-linux-ld -Bstatic -T /home/book/Desktop/u-boot/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000 $UNDEF_SYM cpu/arm920t/start.o \
--start-group 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 --end-group -L /opt/gcc-3.4.5-glibc-2.3.6/bin/../lib/gcc/arm-linux/3.4.5 -lgcc \
-Map u-boot.map -o u-boot
arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
board/100ask24x0/u-boot.lds
,代码段的基地址0x33F80000
,也就是说,链接脚本里面的地址会加上这个数字.arm-linux-ld -Bstatic -T /home/book/Desktop/u-boot/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000 $UNDEF_SYM cpu/arm920t/start.o \..................
也就是说该u-boot应该在0x33F80000
这个位置运行
board/100ask24x0/config.mk
中有定义TEXT_BASE = 0x33F80000
$(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS)
是在LDFLAGS
中定义,我们可以用debug.mk
调试,可以使用d-
再一层解析具体的,但是这里已经能够看到$(TEXT_BASE)
定义了这个地址了make -f Makefile -f debug.mk d-LDFLAGS
LDFLAGS=-Bstatic -T /home/book/Desktop/u-boot/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000
origin = file
value = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
flavor = recursive
grep "LDFLAGS" * -nR
,可以发现在顶层的config.mk
看到定义LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
附录
###################################################################################
# #
# 首先是进行单板的配置 #
# make 100ask24x0_config #
# #
###################################################################################
100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
##################################################################################
#unconfig 执行的操作如下,可以先不去管它
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp
##################################################################################
#当前目录
SRCTREE := $(CURDIR)
# 当前目录下的mkconfig文件
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
##################################################################################
# $@表示目标,在$()中的@也表示目标,接下去的是字符串替换,也就是将目标中的_config 替换为空
# 开头@ 表示不回显
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
#也就是相当于
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
# 也就是调用外部shell脚本了
###################################################################################
# #
# mkconfig的文件注释,shell脚本调用 #
# mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0 #
# [$0] [$1] [$2] [$3] [$4] [$5] [$6] #
###################################################################################
#!/bin/sh -e
# 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
#
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
# 不包含这些打头的参数,忽略这段代码
# $# 参数个数,-gt 大于
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,BOARD_NAME=参数1=100ask24x0
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
# 参数个数合法性判断,必须是5个
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
# 打印显示
echo "Configuring for ${BOARD_NAME} board..."
#
# Create link to architecture specific headers
#
# 这里SRCTREE=OBJTREE=$(CURDIR),我们可以去顶层的makefile中看到
# 也可以使用debug打印变量 make -f Makefile -f debug.mk OBJTREE
# OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
# SRCTREE := $(CURDIR)
# 也就是说 执行else 分支
# 建立asm的符号连接
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
# 删除原有的asm链接,建立新的链接 ln -s asm-arm asm
cd ./include
rm -f asm
ln -s asm-$2 asm
fi
rm -f asm-$2/arch
# -z string 测试指定字符是否为空,空着真,非空为假
# -o: or
# $6=s3c24x0,执行else
# ln -s arch-s3c24x0 asm-arm/arch
# asm-arch指向了arch-s3c24x0
if [ -z "$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
ln -s ${LNPREFIX}arch-$6 asm-$2/arch
fi
# if满足,删除 asm-arm/proc
# 重新建立新的链接 proc-armc 到asm-arm/proc
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi
#
# Create include file for Make
#
# ARCH = arm
# CPU = arm920t
# BOARD = 100ask24x0
# SOC = s3c24x0
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
#
# Create board specific header file
#
# /* Automatically generated - do not edit */
# #include
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 " >>config.h
exit 0
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000; //这个地址会加上 -Ttext 0x33F80000 这个地址
. = 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 = .;
}
转载:https://www.cnblogs.com/zongzi10010/p/10023667.html