U-boot工程的结构分析
U-boot工程的结构分析
我们使用的源码是u-boot-
1、源代码的组织
对于ARM来说主要的目录如下
Board 平台依赖 存放电路板相关的目录文件,每一套板子对应于一个目录如smdk2410(arm920t)
Cpu 平台依赖 存放CPU相关的目录文件,每款CPU对应一个目录,如arm920t、xscale、i386等目录
Lib_arm 平台依赖 存放ARM体系结构通用的文件,主要用于实现arm平台通用的函数。
Common 通用 通用的多功能函数实现,如环境,命令和控制台相关的函数实现的地方
Include 通用 头文件和开发板的配置文件,所有开发板的配置文件都在该目录下的configs目录下
Lib_generic 通用 通用的库函数实现
Net 通用 网络协议的实现
Drivers 通用的 各类具体设备的驱动程序,有以太网,nand驱动等。
2、u-boot的配置、编译和连接过程
所有目录的编译和连接的工作都是由顶层目录的makefile来确定的。
如果你需要使用board目录下的某一款开发板(board_name),在make之前需要先执行make $(board_name)_config的命令进行配置,然后make all就可以生成所需要的该开发板的二进制可执行文件
u-boot.bin
u-boot
u-boot.srec
由于u-boot-
2.1 u-boot的配置过程
执行make $(board_name)_config来对工程进行配置,用以确定目标板的各个子目录和头文件
在顶层Makefile文件可以看到如下的代码形式
SRCTREE := $(CURDIR)
…
MKCONFIG := $(SRCTREE)/mkconfig
…
Smdk2410_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
在u-boot的根目录下编译的时候,MKCONFIG就是根目录下的mkconfig,make smdk2410_config命令相当于执行如下命令:
./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0
Mkconfig的参数如下:
# Parameters: Target Architecture CPU Board [VENDOR] [SOC]
Mkconfig文件主要做了以下的事情:
1、在include文件夹下建立相应的文件夹软链接
如果是arm体系结构的话,执行下列操作
#ln –s asm-arm asm
#ln –s arch-s3c24x0 asm-arm/arch
#ln –s proc-armv asm-arm/proc
2、创建顶层Makefile包含的文件include/config.mk,该文件很简单,如下所示:
如果是./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0这一个命令,所创建的config.mk文件如下:
ARCH = arm
CPU = arm920t
BOARD = smdk2410
SOC = s3c24x0
3、生成include/config.h头文件,该文件只有一行:
#include”config/smdk2410.h”
u-boot的编译链接过程
顶层makefile文件先调用各个子目录的makefile,生成目标文件或者目标文件库,然后再连接所有的目标文件(库)生成最终的u-boot.bin。
需要连接的主要库如下:
OBJS = cpu/$(CPU)/start.o
iLIBS = 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)
跟平台相关的主要是以下这几个
OBJS = cpu/$(CPU)/start.o
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
LIBS += lib_$(ARCH)/lib$(ARCH).a
对于每个OBJS中的成员,都将进入cpu/$(CPU)目录(2440是cpu/arm920t)中编译它们,此处OBJS为cpu/arm920t/start.o,由cpu/arm920t/start.S编译得到。
对于每个LIBS中的成员,都将要进入相应的子目录执行make命令,它们将指定的文件编译连接成一个库文件。
Board/smdk2410目录下的u-boot.lds确定了程序的布局,地址。如下:
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm920t/start.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 = .;
}
在smdk2410开发板目录下有个文件名为config.mk,该文件用于设置代码段起始地址。
该文件如下所示
TEXT_BASE = 0x33F80000
总结下u-boot的编译流程:
首先,编译cpu/$(CPU)/start.S,对于不同的CPU,还可能编译cpu/$(CPU)目录下其他的文件,这视平台而定。
然后,对应于平台和开发板的每个目录、每个通用目录都是用它们各自的Makefile来生成相应的库。
如果需要添加新的文件,则需要在相应目录下的makefile中添加该文件。
将前面生成的.o和.a文件按照board/$(BOARDDIR)/config.mk文件中指定的代码起始段、board/$(BOARDDIR)/u-boot.lds(2410的依据board/smdk2410/u-boot.lds)连接脚步进行连接