完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一.主流的外存设备发展及介绍
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))
● 参数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))
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先和()结合,而不是先和*结合。
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刷机方式)),即解决了这个问题。 |
|
|
|
只有小组成员才能发言,加入小组>>
4359个成员聚集在这个小组
加入小组3289 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4234 浏览 1 评论
4241 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 13:19 , Processed in 0.542462 second(s), Total 75, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号