深圳市航顺芯片技术研发有限公司
直播中

CDCNKA

8年用户 1228经验值
擅长:385288
私信 关注
[问答]

SD卡启动流程是怎样的?

内存和外存的区别是什么?
SD卡启动流程是怎样的?

回帖(1)

李悠冉

2021-10-18 15:09:07
一.主流的外存设备发展及介绍

2017/12/12 23:08
**

  1.首先,清楚内存和外存的区别:
**
一般是把这种RAM(random access memory,随机访问存储器,特点是任意字节读写,掉电丢失)叫内存,
把ROM(read only memory,只读存储器,类似于Flash SD卡之类的,用来存储东西,掉电不丢失,不能随机地址访问,只能以块为单位来访问)叫外存

  2.存储设备按发展趋势分类:
● 磁存储设备:软盘、硬盘、光盘、CD、磁带
● Flash:NandFlash、NorFlash
缺点:时序复杂,无坏块处理机制,接口不统一
NandFlash:MLC(可靠性差,容量大)、SLC(可靠性高、容量小)
现在基本都在发展MLC技术
● 扩展卡式Flash:SD卡、MMC卡、MicroSD(TF卡)
内部为NnadFlash存储颗粒,外部封装了接口,接口标准统一、通用。
缺点:频繁使用导致卡槽接触不可靠
● iNand、MoviNand、eSSD:
内部为NandFlash芯片,集成块设备存储单元,集成了扩展卡式Flash 的优点
接口标准统一(时序、物理封装、引脚定义),以芯片级封装发布
芯片内部具有Flash管理模块:具有能坏块管理等功能
● SSD:固态硬盘
内部为NandFlash芯片,外部封装为硬盘接口
**

  3.SD卡简介
**
SD卡是具有大容量、高性能、安全等多种特点的多功能存储卡,它比MMC卡多了一个进行数据著作权保护的暗号认证功能(SDMI规格),读写速度比MMC卡要快4倍,达2M/秒。
SD插槽支持MMC卡。
SD卡和Nand、Nor等Flash芯片差异
(1)SD卡/MMC卡等卡类有统一的接口标准,而Nand芯片没有统一的标准(各家产品会有差异)
二. SD卡编程接口

**

  1.SD卡3种模式的引脚定义
**





SD卡的引脚接口支持两种通信协议:SD协议和SPI协议。
SPI协议是单片机中广泛使用的一种通信协议,接口时序简单,是一种低速通信协议。
SD通信协议是一个统一标准的通信协议。SoC通过SD卡的九针引脚以SD/SPI协议向SD卡管理模块发送命令、时钟、数据等信息,需要按照时序处理操作SD卡。
**

  2.S5PV210的SD/MMC控制器
**
(1)SD协议要求SoC中有SD控制器,数据手册Section8.7,为SD/MMC控制器介绍。
(2)SD卡内部除了存储单元Flash外,还有SD卡管理模块,我们SoC和SD卡通信时,通过9针引脚以SD协议/SPI协议向SD卡管理模块发送命令、时钟、数据等信息,然后从SD卡返回信息给SoC来交互。工作时每一个任务(譬如初始化SD卡、譬如读一个块、譬如写、譬如擦除····)都需要一定的时序来完成(所谓时序就是先向SD卡发送xx命令,SD卡回xx消息,然后再向SD卡发送xx命令····)
三.SD卡启动流程1

**

  1.S5PV210的启动过程回顾
**
(1)210启动首先执行内部的iROM(也就是BL0),BL0会判断OMpin来决定从哪个设备启动,如果启动设备是SD卡,则BL0会从SD卡读取前16KB(不一定是16,反正16是工作的)到SRAM中去启动执行(这部分就是BL1,这就是steppingstone技术)
(2)BL1执行之后剩下的就是软件的事情了,SoC就不用再去操心了
**

  2.SD卡启动流程(bin文件小于16KB时和大于16KB时)
**
(1)启动的第一种情况是整个镜像大小小于16KB。这时候相当于我的整个镜像作为BL1被steppingstone直接硬件加载执行了而已。
(2)启动的第二种情况就是整个镜像大小大于16KB。(只要大于16KB,哪怕是17KB,或者是700MB都是一样的)这时候就要把整个镜像分为2部分:第一部分16KB大小,第二部分是剩下的大小。然后第一部分作为BL1启动,负责去初始化DRAM并且将第二部分加载到DRAM中去执行(uboot就是这样做的)。
**

  3.最重要的但是却隐含未讲的东西
**
(1)问题:iROM究竟是怎样读取SD卡/NandFlash的?
(2)三星在iROM中事先内置了一些代码去初始化外部SD卡/NandFlash,并且内置了读取各种SD卡/NandFlash的代码在iROM中。BL0执行时就是通过调用这些device copy function来读取外部SD卡/NandFlash中的BL1的。
**

  4.S5PV210读取Flash设备数据的方式
**
三星系列SoC支持SD卡/NandFlash启动,主要是依靠SteppingStone技术,具体能支持steppingstone技术的是内部的iROM代码。
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
**
四.S5PV210读取SD卡数据的方式

**

  1.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

● 参数1:SD卡通道,0或者2通道,我们板子SD卡通道为2
● 参数2:块起始地址(块地址)
● 参数3:拷贝块的数量
● 参数4:数据拷贝到什么地址
● 参数5:返回状态

  思考:为什么读取SD卡时以块为单位?
这就涉及到扇区和块的概念,一个扇区有好多个字节(一般是512个字节),一个扇区可以看成是一个块block(块的概念就是:不是一个字节,是多个字节组成一个共同的操作单元块),所以就把这一类的设备称为块设备。常见的块设备有:磁存储设备硬盘、软盘、DVD和Flash设备(U盘、SSD、SD卡、NandFlash、Norflash、eMMC、iNand)。
磁盘和Flash以块为单位来读写,就决定了我们启动时只能以整块为单位来读取SD卡
**

  2.使用函数指针调用设备拷贝函数
**
第一种方法:宏定义方式来调用。好处是简单方便,坏处是编译器不能帮我们做参数的静态类型检查。
#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

第二种方法:用函数指针方式来调用。
typedef unsigned int bool;typedef bool(*pCopySDMMC2Mem) (int, unsigned int, unsigned short, unsigned int *, bool);// 实际使用时pCopySDMMC2Mem p1 = (pCopySDMMC2Mem)0xD0037F98;p1(x, x, x, x, x);  // 第一种调用方法,编译器默认就是一个函数指针(*p1)(x, x, x, x, x);   // 第二种调用方法,和上面一样,*p1(x, x, x, x, x); // 错误,因为p1先和()结合,而不是先和*结合。


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

五、SD卡启动模式编程

S5PV210启动过程:开发板上电后,BL0执行时会从启动设备加载BL1到iRAM中执行,BL1执行时会初始化SDRAM,将BL2从启动设备拷贝到DDR,然后从BL1远跳转到BL2执行。
总体思路:将我们的代码分为2部分:第一部分BL1小于等于16KB,第二部分为任意大小,iROM代码执行完成后从SD卡启动会自动读取BL1到SRAM中执行;BL1执行时负责初始化DDR,然后手动将BL2从SD卡copy到DDR中正确位置,然后BL1远跳转到BL2中执行BL2。
**

  BL1阶段工作
**
● 关看门狗
● 设置栈
● 开iCache
**初始化DDR
从SD卡拷贝BL2到DDR
远跳转执行BL2**





说明:如图,S5PV210规定BL1从block1开始,BL1长度为16KB内,我们就定为16KB(也就是32个block),即BL1从block1-block32,
**

  BL2阶段工作:
**
● 跳转到BL2执行时,点亮LED灯。
BL2理论上可以从33扇区开始,但我们为了安全会用一些空扇区作为隔离区,故可以从45扇区开始,定义BL2长度为16KB,也就是32扇区
BL2从block45-block76。BL1的运行地址和链接地址为0xD0020010。
说明:BL2的运行地址为DDR中的地址,因此链接地址需要设定为DDR的地址。
我们选0x23E00000(因为我们BL1中只初始化了DDR1,地址空间范围是0x20000000~0x2FFFFFFF)
六.uboot中的做法

第二种思路:程序代码仍然包括BL1和BL2两部分,但是组织形式上不分为2部分而是作为一个整体来组织。它的实现方式是:iROM启动然后从SD卡的扇区1开始读取16KB的BL1然后去执行BL1,BL1负责初始化DDR,然后从SD卡中读取整个程序(BL1+BL2)到DDR中,然后从DDR中执行(利用ldr pc, =main这种方式以远跳转从SRAM中运行的BL1跳转到DDR中运行的BL2)。
**

  再来分析uboot的SD卡启动细节
**
(1)uboot编译好之后有200多KB,超出了16KB。uboot的组织方式就是前面16KB为BL1,剩下的部分为BL2.
(2)uboot在烧录到SD卡的时候,先截取uboot.bin的前16KB(实际脚本截取的是8KB)烧录到SD卡的block1~bolck32;然后将整个uboot烧录到SD卡的某个扇区中(譬如49扇区)
(3)实际uboot从SD卡启动时是这样的:iROM先执行,根据OMpin判断出启动设备是SD卡,然后从S卡的block1开始读取16KB(8KB)到SRAM中执行BL1,BL1执行时负责初始化DDR,并且从SD卡的49扇区开始复制整个uboot到DDR中指定位置(0x23E00000)去备用;然后BL1继续执行直到ldr pc, =main时BL1跳转到DDR上的BL2中接着执行uboot的第二阶段。
总结:uboot中的这种启动方式比上节讲的分散加载的好处在于:能够兼容各种启动方式。
代码分析:E:Linux13.sd_relocate
在linux下使用dd命令烧录程序,插上SD卡,开发板正常运行看到LED闪烁。





七.遇到的问题:

**

  插上分别使用九鼎1烧录好的SD卡和在linux下使用dd命令刷写uboot,启动都没有反应?
**
最终问题是SD卡没有启动起
采用的方法是从新刷机,板子刷入安卓系统,由于SD卡无法启动,故采用USB—dnw刷机方式:
刷机分2步:第一步刷x210_u***.bin,地址是0xd0020010;第二步刷uboot.bin,刷机地址是0x23e00000,uboot启动起来后,先fdisk -c 0去重新分区,然后再fastboot….再按照刷机过程刷入系统。
然后重启,等待系统开机完毕
然后破坏开发板iNand中的bootloader以从SD2启动(参考 二.ARM裸机刷系统(SD卡uboot+串口+u*** otg刷机方式)),即解决了这个问题。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分