疯雨-版权所有,转载请注明【http://blog.csdn.net/u010346967】
内存初始化好了,当然是转移到内存运行了。根据三星的IROM启动文档,里面已经提供了拷贝函数,我们只需要调用即可。
这里的五个参数说明下:
z :表示mmc通道,我们是sd2也就是用的通道2,直接填2就可以了,这个值我当时是测出来的,其实手册上有说明
a:sd卡的起始拷贝块,即从sd卡的哪个块开始拷贝。sd卡前16k给了BL1,sd卡一个扇区是512字节(0.5k),那么最少要32个扇区留给BL1,我们留48个扇区给BL1
也就是BL2从第49个扇区开始存放。
b:从sd卡拷贝多少个扇区到内存,BL2编译完200K左右,拷贝240k的内容过去(大点没关系),也就是480个扇区
c:要拷贝到内存的哪里,也就是所要拷贝到的内存的起始地址,内存是从0x20000000开始的,我们拷贝到0x24800000地址,留出0x4800000放内核代码。
e:这个值默认为0,不用改。
在board/samsung/x210v3目录下新建文件copy_to_mem.c
添加代码如下:
/**
* * This Function copy MMC(MoviNAND/iNand) Card Data to memory.
* * Always use EPLL source clock.
* * This function works at 20Mhz.
* * @param u32 DMA channel number: this is channel 2. Depend on your board.
* * @param u32 StartBlkAddress : Source card(MoviNAND/iNand MMC)) Address.(It must block address.)
* * @param u16 blockSize : Number of blocks to copy.
* * @param u32* memoryPtr : Buffer to copy from.
* * @param bool with_init : determined card initialization.
* * @return bool(u8) - Success or failure.
* */
#define CopySDMMCtoMem(z,a,b,c,e) (((int(*)(int, unsigned int, unsigned short, unsigned int*, int))(*((unsigned int *)0xD0037F98)))(z,a,b,c,e))
#define MMC_CHANNEL 2
#define BL2_START_SECTOR 49
#define BL2_SECTOR_NUM 480
#define BL2_MEM_START_ADDR 0x24800000
void copy_to_mem(void)
{
/*
//print channel value to ensure which channel used
__asm__(
"ldr r0,=0xD0037488\n"
"bl display_mem\n"
:
:
:"memory");
*/
CopySDMMCtoMem(MMC_CHANNEL, BL2_START_SECTOR, BL2_SECTOR_NUM, (unsigned int *)BL2_MEM_START_ADDR, 0);
}
接下来修改Makefile,将文件编译进uboot
root@crazyrain:/home/share/uboot/u-boot-2012.10# vim board/samsung/x210v3/Makefile
修改后如下:
COBJS-y := x210v3.o onenand.o copy_to_mem.o
SOBJS := lowlevel_init.o
make一下,发现没错误,接下来就是调用拷贝函数。在lowlevel_init.S文件如下位置添加代码:
bl internal_ram_init
bl copy_to_mem
至此lowlevel_init.S任务完成,回到start.S文件发现如下代码要修改:
call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r0,=0x00000000
bl board_init_f
首先,内存的基地址不对,这一点通过前面的反汇编就已经知道了,然后就是 bl board_init_f这里有问题,我们的代码已经搬运到了内存,而BL1是运行在SRAM中的,bl跳转是相对跳转,只能跳到前后32M的内存范围。显然从SRAM的0xD0020000到内存的0x24800000不止32M,所以这里要用到伪指令ldr,或者你自己手算要跳到的地址然后mov pc,lr
修改如下:
call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r0,=0x00000000
//bl board_init_f
ldr pc, =board_init_f
然后修改开发板配置头文件,将内存基地址改为0x20000000
root@crazyrain:/home/share/uboot/u-boot-2012.10# vim include/configs/x210v3.h
修改如下:
/* DRAM Base */
//#define CONFIG_SYS_SDRAM_BASE 0x30000000
#define CONFIG_SYS_SDRAM_BASE 0x20000000
root@crazyrain:/home/share/uboot/u-boot-2012.10# make clean
root@crazyrain:/home/share/uboot/u-boot-2012.10# make