@[toc]作者:ZHangZMo
作者:ZHangZMo
本专题将图文详解SAMA5D2-Cortex-A5内核处理器,在上电后直到加载Linux内核之前到底做了哪些操作,帮助了解处理器的启动过程,特别是针对Nand Flash启动配置、Flash PMECC参数配置做了详细图解。
- 上电运行MPU内部集成的boot ROM
boot ROM作为第一级bootloader首先会初始化处理器时钟(Processor Clock - CPU_CLK)和主时钟(Master Clock - MCK),主RC Oscillator(时钟发生器模块)会通过快速启动来唤醒整个系统,这时主时钟MAINCK这块也是使用RC Oscillator,由PMC(Power Management Controller)负责将MAINCK作为CPU Clock(CPU_CLK)和Master Clock(MCK).

接着初始化PLLA锁相环,将系统频率倍频到756MHz并等待PLLA倍频后的频率能够稳定工作,此时PMC里的处理器时钟控制器(Processor Clock Controller)会选择PLLA的输出作为CPU Clock(CPU_CLK)和Master Clock(MCK)的输入时钟源.

在boot ROM运行时其他模块工作时钟频率.

boot ROM随后读取启动配置字(Boot Confguration Word)来决定系统工作模式:
- (1) 从安全熔丝控制器SFC(Secure Fuse Controller)读取启动配置字(Boot Confguration Word).
- (2) 检查是否禁止访问BSCR寄存器(Boot Sequence Configuration Controller Register) - DISABLE_BSCR = 1为真,则执行步骤(3),否则执行步骤(4).
- (3) 从安全熔丝控制器SFC读取启动控制字,配置字读取流程结束。
- (4) 读取BSC_CR寄存器(Boot Sequence Configuration Controller Register)
- (5) 判断读取的BSC_CR的值里面BUREG_VALID(BUREG_INDEX数据是否有效)比特位是否为1,不为1则执行步骤(6),否则执行步骤(7).
- (6) 直接以SFC里面的启动配置字(Boot Confguration Word)作为系统启动配置
- (7) 读取BSC_CR的值里面BUREG_INDEX[1:0]的值(取值范围是0~3),执行步骤(8)
- (8) 读取BUREG_n(n就是BUREG_INDEX[1:0]的值),比如n=1则直接取BUREG_1的值,作为系统启动配置字。


Boot Configuration Word启动配置字的作用如下:
- 配置NVM所在外设的管脚IOSET组合(例如eMMC0接口选择IOSET0组合)
- 禁止boot使用的外设模块(例如禁止boot时使用eMMC0接口)
- 配置UART用于串口打印输出口
- 配置JTAG口所在的管脚用于调试
启动配置字(Boot Confguration Word)解析:
- 默认值为0,系统只选择从eMMC0和eMMC1启动
- 在调试阶段可以覆盖默认的启动配置字,需保持VDDBU一直供电且DISABLE_BSCR值为0(默认值),且往BUGREG_INDEXn和BUREGn写入有效值

- 也可以将需要修改的启动配置字写入fuse,这是一次性的操作(需慎重)
- 启动配置字Boot Confguration Word寄存器

- QSPI_0[1:0],配置QSPI0选择哪组IOSETn

- QSPI_0[1:0]值为0,则配置QSPI0选择IOSET1(QSPI0功能放在PA2上)

- QSPI_0[1:0]值为1,则配置QSPI0选择IOSET2(QSPI0功能放在PA16上)

手动更改启动配置字(Boot Confguration Word)操作步骤如下:
- 读取BSCR寄存器操作命令(Boot Sequence Configuration Controller Register)
sam-ba -p serial -d sama5d29 -a bootconfig -c readcfg:bscr
- 使能BUREGn寄存器操作命令(使能Backup Register 0)
sam-ba -p serial -d sama5d29 -a bootconfig -c writecfg:bscr:bureg0,valid
- 写BUREGn寄存器操作命令(更新Backup Register 0 - UART1和JTAG都采用IOSET1)
sam-ba -p serial -d sama5d29 -a bootconfig -c writecfg:bureg0:UART1_IOSET1,JTAG_IOSET1
boot ROM接着将完成下述初始化操作:
- 为Arm supervisor模式配置好系统堆栈.
- PLLA 的初始化
- Master Clock的选择: 当PLLA稳定后Master Clock从内部12 MHz RC切换到PLLA,接着轮询PMC状态寄存器直到MCK能够稳定,此时系统的主时钟就切换成PCK和MCK。
- C运行环境的初始化: 变量的拷贝(从ROM拷贝到内部SRAM)和初始化操作。
- boot ROM从外部存储NVM中寻找有效的第二级bootloader - at91bootstrap并加载到芯片内部SRAM中运行(没找到at91bootstrap则转为SAM-BA Monitor模式等待sam-ba命令连接)
在NVM中寻找有效的第二级bootloader,包括以下的操作:
- ARM中断向量表的检测 - 适合于Nand、SPI/QSPI Flash启动
- boot.bin文件的检测 - 适合eMMC/SD卡启动,寻找FAT分区里的boot.bin文件

- 预留的中断向量表6会在编译at91bootstrap的时候就自动插入生成的at91bootstrap文件的大小。

- at91bootstrap完成系统时钟、DDR控制器等初始化
- at91bootstrap加载U-Boot到外部DDR并运行

boot ROM从外部存储中寻找第二级bootloader过程如下:

boot ROM从Nand Flash中寻找第二级bootloader过程如下:

- 在对Nand Flash控制器进行初始化后并向Nand Flash发送复位命令后,boot ROM程序读取Nand Flash第一页数据并且不进行ECC检查,然后对读取的数据进行判断是否包含有Nand Flash参数的有效头文件在里面。
- 这个有效头文件会连续出现52次,由一个32bit长度的word类型构成,包含Nand Flash页的配置、PMECC参数等,这些信息将会帮助读取后面Nand Flash其他数据。
- 如下图连续出现52次的0xC0902405

Nand Flash第一页中读取到的有效头文件含义如下:

- Bits 31:28 key[3:0] - 出现的值必须为0xC,用去确认整个word字的有效性.
- Bits 26:18 eccOffset[8:0] – 第一个ECC字节在空闲区间出现的偏移地址.
- Bits 17:16 sectorSize[1:0] – ECC Sector的大小,0对应512,1对应为1024.
- Bits 15:13 eccBitReq[2:0] – 所需要多少位的ECC, 0对应2bit ECC/1对应4bit ECC/2对应8bit ECC/3对应12bit ECC/4对应24bit ECC/5对应32bit ECC.
- Bits 12:4 spareSize[8:0] – Nand Flash每个page空闲区间(OOB)大小(字节).
- Bits 3:1 nbSectorPerPage[2:0] - 每页包含多少个Sectors,Sectors数量的2^n.
- Bit 0 usePMECC - 是否使用PMECC,1表示使用PMECC功能(开启Nand ECC功能).
参考前面给出的0xC0902405有效头文件,我们可以得到以下信息:
- key值对应没问题(为0xC)
- eccOffset的值为36
- sectorSize值为0-对应sector大小为512字节
- eccBitReq值为1-对应需要4bit ECC.
- spareSize值为64-对应Nand Flash每个page空闲区间大小为64字节.
- nbSectorPerPage值为2-对应每页包含2^2个Sectors(即为4).
- usePMECC为1表示启用PMECC功能

复习一下ECC校验位大小和ECC占用字节的关系:
- ECC纠正能力 vs OOB占用空间
| ECC纠正能力 | 512字节每sector | 1024字节每sector |
|---|---|---|
| 2bit | 4 Bytes | 4 Bytes |
| 4bit | 7 Bytes | 7 Bytes |
| 8bit | 13 Bytes | 14 Bytes |
| 12bit | 20 Bytes | 21 Bytes |
| 24bit | 39 Bytes | 42 Bytes |
- OOB占用空间分布图
| OOB | ||||||||
|---|---|---|---|---|---|---|---|---|
| ff | ff | ff | ff | ff | ff | ff | ff | |
| ff | ff | ff | ff | ff | ff | ff | ff | |
| ff | ff | ff | ff | ff | ff | ff | ff | |
| ff | ff | ff | ff | ff | ff | ff | ff | |
| ff | ff | ff | ff | 4d | 3e | 2c | 5a | |
| 4e | 5f | 6c | 4b | 55 | 2a | 1f | 7e | |
| bd | f3 | 0f | 32 | 90 | 56 | 68 | d7 | |
| 2e | bd | 4b | 02 | 59 | 19 | 3b | 01 |
现在Nand Flash page大小为2048,sector大小为512,则每个page分为4个sector(2048/512),且采用4bit ECC纠错能力,则每个sector ECC校验数据需要在OBB中占用7 Bytes空间,则每个page一共占用74=28字节空间。ECC校验数据在OBB中存放的起始位置为64-47=36,和前面提到的eccOffset值为36就对应上了。
4641

被折叠的 条评论
为什么被折叠?



