S5PV210体系结构与接口09:SD卡启动详解

目录

1. MMC技术演进

1.1 NandFlash & NorFlash芯片

1.2 MMC卡 & SD卡 & MicroSD卡(TF卡)

1.2.1 代际关系

1.2.2 技术共性

1.3 iNand & MoviNand

1.4 SD协议简介

1.4.1 物理接口与协议

1.4.2 速度等级

1.4.3 容量等级

2. x210的SD卡启动

2.1 拨码与启动

2.1.1 拨码开关设置

2.1.2 启动channel

2.2 iROM对SD/MMC启动的支持

2.2.1 Global Variable

2.2.2 External Copy Function

2.3 扇区布局

2.4 S5PV210为什么要支持SD卡启动

3. bootloader分散加载方案

3.1 代码拆分

3.2 串口打印说明

3.3 分散加载方案的缺陷

4. Uboot单镜像烧写方案

4.1 实现方法

4.2 脚本分析

4.3 验证与实现

5. 解决x210软开关问题

5.1 x210软启动电路分析

5.2 相关寄存器说明

5.3 代码实现


1. MMC技术演进

1.1 NandFlash & NorFlash芯片

这些芯片单纯由Flash颗粒组成,并且只针对存储单元实现了基本的读写接口,需要外部的SoC来提供Flash读写的控制器

缺点:

① 读写接口的时序比较复杂,且不同厂家的Flash接口不一致

② 没有坏块管理机制,需要SoC自己管理Flash坏块

1.2 MMC卡 & SD卡 & MicroSD卡(TF卡)

1.2.1 代际关系

从技术演进的时间关系上说,上述存储设备的出现时间如下,

MMC --> SD --> MicroSD(TF)

说明1:MicroSD卡就是原先的TF卡,于2004年正式更名

说明2:MMC标准比SD标准早,SD标准兼容MMC标准(即MMC卡可以被SD读卡器读写,而SD卡不可以被MMC读卡器读写)

说明3:MircoSD与SD的只是体积大小的区别,传输原理相同,相当于SD卡的小型化

1.2.2 技术共性

① Flash + Controller

这些卡内部也是Flash存储颗粒,但是比NandFlash芯片增加了Controller,用于进行ECC校验、坏块管理和损耗均衡(Wear leveling)

S5PV210体系结构与接口09:SD卡启动详解_第1张图片

② 统一标准规范

这些卡均遵循各自的标准规范,而不再是各个厂家单独定义。比如SD卡必须遵照SD规范设计。这些规范规定了SD卡的读写速度、读写接口时序、读写命令集、卡尺寸大小、引脚个数及定义。这样不同厂家的SD卡可以通用

1.3 iNand & MoviNand

iNand & MoviNand相当于SD卡的芯片化,二者均遵循eMMC接口标准,差别在于,

iNand是Sandisk公司根据eMMC标准生产的芯片

MoviNand是三星公司根据eMMC标准生产的芯片

目前很多嵌入式设备(e.g. 手机)不再使用外部扩展卡,而是内置大容量eMMC芯片

注意:在S5PV210中SD卡/MMC卡/eMMC芯片均由SD/MMC controller管理

1.4 SD协议简介

1.4.1 物理接口与协议

SD卡的物理接口随模式不同而异,具体如下,

S5PV210体系结构与接口09:SD卡启动详解_第2张图片

SPI协议特点(低速、接口时序简单):

① SPI协议是单片机中广泛使用的一种通信协议,并不是为SD卡专门发明的

② 相对于SD协议,SPI速度比较低

③ SD卡支持SPI协议,就是为了支持单片机使用

SD协议特点(高速、接口时序复杂):

① SD协议是原先专门用来和SD卡通信的,目前也可以用SDIO协议与其他芯片通信(比如SDIO WiFi)

② SD协议要求SoC中有SD控制器,运行在高速率下,要求SoC的主频不能太低

③ 在SD模式下,SD卡工作是通过命令(CMD)驱动的

1.4.2 速度等级

S5PV210体系结构与接口09:SD卡启动详解_第3张图片

1.4.3 容量等级

S5PV210体系结构与接口09:SD卡启动详解_第4张图片

2. x210的SD卡启动

2.1 拨码与启动

2.1.1 拨码开关设置

x210的启动拨码开关支持iNand启动和USB启动,具体电路如下,

S5PV210体系结构与接口09:SD卡启动详解_第5张图片

OM[5]:通过拨码开关选项

OM[4]:0

OM[3]:1

OM[2]:1

OM[1]:0

OM[0]:1

对照S5PV210 iROM手册可知,

当OM[5] == 0时,启动设备为SD/MMC

当OM[5] == 1时,使用UART -> USB的启动方式

此处需要注意2点:

① UART -> USB启动是一套完整流程,先尝试UART启动,当UART启动time out时从USB启动

② 根据拨码开关电路,OM[0]的值为1,这个选项对应了X-TAL(USB)晶振,这点和实际情况不符,此处存疑~~

S5PV210体系结构与接口09:SD卡启动详解_第6张图片

2.1.2 启动channel

① 如果选择从SD/MMC/eMMC启动,默认从channel 0启动。如果从channel 0启动失败,Second boot从channel 2启动

② 需要注意的是,SD/MMC/eMMC的channel 2也是所有启动设备的Second boot设备,即从其他存储设备启动失败时,均会尝试从MMC channel 2启动

S5PV210体系结构与接口09:SD卡启动详解_第7张图片

在x210中,iNand接在MMC channel 0

S5PV210体系结构与接口09:SD卡启动详解_第8张图片

同时设置了2个SD卡槽,分别使用MMC channel 2和channel 3

S5PV210体系结构与接口09:SD卡启动详解_第9张图片

S5PV210体系结构与接口09:SD卡启动详解_第10张图片

因此,如果想从SD卡启动,必须破坏iNand中的Uboot,使其校验不通过,从而进入MMC channel 2的Second boot流程。

破坏方式是进入Linux系统控制台,然后擦除Uboot所在分区的第2个扇区(seek=N即skip N obs-sized blocks at start of output,obs-size默认为512B)

busybox  dd  if=/dev/zero  of=/dev/mmcblk0  bs=512  seek=1 count=1 conv=sync

sync // 此处再执行一次sync命令以保万全

说明:根据S5PV210的启动流程,只要Uboot的前16KB校验失败,启动自然就进入Second boot流程

2.2 iROM对SD/MMC启动的支持

在之前介绍的iRAM布局中,有2个部分与SD卡启动密切相关,即External Copy Function和Global Variable

S5PV210体系结构与接口09:SD卡启动详解_第11张图片

2.2.1 Global Variable

S5PV210体系结构与接口09:SD卡启动详解_第12张图片

当从MMC设备启动时,与该设备相关的信息必须被记录在Global Variable区域

示例:

在x210 Uboot的movi_bl2_copy函数中就会根据0xD0037488(V210_SDMMC_BASE)中的数值判断当前的SD channel,进而从适当的设备中拷贝BL2至内存中

S5PV210体系结构与接口09:SD卡启动详解_第13张图片

验证:

SD卡启动时,打印如下

可见SD卡启动确实使用了channel 2

补充:globalSDHCInfoBit各字段分析

bit [0] = 1:High Capacity Enable

bit [2] = 1:SD Card

RCA(Relative Card Address) Data = 0x21e1

USB启动时,打印如下

通过验证可推测,Global Variable中的数值应该是iROM代码写入的,我们的代码可以读取相关数据,并执行相应的分支

2.2.2 External Copy Function

S5PV210体系结构与接口09:SD卡启动详解_第14张图片

S5PV210的iROM代码中提供了一组从外部存储设备拷贝数据到内存的函数,iROM在读取BL1时也是使用这些函数

S5PV210体系结构与接口09:SD卡启动详解_第15张图片

在x210的Uboot代码中,也使用iROM提供的拷贝函数实现BL2的拷贝。代码中使用的0xD0037F98对应的就是CopySDMMCtoMem函数

S5PV210体系结构与接口09:SD卡启动详解_第16张图片

CopySDMMCtoMem函数的使用方法如下,

S5PV210体系结构与接口09:SD卡启动详解_第17张图片

需要注意如下3点:

拷贝函数实际在iROM当中,所以使用时需要解一次引用

② CopySDMMCtoMem函数的第一个参数是MMC channel

③ 这些函数均在iROM设定的时钟频率下工作(e.g. 此处在20MHz工作),如果后续需要更高的传输速度,需要在Uboot中实现SD/MMC驱动(e.g. driver/mmc.c)

2.3 扇区布局

S5PV210体系结构与接口09:SD卡启动详解_第18张图片

如果使用SD卡,需要空出第0号扇区,从第1号扇区使用。根据实际测试,x210应该是将SD卡和iNand均作为SD/MMC设备使用

而且eMMC从Block 0开始存储BL1也不合理啊,这里应该存放MBR(include分区表)

说明:扇区和块的概念

早期的块设备是软盘硬盘这类磁存储设备,这种设备的存储单元不是以字节为单位,而是以扇区为单位

早期磁盘每个扇区512字节,但是后期磁盘可以支持1/2/4KB的扇区。但是由于之前很多软件(包括操作系统和文件系统)已经默认使用512B,因此后来的硬件虽然物理上支持更大的扇区,但实际上还是兼容512B扇区的操作

2.4 S5PV210为什么要支持SD卡启动

如果说iROM + iRAM的设置是为了省去NorFlash,那么支持SD卡启动就可以省去Flash烧录器

x210在贴片完成后,iNand中没有内容,拨码至eMMC启动自然会进入SD卡启动流程,此时只要将支持刷机的Uboot和需要烧写的文件放入SD卡,就可以实现量产刷机

关于量产卡的制作可以参考下面的文档,其核心就是SD卡分作2部分使用,

① 从编号1扇区开始烧写uboot.bin,该代码需要支持SD卡升级流程(当然,为适应S5PV210的启动流程,uboot.bin烧写时会分为BL1 & BL2,后文中有叙述)

② 从SD卡的256MB之后构建FAT 32分区,将要烧写的文件放入其中。量产刷机时,uboot就是从该分区获取要烧写的文件并进行刷机

3. bootloader分散加载方案

核心:拆分代码,单独编译链接镜像

3.1 代码拆分

① 代码拆分原因

根据S5PV210的启动流程,BL1最大16KB,也就是说iROM最多从SD卡中读取16KB数据作为BL1运行。但目前Uboot编译出的镜像文件一般在200 ~ 500KB,所以需要将代码拆分编译

S5PV210体系结构与接口09:SD卡启动详解_第19张图片

S5PV210体系结构与接口09:SD卡启动详解_第20张图片

② BL1代码解析

链接地址:0xD0020010(如果BL1中没有地址相关操作,链接地址无妨)

主要工作:

a. 核心初始化(e.g. 关闭看门狗、设置栈等)

b. 初始化内存

c. 将BL2从SD卡拷贝到内存

d. 跳转到内存继续运行

核心代码分析:

S5PV210体系结构与接口09:SD卡启动详解_第21张图片

说明:拷贝完成后,直接跳转到拷贝的内存目的地址运行,因此后续的led3函数不会被调用(此处设置仅为验证)

③ BL2代码解析

链接地址:0x23E00000(其实是经过初始化的内存就可以,此处选择该值只是为了和x210的Uboot相同)

主要工作:此处只是简单跳转到主函数运行

注意:此处的BL1 & BL2代码只是为了示意分散加载方案的实现,因此失于简陋,很多需要做的处理并没有做(e.g. BL1和BL2均没有清bss段)

④ 烧写位置说明

BL1从编号1扇区开始:

从SD卡的编号1扇区开始使用,是S5PV210芯片的要求

BL2从编号45扇区开始:

BL1从编号1扇区开始,最大16KB,也就是需要32个扇区,所以BL2的起始地址 >= 33即可。此处从45开始,中间空余的扇区可以存放Uboot环境变量等信息

参考代码:

3.2 串口打印说明

S5PV210体系结构与接口09:SD卡启动详解_第22张图片

破坏iNand中的Uboot后启动会失败,如果不插入SD卡,打印如上方的红框所示

SD checksum Error:iNand启动时,BL1校验失败

SD Init Error:Second boot MMC channel 2 SD卡初始化失败

Uart negotiation Error:Second boot失败后会尝试从UART启动,此处为Uart time out打印

Insert an OTG cable into the connector:UART启动失败后,会尝试从USB启动

S5PV210体系结构与接口09:SD卡启动详解_第23张图片

插入SD卡后启动,如果启动成功,就只会有BL1校验错误的SD checksum Error打印。并且如我们的预期,能实现LED的闪烁

特别注意:此处的串口打印源自UART1,即iROM中使用UART1打印;而我们自己的裸机代码中使用UART0打印

3.3 分散加载方案的缺陷

① BL1 & BL2完全分离,代码编写和组织比较麻烦(e.g. 两部分代码需要分别编译链接,但相互之间又有联系)

② 不能兼容SD卡和其他启动方式

4. Uboot单镜像烧写方案

核心:一份代码,一个镜像,截取16KB制作BL1

4.1 实现方法

① 使用一份代码编译出一个uboot.bin镜像

② 从uboot.bin中截取16KB(x210 uboot实现中是8KB),并计算其校验值,然后在该部分代码前加头,构成BL1

③ 将BL1烧写到SD卡编号1扇区

④ 将整个uboot.bin烧写到SD卡编号49扇区

说明:启动运行流程

① iROM先运行,由于iNand中的Uboot已被破坏,进入Second boot流程,从MMC channel 2的SD卡启动

② 从SD卡的编号1扇区开始读取16KB至iRAM运行,这部分就是BL1

③ BL1需要完成内存初始化,然后从SD卡的第编号49扇区读取整个uboot.bin至Uboot的链接地址

④ 跳转到内存中运行

特别注意:此处不是跳转到内存的Uboot链接地址处运行,而是跳转到内存中接着BL1运行

说明:一般情况下,BL1和BL2是汇编代码和C代码的分水岭。BL2的起始地址是一个C函数,BL1在完成环境初始化和代码重定位后,就是跳转到BL2的起始C函数开始运行

4.2 脚本分析

S5PV210体系结构与接口09:SD卡启动详解_第24张图片

① uboot_inand.bin就是编译出的完整Uboot镜像,大小约384KB

② 首先调用mkbl1程序从uboot_inand.bin中读出8KB,并对其校验加头构成BL1

③ 然后将BL1烧写到SD卡编号1扇区

④ 最后将整个uboot_inand.bin烧写到SD卡编号49扇区

4.3 验证与实现

说明:由于x210提供的一套uboot源代码环境还没有验证过(补充:后续已验证可行,但需要简单修正脚本~~),目前使用mkv210_image.c代码制作BL1

① 添加movi_bl2_copy函数

S5PV210体系结构与接口09:SD卡启动详解_第25张图片

此处我们从编号45扇区开始,拷贝64个扇区的内容至链接地址

② 在start.S中调用movi_bl2_copy实现代码重定位

S5PV210体系结构与接口09:SD卡启动详解_第26张图片

说明1:code_relocate函数用于实现从iRAM到DDR的代码重定位,此处不再调用

说明2:在调用过movi_bl2_copy之后,直接跳转到DDR中运行start_main函数

③ 修改链接器脚本,确保movi.c被链接到前16KB

将BL1阶段需要用到的代码链接到最前端,确保其在前16KB范围内

5. 解决x210软开关问题

5.1 x210软启动电路分析

S5PV210体系结构与接口09:SD卡启动详解_第27张图片

① MP1482芯片的作用:当外部适配器电压在一定范围内变化时,稳压芯片的输出电压都是5V

② MP1482芯片有一个EN(Enable)引脚,这个引脚可以控制芯片是否工作。EN为高电平时有输出电压,EN为低电平时稳压芯片无输出。有2个因素会影响EN引脚的电平,

a. POWER按键,POWER按键按下时EN为高电平;POWER按键弹起时EN为低电平

b. POWER_LOCK引脚,若该引脚为EINT0模式或为POWER_LOCK模式但输出为低电平,EN为低;若该引脚为POWER_LOCK模式,且输出为高,则EN为高电平

③ 图中的EINT1引脚作为中断提供给CPU,用于实现唤醒

说明:x210为什么使用软启动?

一般开发板使用拨码开关做电源开关,虽然使用简单,但是整个开发板要么通电,要么没电,无法实现休眠 / 低功耗等电源模式。使用软启动的电路,比较接近实际产品

5.2 相关寄存器说明

软开关在设计时有一个置锁电路,用EINT0(GPH0_0)引脚来控制。而EINT0管脚可以用作PS_HOLD_CONTROL功能,具体寄存器如下(datasheet P470)

S5PV210体系结构与接口09:SD卡启动详解_第28张图片

PS_HOLD_CONTROL寄存器,共有3个位有用,

bit 0,0表示这个引脚为GPIO功能,1表示这个引脚为PS_HOLD功能

bit 9,0表示这个引脚方向为输入,1表示这个引脚方向为输出

bit 8,0表示这个引脚输出为低电平,1表示输出为高电平

因此,要想将软启动置锁,需要将bit 0、8、9均置为1

5.3 代码实现

S5PV210体系结构与接口09:SD卡启动详解_第29张图片

代码中在关闭看门狗之前将PS_HOLD置锁,可以尽快实现开发板始终通电的目的。需要注意的是,开发板置锁后,POWER按键已经失效,关机时需要按下复位按键

你可能感兴趣的:(Linux嵌入式开发,arm,嵌入式硬件,fpga开发)