6.7. SPI NAND 启动

在常见的方案中,通常划出前面4个 Block 作为保存第一级引导程序的保存分区,并且在每个 Block 中保存一份启动镜像。 本芯片的实现方案有一些不同。

6.7.1. 候选启动块

本方案中同样划出前面4个 Block 作为第一级引导程序的保存区域, 这个区域称为显式的第一级引导程序保存区域,进行 MTD 分区时,应该将其预留为启动分区。

除此之外,本方案还另外定义了 14 个索引号为偶数的 Block 作为保存第一级引导程序的候选块, 这14个块从 NAND 的前1024个块中随机选取。对于块大小为 128K 的 NAND,候选块分布在前 128MB, 对于块大小为 256KB 的 NAND,候选块分布在前 256MB。

如下表,总共有18个 Block 作为候选启动块。这些启动块的使用规则是:

  1. 按照优先顺序,逐个检查是否为好块

  2. 按顺序选出4个好块作为启动块,分别写入启动镜像

  3. 对于后14个候选块,如果被选中作为启动块,则在烧录启动镜像时将其标记为坏块,以及启动块的特殊标记。标记为坏块的目的是防止其他应用再次使用该块而导致启动镜像被破坏

  4. 如果表中所列候选块都是坏块,该 SPI NAND 无法作为启动器件使用

表 6.3 候选启动块列表

优先顺序

Block ID

说明

1

0

启动分区内,优先使用

2

1

启动分区内,优先使用

3

2

启动分区内,优先使用

4

3

启动分区内,优先使用

5

202

如果是好块,则作为启动块。写入启动镜像后标记为坏块

6

32

如果是好块,则作为启动块。写入启动镜像后标记为坏块

7

312

如果是好块,则作为启动块。写入启动镜像后标记为坏块

8

296

如果是好块,则作为启动块。写入启动镜像后标记为坏块

9

142

如果是好块,则作为启动块。写入启动镜像后标记为坏块

10

136

如果是好块,则作为启动块。写入启动镜像后标记为坏块

11

392

如果是好块,则作为启动块。写入启动镜像后标记为坏块

12

526

如果是好块,则作为启动块。写入启动镜像后标记为坏块

13

452

如果是好块,则作为启动块。写入启动镜像后标记为坏块

14

708

如果是好块,则作为启动块。写入启动镜像后标记为坏块

15

810

如果是好块,则作为启动块。写入启动镜像后标记为坏块

16

552

如果是好块,则作为启动块。写入启动镜像后标记为坏块

17

906

如果是好块,则作为启动块。写入启动镜像后标记为坏块

18

674

如果是好块,则作为启动块。写入启动镜像后标记为坏块

准备这些候选块的目的是为了增强 BROM 对各种品质 SPI NAND 的适应性。 虽然每个厂商都宣称 NAND 的前面几个块质量较好的,但是在实际应用中,不可避免会遇到前面4个候选块为坏块的场景。 并且 NAND 出现坏块时,通常会出现连续坏块。因此这里设计16个候选块时, 后14个块是随机选取的。这样既兼容传统用法,方便理解和使用,又在坏块较多的情况下,提高可启动的概率。

备注

在正常情况下,烧录的 SPI NAND 前面四个块为好块,则仅有前面四个块被用作启动块, 后面的 14 个候选块不需要保留,可以作为其他用途。

6.7.2. Page table

烧录在启动块上的数据并不仅仅是启动镜像,还包括一个页索引表(Page Table)。Page Table 的目的是构建一个全局的索引表,通过该索引表,可以找到保存4个备份镜像的所在 Page 的地址(PA)。 这样 BROM 一旦读取到正确的 Page Table,就可以直接读取到4个备份镜像,减少尝试的时间。

Page Table 总是保存在启动块的Page0 中,启动镜像则从Page1 开始保存。启动块中数据的分布如下。

表 6.4 启动块中的 Page 数据

页号

内容

Page 0

保存 Page Table(2KB) 的数据,仅使用前2KB

Page 1

启动镜像的第1个2KB/4KB 数据

Page 2

启动镜像的第2个2KB/4KB 数据

Page 3

启动镜像的第3个2KB/4KB 数据

Page 4

启动镜像的第4个2KB/4KB 数据

……

……

小心

本方案只支持 Page 大小为 2KB 和 4KB 的 SPI NAND。

Page Table 中包括一个头信息,以及4个备份镜像所在的页地址。其格式如下表所示。

表 6.5 Page table 的格式

区域

名字

字节

备注

Head

Magic

4

“AICP” 标记

Entry Count

4

启动镜像占用的 Page 数量

Page Size

2

当前 SPI NAND 的 Page Size

Page per block

1

当前 SPI NAND 中,一个块的页数量

Blocks

1

当前 SPI NAND 的块数量

Planes

1

当前 SPI NAND 的 Plane 数量

Padding

7

Data Page1

Block0 Page 1 Address

4

启动镜像第1个Page数据保存在 Block0 中的 Page 地址

Block1 Page 1 Address

4

启动镜像第1个Page数据保存在 Block1 中的 Page 地址

Block2 Page 1 Address

4

启动镜像第1个Page数据保存在 Block2 中的 Page 地址

Block3 Page 1 Address

4

启动镜像第1个Page数据保存在 Block3 中的 Page 地址

Page 1 Data Checksum

4

启动镜像第1个Page数据的32位校验和

Data Page2

Block0 Page 2 Address

4

启动镜像第2个Page数据保存在 Block0 中的 Page 地址

Block1 Page 2 Address

4

启动镜像第2个Page数据保存在 Block1 中的 Page 地址

Block2 Page 2 Address

4

启动镜像第2个Page数据保存在 Block2 中的 Page 地址

Block3 Page 2 Address

4

启动镜像第2个Page数据保存在 Block3 中的 Page 地址

Page 2 Data Checksum

4

启动镜像第2个Page数据的32位校验和

备注

此处中的 Block0、Block1、Block2、Block3 是指选定的四个候选块。

使用 Page Table,除了可以快速定位4个启动备份镜像在 SPI NAND 中的位置,还可以提高启动成功的概率。 在极端情况下,可能出现四个启动块都在使用过程中变成坏块的情况,BROM 无法从单个块中读取完整启动镜像。 借助 Page Table 的信息,只要不出现同一块镜像数据在4个启动块中都出现损坏的情况, 此时 BROM 还可以通过组织分布在不同启动块中没有损坏的 Page 数据,重建出一个完整的启动镜像。

6.7.3. SPI NAND 的启动流程

SPI NAND 启动时,首先按照上述的候选块顺序,逐个尝试从候选启动块读取 Page Table。一旦找到可以用的 Page Table,就可以找到4个备份镜像保存的页地址(PA)。 接下来尝试从单个启动块中读取完整的备份镜像。共有4个备份镜像,逐个尝试。 如果4个启动块中的备份镜像都出现读取错误,这时可以尝试将4个启动块中没有出错的 Page 数据进行组合的方式,重建完整的启动镜像。 如果都失败,则从 SPI NAND 启动失败。

../../_images/spinand_boot_flow.png

图 6.8 SPI NAND 启动流程