一、s3c6410启动流程
要移植uboot到tiny6410,首先需要弄清楚tiny6410的启动流程,下面是三星官方文档给出的启动流程图
从流程图中可以看到需要4步:
1、上电后先运行IROM里面的代码,芯片厂商固定好,进行硬件初始化,包括系统时钟初始化,D-TCM初始化等,这部分叫BL0。
2、iRom在初始化完后会把外部启动设备(nand flash、sd卡等)中的bootloader的前4K拷贝到stepping stone中,然后调到stepping stone中运行,这部分叫BL1。
3、BL1会初始化系统时钟,串口和内存,初始化完后,会把剩余的bootloader从启动设备拷贝到内存,这部分叫BL2。
4、拷贝完后跳到内存运行,之后就是加载内核、文件系统等。
大致的步骤就是这样,步骤1已经是固定好的,我们需要移植的是步骤2、3、4。
先下载好uboot-2010-03版本的uboot源码,在官方上好像下载不了,可以在这里下载:
http://download.csdn.net/detail/atmega_chen/9795885
二、uboot-2010-03 移植前分析
1、什么是nand spl
在下载好源码,解压后,移植前先分析uboot的编译流程和移植方向。因为2010-03版本的uboot加了nand spl,之前使用的版本并未使用到nand spl,所以会分析有nand spl和无nand spl的区别已经移植的。
nand spl也就是一个包含uboot前面4k大小的bin文件,在生成的时候uboot的总文件的时候会将4k的bin文件和u-boot.bin合并成一个大小为256k的u-boot-nand.bin。下面根据源码具体分析有nand spl和无nand spl的区别。
2、nand spl生成分析
由于我们要移植的是tiny6410,uboot2010-03中并没有支持tiny6410,但是有支持smdk6400,所以我们先用smdk6400的代码分析。
先看到根目录下面的Makefile,在6400配置规则里面当执行make smdk6400的时候会把CONFIG_NAND_U_BOOT宏定义写入到include/config.mk里面去,编译的时候会调用。
smdk6400_config : unconfig
@mkdir -p $(obj)include $(obj)board/samsung/smdk6400
@mkdir -p $(obj)nand_spl/board/samsung/smdk6400
@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
@if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then \
echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
$(MKCONFIG) $(@:_config=) arm arm1176 smdk6400 samsung s3c64xx; \
else \
echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
$(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6400 samsung s3c64xx; \
fi
@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
然后找到这个宏使用的地方,这里就是说如果有定义CONFIG_NAND_U_BOOT,就定义NAND_SPL和U_BOOT_NAND这两个变量,这两个变量有什么用呢。
ifeq ($(CONFIG_NAND_U_BOOT),y)
NAND_SPL = nand_spl
U_BOOT_NAND = $(obj)u-boot-nand.bin
endif
我们先看到Makefile的总生成目标,可以看到总的生成目标里面有u-boot.srec,u-boot.bin和U_BOOT_NAND,也就是u-boot-nand.bin
# Always append ALL so that arch config.mk's can add custom ones
ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND)
all: $(ALL)
在往下找U_BOOT_NAND的生产规则,u-boot-nand.bin依赖NAND_SPL和u-boot.bin,其中u-boot.bin的生成不分析就是正常的uboot生成u-boot.bin的流程,主要分析NAND_SPL的生成。如果依赖关系满足,那么就将u-boot-spl-16k.bin和u-boot.bin这个两个文件合并成u-boot-nand.bin。其中u-boot-spl-16k.bin这个文件的生成,就是根据依赖NAND_SPL来生成,具体怎么生成往下分析。
$(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin
cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
搜索NAND_SPL的生成规则,这条规则会去编译nand_spl/board/ (BOARDDIR)下面的文件,其中 (BOARDDIR)就是samsung目录。
$(NAND_SPL): $(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk
$(MAKE) -C nand_spl/board/$(BOARDDIR) all
进入到nand_spl/board/samsung/smdk6400目录,看到一开始只有三个文件。
这里就是nand spl的关键所在,也就说前面只要定义了CONFIG_NAND_U_BOOT就会编译nand spl这个目录,那么编译出来的是什么东西呢?打开Makefile看看。
首先定义了CONFIG_NAND_SPL = y,这个宏比较重要,后面会介绍用处。
CONFIG_NAND_SPL = y
include $(TOPDIR)/config.mk
include $(TOPDIR)/nand_spl/board/$(BOARDDIR