SD卡启动

SD卡启动的好处

  1. 一般烧录的方式都是借助电脑进行,特别麻烦,有啦SD卡后,可以直接烧写在SD卡进行刷机,无论机子在哪儿,只要拿着SD卡即可
  2. 譬如在量产S5PV210时,可以用SD卡进行量产刷机,板子贴片好的时候,内部iNand是空的,此时直接启动无启动;板子出厂前官方刷机时是把事先做好的量产卡插入SD卡卡槽,然后打到iNand方式启动;因为此时iNand是空的所以第一启动失败,会转而第二启动,就从外部SD2通道的SD卡启动了。启动后会执行刷机操作对iNand进行刷机,刷机完成后自动重启(这回重启时iNand中已经有image了,所以可以启动了)。刷机完成后SD量产卡拔掉,一般烧机48小时,无死机即可装箱待发货。

SD卡启动的难点

  1. 对于SRAM、DDR来说,这两种都是总线访问,而SRAM不需要初始化即可使用,DDR需要初始化,总而言之,CPU可以直接和SRAM、DDR交互;
  2. SD卡不能通过总线来访问,而是需要时序,常用于SD的两种时序有–> SD协议、SPI协议;

回顾S5PV210的启动过程

如图,来自210官方手册
该图描述啦210的整个启动过程:
在这里插入图片描述
*. 首先板子上电,BL0开始运行,然后判断210从哪个设备启动(一般支持oneNand、SD、MMC、eMMC、NAND、eSSD、NOR等启动),如果是SD卡启动方式,则BL0会从SD卡读取16KB到SRAM去执行,也就是复制BL1到SRAM运行,然后BL1把BL2复制到SRAM,让BL2跑起来,接下来BL2去初始化DDR,并把OS复制到DDR,这时程序就运行起来啦。

SD卡启动流程(分为两部分)

  1. 整个镜像小于16KB:
    这个时候相当于整个镜像作为BL1被steppingstone直接硬件加载执行
  2. 整个镜像大于16KB
    只要大于16KB,就把整个镜像分为两部分,第一部分是16KB大小,第二部分是剩下的大小,对于UBOOT 会把第一部分作为BL1启动,然后去初始化DRAM,并且把第二部分(BL2)复制到DRAM去执行。

代码编写思路(大于16KB的SD卡启动)

首先分为两部分:BL1 BL2

BL1中需要完成:
	1)关看门狗
	2)设置SVC栈
	3)开iCache
	4)初始化DDR
	5)在SD卡中复制BL2到特定位置
	6)跳转到执行BL2
BL2中需要完成:
	让LED闪烁

SD
如图是SD卡的boot分区图
一般都是从第二个块开始,第一个块保留
BL1

.global _start      		 //声明_start为外部变量(相当于C语言全局变量)
_start:             
	//第1步,关闭看门狗
	ldr r0, =WATCH_DOG
	ldr r1, =0x0
	str r1, [r0]
	
	//第2步,设置栈
	ldr sp, =svc_stack
	
	//第3步,开关cache
	mrc p15,0,r0,c1,c0,0;  //读出cp15的c1到r0中
	//bic r0,r0,#(1<<12)     //bit 12 置0 关icache
	orr r0,r0,#(1<<12)     //bit 12 置1 开icache
	mcr p15,0,r0,c1,c0,0;
	
	// 第4步:初始化ddr
	bl sdram_asm_init

	//第5步:重定位,从SD卡第45扇区开始,
	//复制32个扇区内容到DDR的0x23E00000
	//复制BL2到DDR
	bl copy_bl2_2_ddr
	
	//汇编最后的死循环
	b .  
#define SD_START_BLOCK 45
#define SD_BLOCK_CNT   32
#define DDR_START_ADDR 0x23E00000
typedef unsigned int bool;

//参数1:通道号:0或者2   
//参数2:开始扇区号: 	45    
//参数3:读取扇区个数:  32  
//参数4:读取后放入内存地址:0x23E00000
//参数5:with_init: 0
typedef bool(*pCopySDMMC2Mem)(int, unsigned int, unsigned short, unsigned int*, bool);

typedef void (*pBL2Type)(void);
//第5步,从SD卡第45扇区开始,
//复制32个扇区内容到DDR的0x23E00000,然后跳转到0x23E00000去执行
void copy_bl2_2_ddr(void)
{
	//第一步,读取SD卡扇区到DDR中
	pCopySDMMC2Mem p1 = (pCopySDMMC2Mem)(*(unsigned int *)0xD0037F98);
	p1(2, SD_START_BLOCK, SD_BLOCK_CNT, (unsigned int*)DDR_START_ADDR, 0);   //读取SD卡扇区到DDR中
	
	//跳转到DDR中的BL2运行
	pBL2Type p2 = (pBL2Type)DDR_START_ADDR;
	p2();
}

BL2

void main(void)
{
	//led初始化
	unsigned int *p = (unsigned int*)GPJ0CON;
	*p = 0x11111111;
	
	while(1)
	{
		unsigned int *p1 = (unsigned int*)GPJ0DAT;
		//亮
		*p1 = ((0<<3) | (0<<4) | (0<<5));
		
		//延时
		delay();
		
		//灭
		*p1 = ((1<<3) | (1<<4) | (1<<5));
		//延时
		delay();
	}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值