• SD卡启动详解


    主流的外存设备介绍

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

    软盘、硬盘、光盘、CD、磁带

    • 存储原理大多数位次磁存储,缺点是读写速度可靠性等,优点是技术成熟价格便宜。广泛使用在桌面电脑中,在嵌入式设备中几乎不用。
    • 线代的存储发展方向是Flash存储,闪存技术是利用电学原理存储1和0,从而制成存储设备。所以闪存设备没有物理运动(磁盘中的磁头),所以读写速度很快,且无物理损耗。

    纯粹的Flash:Nandflash、Norflash

    • 这些是最早出现的,最原始的Flash颗粒组成芯片,也就是说Nandflash、Norflash芯片只是对存储单元做了最基本的读写接口,然后要 求外部的SoC来提供Flash读写控制器以和Flash进行读写时序

    缺陷:

    • 读写接口时序比较复杂,
    • 内部无坏块处理机制,需要SoC自己来管理Flash坏块
    • 各厂家的Flash接口不一致,甚至同一个厂家的不同型号、系列的Flash接口都不一致,这就造成产品升级麻烦

    分类:

    Nandflash分为MLC和SLC两种。SLC技术比较早,可靠性高,缺点是容量做不大(或者说容量做大了太贵,一般SLC的Nand容量都在512M以下),MLC技术比较新,不成熟可靠性差,优点是可以做的很便宜,容量可以做的很大。现在基本都在发展MLC技术。

    SD卡、MMC卡、MicroSD、TF卡

    • 这些卡其实内部就是Flsah存储颗粒,比直接的Nandflash芯片多了统一的外部封装和接口。
    • 卡都有统一的标准,譬如SD卡都是遵照SD规范来发布的。这些规范规定了SD卡的读写接口时序、读写命令集、卡的大小尺寸,引脚个数及定义。这样做的好处就是不同的厂商可以通用。

    iNand、MoveiNand、essD

    • 电子产品比如:手机相机等,前些年的趋势用SD卡/TF卡等扩展存储容量;但是近些年的趋势是直接内置大容量的Flash芯片而不是外部扩展卡。
    • 外部扩展卡时间长了,卡槽可能造成接触不良,导致不可靠
    • 现在主流的发展方向是使用iNand、MoviNand、eSSD(还有一些别的名字)来做电子产品的存储芯片。这些东西的本质还是Nandflash,内部由Nand的存储颗粒构成,再集成了块设备管理单元,综合了SD卡为代表的卡的优势和原始的NandFlash芯片的优势。
    • 优势1、向SD卡学习,有统一的接口标准(包括引脚定义、物理封装、接口时序)
    • 优势2:向原始的Nand学习,以芯片的方式来发布而不是以卡的方式
    • 优势3:内部内置了Flash管理模块,提供了诸如坏块管理等功能,让Nand的管理容易了起来

    SSD(固态硬盘)

    SD卡的特点和背景知识

    SD卡和MMC卡的关系

    • MMC卡比SD卡的标准早,SD卡标准兼容MMC卡标准。
    • MMC卡可以被SD读卡器读写,而SD卡不可以被MMC读卡器读写

    SD卡和Nand、Nor等Flash芯片差异

    • SD卡/MMC卡等卡类有统一的接口标准,而Nand芯片没有统一的标准(各家产品会有差异)

    SD卡与MicroSD的区别

    • 体积大小区别而已,传输与原理完全相同

    SD卡与TF卡的区别

    • 外观上,SD卡答而TF卡小,用途上,SD卡用于数码相机等而TF卡广泛应用于手机、GPS等
    • 时间上,SD卡1999年推出,TF卡于2004年推出,SD卡由日本松下、东芝与美国SanDisk共同推出,而TF卡Motorola和SanDisk共同推出
    • SD卡由写保护而TF卡没有,TF卡可以通过卡套转成SD卡使用

    SD卡编程接口

    SD卡的物理接口

    • SD卡的物理接口由9个真叫与外接进行物理连接,这9个脚中有2个地,1个电源,6个信号线

    SD协议与SPI协议

    • SD卡与SRAM/DDR/SROM之类的东西的不同:SRAM/DDR/SROM之类的存储芯片是总线式的,只要连接上初始化好之后就可以由SoC直接以地址的方式来访问。但是SD卡不能直接通过接口给地址来访问,他的访问需要按照一定的接口协议(时序)来访问
    • SD卡虽然只有一种物理接口,但是却支持两种读写协议:SD协议和SPI协议

    SPI协议特点(低速、接口操作时序简单、适合单片机)

    • SPI协议是单片机中广泛使用的一种通信协议,并不是为SD卡专门发明的
    • SPI协议相对于SD协议来说速度比较低
    • SD卡支持SPI协议就是为了方便单片机使用

    SD协议特点(高速、接口时序复杂、适合有SDIO接口的SoC)

    • SD协议是专门用来和SD卡通信的
    • SD协议要求SoC中有SD控制器,运行在高速率下,要求SoC主频不能太低

    S5PV210的SD/MMC控制器

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

     S5PV210的SD卡启动详解1

    SoC为何要支持SD卡启动

    • (1)一个普遍性的原则就是:SoC支持的启动方式越多,用户的可选择型就越大,SoC的适用面就越广。
    • (2)SD卡启动有一些好处:譬如可以在不借用专用烧录工具(类型Jlink)的情况下对SD卡进行刷机,然后刷机后的SD卡插入卡槽,SoC即可启动.像X210开发板板子贴片好的时候,内部iNand是空的,此时直接启动无启动。板子出厂前官方刷机时是把实现做好的量产卡插入卡槽,然后打到iNand方式启动;因为此时的iNand是空的,所以第一启动方式失败,转为第二启动方式,就是从外部的SD2通道的SD卡启动。启动后会执行刷机操作对iNand进行刷机,刷机完成后自动重启(这回iNand中已经有image了,所以可以启动了)。刷机完成后SD量产卡拔掉,烧机48小时,无死机后可以装箱待发货。

    SD卡启动的难点在哪里(ARAM、DDR、SDCard)

    • SRAM、DDR都是总线式访问的,SRAM不需要初始化就可以直接访问而DDR需要初始化才能使用,但是总之,CPU可以直接和SRAM或者DRAM打交道。而SD卡需要时序访问,CPU不可以直接和SD卡打交道。NorFlash读取是可以总线式访问,所以NorFlash启动非常简单,可以直接启动,但是SD/NandFlash不行
    • 以前只有NorFlash可以作为启动介质,台式机笔记本的BIOS就是NorFlash做的,后来三星在 2440中使用了SteppingStone的技术,让NandFlash也可以作启动介质。SteppingStone(翻译为启动基石)技术就是在SoC内部内置4KB的SRAM,然后开机时SoC根据OMpin判断用户设置的启动方式,如果是NandFlash启动,则SoC的启动部分的硬件直接从外部的NandFlash中读取开头的4KB到内部的SRAM作为启动内容。
    • 启动基石技术进一步发展在6410中进一步发展,在210中已经发展成熟。210中有96KB的SRAM并且有一段IROM代码作为BL0,然后BL0再去启动BL1,实际上210中做的事情在210中也有,只不过那时候是硬件自动完成的,而且体系没有210这么详细。

    S5PV210的启动过程回顾

    • 210启动首先执行内部iROM(也就是BL0),BL0会判断从哪个设备启动,如果启动设备是SD卡,则BL0则会从SD卡读取16KB(不一定是16KB,反正16KB是工作的)到SRAM中执行(这部分就是BL1,这就是stepping stone技术)
    • BL1执行之后剩下的就是软件的事情了,SoC就不用再操心了

    SD卡启动流程(bin文件小于16KB时和大于16KB时)

    • 启动的第一种情况时整个镜像大小小于16KB,这时候相当于整个镜像作为BL1被stepping stone直接硬件加载执行了而已。
    • 启动的第二种情况就是整个镜像大小大于16KB(只要大于16KB哪怕是17KB或者是700MB都是一样的),这时候整个镜像就要分为两个部分,第一部分16KB大小,剩下的部分作为第二部分。然后第一部分作为BL1启动,负责初始化DRAM并且负责将第二部分加载到DRAM中执行(uboot就是这么做的)。

    最重要的但是却隐含未讲的

    • 问题:iROM究竟是怎样读取我们的SD卡/NandFlash的?

    三星在iROM中事先内置了一些代码去初始化外部SD卡/NandFlash,并且内置了读取各种SD卡/NandFlash的代码在iROM中。BL0执行时就是通过调用这些device copy function来读取外部SD卡/NandFlash中的BL1

     S5PV210的SD卡启动详解2

    SoC支持SD卡启动的秘密(iROM代码)

    • 三星系列SoC支持SD卡/NandFlash启动,主要是依赖stepping stone技术,具体在S5PV210中支持stepping stone技术的是内部的iROM代码。

    SDHC卡和SD卡的区别?

    • SDHC卡相当于高容量的SD卡。
    • SD卡一般支持最大位2GB,而SDHC最大支持32GB,SDXC最大支持2TB

    再看iROM Application note:block device copy function

     扇区和块的概念

    • 早期的的块设备就会软盘硬盘这类次存储设备,这种设备的存储单元不是以字节为单位而是以扇区为单位。储存设备读写的最小单元就是扇区,不应该只读或者写部分扇区,也成为了编程时必须遵守的规律。
    • 一个扇区有好多个字节,一般是512字节,早起的磁盘扇区是512字节,实际上后来的磁盘扇区可以做的比较大,譬如1024字节,2048字节,4096字节,但是因为原先最早就是512字节,很多的软件和操作系统已经默认了512字节,因此后来的硬件虽然物理上可能支持更多更大的扇区,但是实际上还是兼容512字节的方法。
    • 一个扇区可以看成是一个块(块的概念就是:不是一个字节,是多个字节组成一个共同的操作单元块),于是就有了块的概念,所以就把这类的设备称为块设备,常见的块设备有:磁存储设备硬盘,软盘、DVD和Flash设备(U盘、SSD、SD卡、NandFlash、eMMC、iNand)
    • linux里有个mtd驱动,就是用来管理块设备的
    • 磁盘和我们的Flash以块位单位来读写就决定了我们启动时,device copy function只能以整块来读取SD卡。

    函数指针调用device copy function

    • 第一种方法:宏定义的方式来调用。好处是简单方便,坏处是编译器不能自动做参数的静态类型检查。
    • 第二种方法:用函数指针方式来调用

    S5PV210的SD卡启动实战1

    任务:大于16KB的bin文件,使用SD卡启动

    总体思路:将我们的代码分为两个部分:第一部分BL1为小于等于16KB,第二部分位任意大小。iROM代码执行完成后从SD卡启动会自动读取BL1到SRAM中执行。BL1执行时负责初始化DDR,然后手动将BL2从SD卡copy到DDR中的正确位置,然后BL1跳转到BL2中执行BL2部分

    • 细节1:我们的程序怎么安排?:整个程序分为两个文件夹BL1和BL2,各自管理各自的项目。
    • 细节2:BL1中要完成:关看门狗、设置栈、开icache,初始化DDR、从SD卡复制BL2到DDR特定位置,跳转执行BL2
    • 细节3:BL1在SD卡中必须从Block1开始(Block0不能用,这个是三星官方该规定的),长度为16KB内,我们就定义位16KB(也就是32个Block)
    • BL1理论上可以从32扇区开始,但是实际上我们安全都会留一些空扇区作为隔离譬如可以从45扇区开始,长度由自己定(实际根据自己的BL2大小来分配长度,我们BL2实验时非常小,因此我们定义BL2长度位为16KB,也就是32扇区)
    • 细节4:DDR初始化好后,整个DDR都可以使用,这时在其中选择一段长度足够BL2的DDR空间即可。我们选0x23E00000(因为我们BL1只初始化了DDR1,地址空间范围为:0x20000000~0x2FFFFFFF)

    代码分为两个部分(BL1和BL2)

    • BL1中的重定位
    • BL2远跳转

    因为我们BL1和BL2其实是2个独立的程序,链接时也是独立分开链接的,所以不能像以前一样使用ldr pc, =main这种方式来通过链接地址实现元跳转到BL2。

    我们的解决方案是使用地址进行强制跳转,因为我们知道BL2在内存地址0x23E00000处,所以直接去执行即可。

    S5PV210的SD卡启动实战2

    烧录启动试验

    • 代码分为2部分启动(上一节讲的缺陷)
    • 代码分为两个部分,这种技技术叫做分散加载。这种分散加载的方法可以解决问题但是比价麻烦。
    • 分散加载的缺陷:第一,代码完全分为两个部分,代码编写和组织上比较麻烦。第二,无法让工程项目兼容SD卡启动和Nand启动、NorFlash启动等各种方式

    uboot中的做法

    第二种思路:程序代码仍然包括BL1,BL2两个部分但是组织形式上不分为两个部分而是作为一个整体来组织。它的实现方式是:iROM启动,然后从SD卡的扇区1开始读取16KB的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中的这种启动方式比上节讲的分散加载的好处在于:能够兼容各种启动方式。

    解决X210开发板的软开关按键问题

    X210开发板的软启动电路详解

    • (1)210供电需要的电压比较稳定,而外部适配器的输出电压不一定那么稳定,因此板载了一个文稳压器件MP1482.这个稳压芯片的作用就是外部适配器电压在一定范围内变化时稳压芯片的输出电压都是5V。
    • (2)MP1482芯片有一个EN(Enable)引脚,这个引脚可以让稳压芯片输出或关闭输出。EN为高电平时有输出电压,EN引脚为低电平时稳压芯片无输出。
    • (3)两个因素可以影响EN引脚的电平:第一个是POWER按键(SW1),POWER按键按下时EN为高电平,POWER按键弹起时EN为低电平;第二个是POWER_LOCK(EINT0)引脚,这个引脚为POWER_LOCK模式下高电平,则EN为高;若这个引脚为EINT0模式或者为POWER_LOCK模式但输出为低电平,则EN为低。
    • (4)图中还有EINT1引脚,这个引脚的作用是用来做中断,提供给CPU用来唤醒的。

    为什么要软启动

    • (1)一般的电路设计都是用拨码开关来做电源开关的(打到一侧则接通,打到另一侧则关闭)。这种方式的优点是设计简单,缺点是电路太简单,整个主板要么有电要么没电无法做休眠模式、低功耗模式等。
    • (2)软启动电路是比较接近于实际产品的,其他开发板的硬开关其实是简化版的,和实际产品还有差异。

    开发板供电置锁原理和分析

    • (1)软开关在设计时有一个置锁电路,用EINT0(也就是GPH0_2)引脚来控制的。
    • (2)EINT0这个引脚是有复用设计(两个完全不相干的功能挤在同一个引脚上,同时我们只能让这个引脚用于其中一种功能,这就叫复用)的,一个是GPIO(也就是GPH0_2引脚)、一个是PS_HOLD_CONTROL。(注意:EINT0功能算是GPIO下的一个子功能)
    • (3)PS_HOLD在Section2.4 Power Management章节下的4.10.5.8节下。
    • (4)PS_HOLD_CONTROL寄存器(0xE010E81C),共有3个位有用。
    • bit0, 0表示这个引脚为GPIO功能,1表示这个引脚为PS_HOLD功能
    • bit9,0表示这个引脚方向为输入,1表示这个引脚方向为输出
    • bit8,0表示这个引脚输出为低电平,1表示输出为高电平。
    • 分析:我们要使用软启动置锁,则需要将bit0、8、9都置为1即可。

    写代码+实验验证

    • (1)要想让开发板和普通的开发板一样,一按下按键程序运行后即可松手不会断电,则只要在程序的开头部分添加代码去置锁开关板即可。
    • (2)置锁代码的方法是:给PS_HOLD_CONTROL寄存器的bit0、8、9均写入1即可。
    • (3)注意:此时开发板已经置锁,POWER按键已经失效,关机时需要按下复位按键。
  • 相关阅读:
    Java实现 LeetCode 679 24 点游戏(递归)
    Java实现 LeetCode 678 有效的括号字符串(暴力+思路转换)
    Java实现 LeetCode 678 有效的括号字符串(暴力+思路转换)
    Java实现 LeetCode 678 有效的括号字符串(暴力+思路转换)
    Java实现 LeetCode 677 键值映射(字典树)
    Java实现 LeetCode 677 键值映射(字典树)
    Java实现 LeetCode 677 键值映射(字典树)
    Java实现 LeetCode 676 实现一个魔法字典(暴力)
    PHP empty() 函数
    PHP floatval()、doubleval () 函数
  • 原文地址:https://www.cnblogs.com/jxjl/p/7138133.html
Copyright © 2020-2023  润新知