嵌入式Linux裸机开发——SD卡启动
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式Linux裸机开发——SD卡启动相关的知识,希望对你有一定的参考价值。
嵌入式Linux裸机开发(十)——SD卡启动
存储设备分类:
磁存储设备:软盘、硬盘、光盘、CD、磁带
Flash:NandFlash、NorFlash
缺点:时序复杂,无坏块处理机制,接口不统一
NandFlash:MLC(可靠性差,容量大)、SLC(可靠性高、容量小)
扩展卡式Flash:SD卡、MMC卡、MicroSD(TF卡)
内部为NnadFlash存储颗粒,外部封装了接口,接口标准统一、通用。
缺点:频繁使用导致卡槽接触不可靠
iNand、MoviNand、eSSD:
内部为NandFlash芯片,集成块设备存储单元,集成了扩展卡式Flash 的优点,接口标准统一(时序、物理封装、引脚定义)
芯片级封装发布
Flash管理模块:坏块管理等
SSD:
内部为NandFlash芯片,外部封装为硬盘接口
一、SD卡简介
SD卡(Secure Digital Memory Card)是一种基于半导体闪存工艺的存储卡,1999年由日本松下主导概念,参与者东芝和美国SanDisk公司进行实质研发而完成。SD卡已成为目前消费数码设备中应用最广泛的一种存储卡。SD卡是具有大容量、高性能、安全等多种特点的多功能存储卡,它比MMC卡多了一个进行数据著作权保护的暗号认证功能(SDMI规格),读写速度比MMC卡要快4倍,达2M/秒。
SD插槽支持MMC卡。
二、SD卡编程接口
SD卡的引脚定义
针脚 | 4位SD模式 | 1位SD模式 | SPI模式 | |||
名称 | 描述 | 名称 | 描述 | 名称 | 描述 | |
1 | CD/DAT3 | 卡监测/数据位3 | CD | 卡监测 | CS | 芯片选择 |
2 | CMD | 命令/回复 | CMD | 命令/回复 | DI | 数据输入 |
3 | VSS1 | 地 | VSS1 | 地 | VSS1 | 地 |
4 | VCC | 电源 | VCC | 电源 | VCC | 电源 |
5 | CLK | 时钟 | CLK | 时钟 | CLK | 时钟 |
6 | VSS2 | 地 | VSS2 | 地 | VSS2 | 地 |
7 | DAT0 | 数据位0 | DAT | 数据位 | DO | 数据输出 |
8 | DAT1 | 数据位1 | RSV | 保留 | RSV | 保留 |
9 | DAT2 | 数据位2 | RSV | 保留 | RSV | 保留 |
SD卡的引脚接口支持两种通信协议:SD协议和SPI协议。
SPI协议是单片机中广泛使用的一种通信协议,接口时序简单,是一种低速通信协议。
SD通信协议是一个统一标准的通信协议。SoC通过SD卡的九针引脚以SD/SPI协议向SD卡管理模块发送命令、时钟、数据等信息,需要按照时序处理操作SD卡。
三、SD卡启动模式
1、S5PV210读取Flash设备数据的方式
S5PV210内部iROM内部固化了多个设备拷贝函数,这些函数支持从SD/MMC、eMMC、OneNand、eSSD设备拷贝数据到SDRAM中。设备拷贝函数如下:
NF8_ReadPage_Adv(0xD0037F90):2K、4K,8bit总线
NF16_ReadPage_Adv(0xD0037F94):2K,5 cycle ,16位总线
CopySDMMCtoMem(0xD0037F98):从SD/MMC设备拷贝到SDRAM
CopyMMC4_3toMem(0xD0037F9C):从eMMC设备拷贝到SDRAM
CopyOND_ReadMultiPages(0xD0037FA0):从OneNand设备拷贝到SDRAM
CopyOND_ReadMultiPages_Adv(0xD0037FA4):从OneNand设备拷贝到SDRAM
Copy_eSSDtoMem(0xD0037FA8):从eSSD设备拷贝到SDRAM(CPUPIO模式)
Copy_eSSDtoMem_Adv(0xD0037FAC):从eSSD设备拷贝到SDRAM(UDMA模式)
NF8_ReadPage_Adv128p(0xD0037FB0):每块128页,每页2K的Nand
2、S5PV210读取SD卡数据的方式
CopySDMMCtoMem函数解读:
#define CopySDMMCtoMem(z,a,b,c,e) (((bool(*)(int, unsigned int, unsigned short, unsigned int*, bool))(*((unsigned int *)0xD0037F98)))(z,a,b,c,e))
参数1:SD卡通道
参数2:块起始地址(块地址)
参数3:拷贝块的数量
参数4:数据拷贝到什么地址
参数5:返回状态
3、函数指针调用设备拷贝函数
typedef unsigned int bool;
typedef bool(*CopySDMMC2Mem) (int, unsigned int, unsigned short, unsigned int *, bool);
CopySDMMC2Mem pFun = (CopySDMMC2Mem)0xD0037F98;
(*pFun)(x,x,x,x,x);//调用方式
四、SD卡启动模式编程
S5PV210启动过程:开发板上电后,BL0执行时会从启动设备加载BL1到iRAM中执行,BL1执行时会初始化SDRAM,将BL2从启动设备拷贝到SDRAM,然后从BL1远跳转到BL2执行。
BL1阶段工作:
初始化SDRAM
从SD卡拷贝BL2到SDRAM
远跳转执行BL2
说明:S5PV210规定BL1从block1开始,BL1从block1-block32,
BL2从block45-block76。BL1的运行地址和链接地址为0xD0020010。
BL2阶段工作:
跳转到BL2执行时,点亮LED灯。
说明:BL2的运行地址为SDRAM中的地址,因此链接地址需要设定为SDRAM 的地址。
BL1工程代码分析:
start.S:
.global _start
_start:
// 初始化DDR SDRAM内存
bl sdram_init
// 从SD卡中读取数据到SDRAM,重定位,并跳到DRAM中运行
bl CopyBL2toSdram
loop:
b loop
sd_relocate.c:
#define SD_START_BLOCK 1
#define SD_BLOCK_CNT 32
#define DDR_START_ADDR 0x23E00000
typedef unsigned int (*CopySDMMC2Mem) (unsigned int channel, unsigned int start_block, unsigned char block_size, unsigned int *trg, unsigned int init);
void CopyBL2toSdram(void)
{
unsigned long ch;
void (*BL2)(void);
ch = *(volatile unsigned int *)(0xD0037488);
// 函数指针
CopySDMMC2Mem copy_bl2 = (CopySDMMC2Mem) (*(unsigned int *) (0xD0037F98));
unsigned int ret;
// 通道0
if (ch == 0xEB000000)
{
// 0:channel 0
// 49:源,代码位于扇区49,1 sector = 512 bytes
// 32:长度,拷贝32 sector,即16K
// 0x23E00000:目的,链接地址0x23E00000
ret = copy_bl2(0, 49, 32,(unsigned int *)0x23E00000, 0);
}
// 通道2
else if (ch == 0xEB200000)
{
ret = copy_bl2(2, 49, 32,(unsigned int *)0x23E00000, 0);
}
else
return;
BL2 = (void *)0x23E00000;
// 跳转到SDRAM中0x23E00000执行
(*BL2)();
}
工程源码见附件,编译后烧录到smart210正常运行,LED等闪烁。
本文出自 “生命不息,奋斗不止” 博客,请务必保留此出处http://9291927.blog.51cto.com/9281927/1787655
以上是关于嵌入式Linux裸机开发——SD卡启动的主要内容,如果未能解决你的问题,请参考以下文章