u-boot总体结构

本文和接下来几篇u-boot文章都是基于s3c2440的cpu移植到FL2440开发板上

1、u-boot源码组成

从u-boot-2010.06版本开始把体系结构相关的内容合并,原先的cpu与lib_arch内容全部纳入arch中,并且其中增加inlcude文件夹;分离出通用库文件lib。

u-boot-2010.06及以后版本
├── api                存放uboot提供的接口函数
├── arch               与体系结构相关的代码,uboot的重头戏
├── board              根据不同开发板定制的代码,代码也不少
├── common             通用的代码,涵盖各个方面,已命令行处理为主
├── disk                磁盘分区相关代码
├── doc                文档,一堆README开头的文件
├── drivers            驱动,很丰富,每种类型的设备驱动占用一个子目录
├── examples           示例程序
├── fs                 文件系统,支持嵌入式开发板常见的文件系统
├── include            头文件,已通用的头文件为主
├── lib                通用库文件
├── nand_spl           NAND存储器相关代码
├── net                网络相关代码,小型的协议栈
├── onenand_ipl
├── post               加电自检程序
└── tools              辅助程序,用于编译和检查uboot目标文件

2.makefile简要分析
所有这些目录的编译连接都是由顶层目录的makefile来确定的。
在执行make之前,先要执行make $(board)_config 对工程进行配置,以确定特定于目标板的各个子目录和头文件。
$(board)_config:是makefile 中的一个伪目标,它传入指定的CPU,ARCH,BOARD,SOC参数去执行mkconfig脚本。
这个脚本的主要功能在于连接目标板平台相关的头文件夹,生成config.h文件包含板子的配置头文件。
使得makefile能根据目标板的这些参数去编译正确的平台相关的子目录。
以s3c2440板为例,执行 make s3c2440_config,
主要完成三个功能:
@在include文件夹下建立相应的文件(夹)软连接,

#如果是ARM体系将执行以下操作:
#ln -s     ../arch/arm/include/asm       asm   
#ln -s  asm/arch-s3c24x0    asm/arch 
#ln -s   asm/proc-armv       asm/proc

@生成Makefile包含文件include/config.mk,内容很简单,定义了四个变量:

ARCH   = arm
CPU    = arm920t
BOARD  = s3c2440
SOC    = s3c24x0

@生成include/config.h头文件,只有一行:

/* Automatically generated - do not edit */
#include "config/s3c2440.h"

顶层makefile先调用各子目录的makefile,生成目标文件或者目标文件库。
然后再连接所有目标文件(库)生成最终的u-boot.bin。
连接的主要目标(库)如下:
OBJS  = $(CPUDIR)/start.o 
OBJS := $(addprefix $(obj),$(OBJS))
LIBS  = lib/libgeneric.a
LIBS += lib/lzma/liblzma.a
LIBS += lib/lzo/liblzo.a
LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
    "board/$(VENDOR)/common/lib$(VENDOR).a"; fi)
LIBS += $(CPUDIR)/lib$(CPU).a
ifdef SOC
LIBS += $(CPUDIR)/$(SOC)/lib$(SOC).a
endif
ifeq ($(CPU),ixp)
LIBS += arch/arm/cpu/ixp/npe/libnpe.a
endif
LIBS += arch/$(ARCH)/lib/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 fs/yaffs2/libyaffs2.a \
    fs/ubifs/libubifs.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += drivers/bios_emulator/libatibiosemu.a
LIBS += drivers/block/libblock.a
LIBS += drivers/dma/libdma.a
LIBS += drivers/fpga/libfpga.a
LIBS += drivers/gpio/libgpio.a
LIBS += drivers/hwmon/libhwmon.a
LIBS += drivers/i2c/libi2c.a
LIBS += drivers/input/libinput.a
LIBS += drivers/misc/libmisc.a
LIBS += drivers/mmc/libmmc.a
LIBS += drivers/mtd/libmtd.a
LIBS += drivers/mtd/nand/libnand.a
LIBS += drivers/mtd/onenand/libonenand.a
LIBS += drivers/mtd/ubi/libubi.a

LIBS += drivers/mtd/spi/libspi_flash.a
LIBS += drivers/net/libnet.a
LIBS += drivers/net/phy/libphy.a
LIBS += drivers/pci/libpci.a
LIBS += drivers/pcmcia/libpcmcia.a
LIBS += drivers/power/libpower.a
LIBS += drivers/spi/libspi.a
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/qe.a
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.a
endif
ifeq ($(CPU),mpc85xx)
LIBS += drivers/qe/qe.a
LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.a
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.a
endif
ifeq ($(CPU),mpc86xx)
LIBS += arch/powerpc/cpu/mpc8xxx/ddr/libddr.a
LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.a
endif
LIBS += drivers/rtc/librtc.a
LIBS += drivers/serial/libserial.a
LIBS += drivers/twserial/libtws.a
LIBS += drivers/usb/gadget/libusb_gadget.a
LIBS += drivers/usb/host/libusb_host.a
LIBS += drivers/usb/musb/libusb_musb.a
LIBS += drivers/usb/phy/libusb_phy.a
LIBS += drivers/video/libvideo.a
LIBS += drivers/watchdog/libwatchdog.a
LIBS += common/libcommon.a
LIBS += lib/libfdt/libfdt.a
LIBS += api/libapi.a
LIBS += post/libpost.a
ifeq ($(SOC),omap3)
LIBS += $(CPUDIR)/omap-common/libomap-common.a
endif

ifeq ($(SOC),omap4)
LIBS += $(CPUDIR)/omap-common/libomap-common.a
endif
ifeq ($(SOC),s5pc1xx)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.a
endif
ifeq ($(SOC),s5pc2xx)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.a
endif
显然跟平台相关的主要是:
$(CPUDIR)/start.o
board/$(VENDOR)/common/lib$(VENDOR) 
 $(CPUDIR)/lib$(CPU).a
$(CPUDIR)/$(SOC)/lib$(SOC).a
 arch/$(ARCH)/lib/lib$(ARCH).a
这里面的五个变量定义在include/config.mk(见上述)。
其余的均与平台无关。
所以考虑移植的时候也主要考虑这几个目标文件(库)对应的目录。

关于u-boot 的makefile更详细的分析可以参照http://blog.mcuol.com/User/lvembededsys/Article/4355_1.htm

3、u-boot通用目录是怎样做到与自己的目的平台有关的

include/configs/s3c2440.h

这个头文件主要定义了一类变量,前缀是CONFIG_,用来选择处理器、设备接口、命令、属性等,主要用来 决定是否编译某些文件或者函数。

这类宏定义对u-boot的移植性非常关键,比如drivers/net/dm9000x.c,对于dm9000x.c的操作很多都是通用的,但不是所有的板子上面都有这个芯片,即使有它在内存中映射的基地址也是平台相关的。所以对于fl2410板,在s3c2440.h中定义了

#define CONFIG_NET_MULTI            1
#define CONFIG_NET_RETRY_COUNT      20
#define CONFIG_DRIVER_DM9000        1
#define CONFIG_DM9000_BASE          0x20000300  /* nGCS4*/
#define DM9000_IO                   CONFIG_DM9000_BASE
#define DM9000_DATA                 (CONFIG_DM9000_BASE+4)
#define CONFIG_DM9000_USE_16BIT     1
#define CONFIG_DM9000_NO_SROM       1
#undef CONFIG_DM9000_DEBUG

CONFIG_DRIVER_DM9000的定义使得dm9000x.c可以被编译,因为dm9000.c中在函数定义的前面就有编译条件判断:#ifdef CONFIG_DRIVER_dm9000 如果这个选项没有定义,整个dm9000x.c就不会被编译了。
而常数参量DM9000_BASE则用在dm9000x.h头文件中定义各个功能寄存器的地址。u-boot的dm9000工作在IO模式下,只要给定IO寄存器在内存中映射的基地址,其余代码就与平台无关了。

u-boot的命令也是通过目标板的配置头文件来配置的,比如要添加ping命令,就必须添加CONFIG_CMD_PING才行。不然common/cmd_net.c就不会被编译了。
 从这里我可以这么认为,u-boot工程可配置性和移植性可以分为两层:
 一是由makefile来实现,配置工程要包含的文件和文件夹上,用什么编译器。
 二是由目标板的配置头文件来实现源码级的可配置性,通用性。主要使用的是#ifdef #else #endif 之类来实现的。

4、s3c2440其余重要的文件:
arch/arm/include/asm/arch-s3c24x0/s3c24x0.h        定义了s3x24x0芯片的各个特殊功能寄存器(SFR)的地址。
arch/arm/cpu/arm920t/start.s         在flash中执行的引导代码,也就是bootloader中的stage1,负责初始化硬件环境,把u-boot从flash加载到RAM中去,然后跳到arch/arm/lib/board.c中的start_armboot中去执行。
arch/arm/lib/board.c         u-boot的初始化流程,尤其是u-boot用到的全局数据结构gd,bd的初始化,以及设备和控制台的初始化。
board/s3c2440/flash.c       在board目录下代码的都是严重依赖目标板,对于不同的CPU,SOC,ARCH,u-boot都有相对通用的代码,但是板子构成却是多样的,主要是内存地址,flash型号,外围芯片如网络。对fl2410来说,主要考虑从smdk2410板来移植,差别主要在nor flash上面。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值