s5pv210从存储设备加载代码到DDR

建议先看《[project X] tiny210(s5pv210)上电启动流程(BL0-BL2)》,根据例子了解一下上电之后的BL0\BL1\BL2阶段,以及各个阶段的运行位置、功能。

一、说明

1、疑问

前面文章中《[uboot] (第三章)uboot流程——uboot-spl代码流程》中,最后uboot-spl的操作是调用board_init_f了,在board_init_f中实现了加载BL2镜像(uboot.bin)到ddr上,然后跳转到相应位置。
那么前面有个坑,就是tiny210的board_init_f中,是 如何实现加载BL2镜像(uboot.bin)到ddr上,然后跳转到BL2的相应地址上?
这个也就是本文里面的主要介绍的:
s5pv210是如何实现把镜像从存储设备上加载到ddr上的?

2、原理

通过《[project X] tiny210(s5pv210)上电启动流程(BL0-BL2)》, s5pv210的BL0会根据启动模式从相应存储设备上获取BL1的镜像到DDR上。
例如,当启动模式是SD boot的时候,BL0会从SD卡上获取BL1镜像,加载到对应位置上。当启动模式是nand flash boot的时候,BL0会从nand flash上获取BL1镜像,加载到对应位置上。
如下表格(从《[project X] tiny210(s5pv210)上电启动流程(BL0-BL2)》截取的一部分)

模式硬件支持BL1镜像存放起始位置BL1镜像是否需要header加载位置跳转位置
Nand BootNand flashpage00xD002_00000xD002_0010
SD / MMC BootSD / MMCblock10xD002_00000xD002_0010

同时,BL0是固化在s5pv210的IROM中的,是芯片在出厂的时候已经实现好了的。相应的,其从存储设备(SD/nand/eMMC)上获取镜像的代码就也就必须是已经实现好的。
既然,从存储设备(SD/nand/eMMC)上获取镜像的代码已经实现好了,也就是存储设备代码拷贝函数,并且在BL1阶段和BL2阶段可能也要需要使用到相同的功能,于是s5pv210将这部分代码的也是固化在IROM中,并且将这些函数接口的函数指针存放到某一个固定的地方。
当BL1或者BL2需要使用到从存储设备(SD/nand/eMMC)上获取镜像的函数接口时,就可以从对应的地方获取函数指针。
而剩下的,也就是最重要的是,这些函数指针被存放在上什么地方?这也是我们后续重点关注的地方。
为什么是函数指针而不是函数地址呢,是因为可以直接使用函数指针来调用函数。

二、s5pv210代码拷贝函数介绍

现在,我们要关心的是s5pv210的存储设备代码拷贝函数的函数原型以及函数指针的存放位置。
主要参考文档:《S5PV210-iROM-ApplicationNote-Preliminary-20091126》
先一段文档里面的说明:
s5pv210的IROM中集成了一些启动存储设备的块拷贝函数。因此,开发者不需要实现对应的存储设备的拷贝函数了。这些拷贝函数可以实现从存储设备到memory的拷贝。当IROM启动完成之后,开发者也可以直接使用这些拷贝函数了。
这和我们第一节中,说明的是一致的。

1、存储设备代码拷贝函数(Device Copy Function)地址存储位置

这里要特别注意,这里既不是指函数指针,也不是指函数地址,而是指函数指针被存放到的位置。
可以通过函数指针被存放到的位置找到函数指针,调用函数指针就可以调用到相应的函数了。

函数指针的地址函数名功能
0xD0037F90NF8_ReadPage_Advis advanced NF8_ReadPage function.
0xD0037F94NF16_ReadPage_Advis advanced NF16_ReadPage function.
0xD0037F98CopySDMMCtoMemcan copy any data from SD/MMC device to SDRAM.
0xD0037F9CCopyMMC4_3toMemcan copy any data from eMMC device to SDRAM.
0xD0037FA0CopyOND_ReadMultiPagescan copy any data from OneNand device to SDRAM.
0xD0037FA4CopyOND_ReadMultiPages_Advcan copy any data from OneNand device to SDRAM.
0xD0037FA8Copy_eSSDtoMemcan copy any data from eSSD device to SDRAM.
0xD0037FACCopy_eSSDtoMem_Advcan copy any data from eSSD device to SDRAM.
0xD0037FB0NF8_ReadPage_Adv128pis advanced NF8_ReadPage function.

更详细的功能介绍建议参考文档《S5PV210-iROM-ApplicationNote-Preliminary-20091126》。
这些地址是递归的,位于0xD003_7F90-0xD003_7FB0
通过文档《[project X] tiny210(s5pv210)上电启动流程(BL0-BL2)》,我们知道了0xD002_0000-0xD003_7FFF是属于IRAM的区域,所以说’函数指针存放地址’是放在IRAM上的,按照我猜,应该是在启动过程中,BL0把这些IROM上这些固化的函数的地址写到IRAM对应的位置上,例如0xD0037F90,对应位置就可以当作一个函数指针来使用。

2、函数原型说明

文档中的函数原型和使用过程中的函数原型有所差异。个人感觉可能是文档有问题,但是这里还是以文档为准。使用介绍中,再以实际的使用为准。
因为tiny210只支持SD boot和nand flash的方式,下面我就以SD和nand flash作为存储设备的拷贝函数做介绍。

(1)CopySDMMCtoMem
从SD/MMC拷贝(加载)块到内存中的函数。
函数结构如下(也就是一个简单的使用范例)

?
1
2
3
4
5
6
7
8
9
10
11
/**
* This Function copy MMC(MoviNAND/iNand) Card Data to memory.
* Always use EPLL source clock.
* This function works at 20Mhz.
* @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) (((bool(*)( int , unsigned int , unsigned short , unsigned int *, bool))(*((unsigned int *) 0xD0037F98 )))(z,a,b,c,e))

可以简单推测出函数原型为bool CopySDMMCtoMem(int, unsigned int, unsigned short, unsigned int*, bool)。

argv0=起始块号 argv1=块数量 argv2=要拷贝到内存的什么位置上,也就是目标地址指针。 argv3=是否需要检测初始化 argv4=返回参数,用于决定是成功还是失败。

注意:以上是文档的说明,
但是在实际使用中,实际的函数原型如下:
boot copy_sd_to_ddr(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init);
可见,文档是有问题的。后续会说明。

(2)NF8_ReadPage_Adv
从nand flash拷贝(加载)页到内存中的函数。
8bit ECC校验的函数结构如下(也就是一个简单的使用范例)

?
1
2
3
4
5
6
7
8
/**
* This Function copies a block of page to destination memory.( 8-Bit ECC only )
* @param uint32 block : Source block address number to copy.
* @param uint32 page : Source page address number to copy.
* @param uint8 *buffer : Target Buffer pointer.
* @return int32 - Success or failure.
*/
#define NF8_ReadPage_Adv (a,b,c) ((( int (*)(uint32, uint32, uint8*))(*((uint32 *) 0xD0037F90 )))(a,b,c))

其参数意义参考注释,这里不加以说明了。

三、s5pv210代码拷贝函数使用示例

s5pv210代码拷贝函数是以函数指针的方式进行使用的,因为,在这里先介绍一个简单的函数指针的使用示例。

1、函数指针简单示例说明

假设有一个函数原型是int function(int a, int b),其函数指针被存放在了0x10的位置上。
那么我们调用该函数的方法如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#define CopySDMMCtoMem 0xD0037F98
// 上述我们已经说明了,CopySDMMCtoMem的函数指针是存放在0xD0037F98的。
 
typedef u32(*copy_sd_mmc_to_mem)
         (u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init);
// 这样就定义了copy_sd_mmc_to_mem为u32 (*)(u32, u32, u16, u32 *, u32)类型,后续可以直接用于函数指针变量的定义和类型强制转换
// argv0=通道号
// argv1=起始块号
// argv2=块数量
// argv3=要拷贝到的目标地址
// argv4不解
 
// 以下就是加载BL2镜像到DDR中的主体了,是在BL1中执行的。
// 主要关心一下函数指针的获取、转化和调用过程
void copy_bl2_to_ddr( void )
{
     u32 sdmmc_base_addr;
     copy_sd_mmc_to_mem copy_bl2 = (copy_sd_mmc_to_mem)(*(u32*)CopySDMMCtoMem);
// 这个是重点函数,也是要重点理解的地方
// (u32*)CopySDMMCtoMem先将0xD003_7F98强制类型转换成一个指针
// (*(u32*)CopySDMMCtoMem)从0xD003_7F98中获取函数指针
// (copy_sd_mmc_to_mem)对得到的函数指针进行强制类型转换,赋值给copy_bl2,后续直接调用copy_bl2即可。
 
     sdmmc_base_addr = *(u32 *)SDMMC_BASE;
// 获取通道,SD有两个通道,这部分在文档上没有说明,这里我们也不关心。
 
     if (sdmmc_base_addr == SDMMC_CH0_BASE_ADDR)
         copy_bl2( 0 , MOVI_BL2_SDCARD_POS, MOVI_BL2_BLKCNT, (u32 *)CONFIG_SYS_TEXT_BASE, 0 );
// 直接调用copy_bl2,就可以调用到具体的函数指针了
// MOVI_BL2_SDCARD_POS表示我们把BL2的镜像放到了哪个块上
// MOVI_BL2_BLKCNT表示BL2占用的块长度
// CONFIG_SYS_TEXT_BASE=0x23E0_0000,定义在include/configs/tiny210.h中,表示我们要把BL2的镜像(uboot.bin)放到什么位置上。
 
     if (sdmmc_base_addr == SDMMC_CH2_BASE_ADDR)
         copy_bl2( 2 , MOVI_BL2_SDCARD_POS, MOVI_BL2_BLKCNT, (u32 *)CONFIG_SYS_TEXT_BASE, 0 );
}

通过上述代码uboot-spl调用copy_bl2_to_ddr就可以实现把uboot.bin从SD中拷贝到0x23E0_0000,后面跳转到0x23E0_0000后,就可以直接进入uboot了。
uboot中把kernel、rootfs、dtb从SD中拷贝到对应位置上也是通过一样的方法,具体请自行参考代码copy_kernel_to_ddr的实现。

综上,就实现了利用IROM的代码从SD上拷贝镜像、代码到ddr中。
nand flash后续实现之后再进行补充。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值