u-boot移植重要问题说明
一、从SD卡拷贝BL2到内存的函数
函数名字叫copy_uboot_to_ram,位置在board/samsung/real210/mmc_boot.c
其中有这个一部分
ch = *(volatileu32 *)(0xD0037488);
copy_sd_mmc_to_memcopy_bl2 =
(copy_sd_mmc_to_mem) (*(u32 *)(0xD0037F98));
可能看着比较费解,其实这个拷贝函数是固化在irom里面的,是无法修改的,不过是可以直接使用的,它的地址就是在0xD0037F98,只要使用下面的定义然后再把0xD0037F98地址传递给copy_bl2就可以了。
typedef u32(*copy_sd_mmc_to_mem)
(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init);
参考博客http://blog.csdn.net/shangguobuliuhen/article/details/9844371
二、从nand启动 8位ECC校验以及u-boot前8K校验和校验问题
在从nand启动时,s5pv210会对读取的代码进行ECC和校验和校验,所以在往nand写入u-boot时也要正确的做好8位ECC和校验和计算之后再写入。校验和是在nand_write函数中进行的,所在的文件位置是drivers/mtd/nand/nand_base.c。进行校验和计算的代码是:
#if defined(CONFIG_BL1_CHECKSUM)
inti;
ulongchecksum;
uint8_t*ptr;
#endif
#if defined(CONFIG_BL1_CHECKSUM)
if(to == 0) {
ptr= buf + 16;
for(i= 16, checksum = 0; i < 8192; i++) {
checksu+= *ptr;
ptr++;
}
*((volatileu32 *)(buf + 0x8)) = checksum;
}
#endif
由宏CONFIG_BL1_CHECKSUM控制。其中if (to== 0)是用来判断是否为u-boot.bin文件的首地址(也是nand的起始地址,即0x00000000地址),如果是那么就进行校验和的计算,否则直接写入,不在计算校验和。有了这个判断就很好的解决即可以实现对u-boot.bin前8K的BL1进行校验和计算,也不影响后续的数据写入。使用if (to == 0)原因是,u-boot.bin的前8K数据需要计算,后面的就不需要了,而if (to == 0)就正好实现了这个功能。
三、u-boot.lds连接文件问题
这里只贴出.text部分:
下面是官方部分
.text :
{
*(.__image_copy_start)
CPUDIR/start.o(.text*)
*(.text*)
}
下面是修改后的部分
.text :
{
*(.__image_copy_start)
CPUDIR/start.o(.text*)
board/samsung/real210/real210_board.o (.text)/*用户添加*/
*(.text*)
}
real210_board.o就是要链接的目标文件。为什么要做这个呢?这个是u-boot移植中很重要的一部分,不做这个的话,BL1都无法实现。原因慢慢来说:
知道BL1是u-boot.bin的前8K代码,要在BL1阶段进行串口和内存的初始化,那么这些初始化的代码必须在u-boot.bin前8K数据之内,否则会因为找不到函数崩溃掉。在u-boot中默认是没有这个链接的,也就是说,即使你写的代码完全正确,没有这个链接的话,也是无法正常运行的,因为在默认的情况下,编译后u-boot很可能把这些初始化链接到了前8K之外。为此我们就需要把这些函数链接到前8K之内。也就是链接real210_board.o这个文件,如上面的代码。
可以知道real210_board.o这个文件是在板级文件夹中,看看该文件夹下的makefile:
#下面为用户添加,功能是把lowlevel_init.o mem_setup.o mmc_boot.o这三个目标独立出来,生成real210_board.o,用于在u-boot.lds中做链接
#这样做的目的是,为了在增加该目录下代码量时,不影响生成u-boot.bin前8K的BL1
LIBReal = $(obj)real210_board.o
REAL210_board :=lowlevel_init.o mem_setup.o mmc_boot.o nand_cp.o
SRCS := $(REAL210_board:.o=.S)
REAL210_board :=$(addprefix $(obj),$(REAL210_board))
#上面为用户添加
LIB = $(obj)lib$(BOARD).o
COBJS-y := real210.o
#COBJS-$(CONFIG_SAMSUNG_ONENAND) += onenand.o
SOBJS :=
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS-y))
SOBJS := $(addprefix $(obj),$(SOBJS))
#下面为用户添加,下面的ALL一定不能少,它的意思是告诉编译器后面的两个LIB全部都要编译,不加只会编译前面的一个,后面的不会编译
ALL :$(LIB) $(LIBReal)
$(LIBReal):$(obj).depend$(REAL210_board)
$(call cmd_link_o_target, $(REAL210_board))
#上面为用户添加
$(LIB) :$(obj).depend $(SOBJS) $
可以看到real210_board.o 是由lowlevel_init.o mem_setup.o mmc_boot.o nand_cp.o文件链接的目标文件。而BL1所需要的函数也都在这些文件之中,如果链接过后有函数在u-boot.bin前8K之外,那么就需要对这些文件里的函数瘦身了。