Edit online

配置启动分区

5 Dec 2024
Read time: 7 minute(s)

本节描述不同存储介质的默认分区方案,仅涉及启动相关的分区。应用相关的分区不同的方案会有不同的选择,此节未做描述。

在 ArtInChip 的方案中:
  • env.txt 可以配置分区表信息,包括各分区在存储介质中的位置和大小。

    env.txt 通常位于 target/<ic>/common/

  • 各项目对应的 image_cfg.json 中设置分区要烧录的内容。

MMC 分区配置

MMC 包括 SD Card 和 eMMC。对于 eMMC,ArtInChip 方案中不支持从 Boot Partition 启动, 只支持从 UDA (User Data Area) 启动,因此具体的分区方式与 SD Card 一致,统一采用 GPT 分区。

  • 目标平台上的 GPT 分区

    在项目的image_cfg.json 中配置具体分区。使用 mk_image.py 生成镜像过程中,相关分区信息会被添加到 env.bin 中,以 GPT= 格式存储在环境变量中,示例如下:
    GPT=size1@offset1(partition name1),size2@offset2(partition name2),-(last partition)
    其中
    • size 是分区的大小。
    • offset 是分区的开始位置,相对 UDA 的开始位置,单位为字节。

      如果是最后一个分区,可以不设置 size@offset,使用 - 代替,表示剩余的所有空间都分配给该分区。

    例如 image_cfg.json 中的分区配置:
    "mmc": { // Media type
        "size": "8G", // Size of SD/eMMC
        "partitions": { // Partition table apply to device
                "spl_1":  { "offset": "0x4400", "size": "128k" },
                "spl_2":  { "size": "367k" },
                "uboot":  { "size": "1m" },
                "env":    { "size": "512k" },
                "kernel": { "size": "16m" },
                "rootfs": { "size": "64m" },
                "user":   { "size": "-" },
        },
    },
    环境变量中保存的格式:
    GPT=128k@0x4400(spl_1),367k(spl_2),1m(uboot),512k(env),16m(kernel),64m(rootfs),-(user)
    不设置 offset,表示各分区相连,程序自动计算该分区的开始位置:
    GPT=128k(spl_1),367k(spl_2),1m(uboot),512k(env),512k(bootui),512k(dtb),
        16m(kernel),64m(rootfs),-(user)
    注:

    UDA 的前面 34 个 block 被用作 GPT Header,无论第一个分区是否设置 offset,程序在做分区时都会预留 34 个 block 给 GPT Header。即:128k@0x4400(spl_1) 和 128k(spl_1) 是一样的。

    1. 基本分区
    分区 大小 - 备注
    spl_1 128KB RAW 分区开始位置固定,从 0x4400 开始,大小固定
    spl_2 ≥ 128KB RAW 分区开始位置固定,镜像备份,可不要
    uboot . RAW 大小根据实际项目需要配置
    env ≥16KB RAW 保存环境变量
    dtb . RAW 保存 kernel dtb,大小根据实际情况分配
    kernel . RAW 大小根据实际项目需要配置
    rootfs . Ext4 大小根据实际项目需要配置
    user . Ext4 大小根据实际项目需要配置

    如果 Kernel 使用 FIT Image 格式,上述分区中的 dtb 可以省略。 user 分区以及是否有更多的应用分区,由具体项目决定。

  • SD 量产卡的 GPT 分区

    量产卡用在工厂生产过程中,通过运行量产卡中的升级程序,对目标平台进行量产升级。 具体的分区设置在 env.txt 中的 burn_mmc= 配置。例如:
    burn_mmc=128k@0x4400(spl_1),367k(spl_2),1m(uboot),512k(env),512k(bootui),-(image)
    2.
    分区 大小 - 备注
    spl_1 128KB RAW 用于升级的 SPL
    spl_2 ≥ 128KB RAW 用于升级的 SPL 备份
    uboot . RAW 用于升级的 U-Boot
    env ≥ 16KB RAW 保存环境变量
    data . RAW 保存用于烧录固件镜像文件

    目标平台在启动到 U-Boot 时,进入量产模式。U-Boot 量产程序从 data 分区读取固件数据,并且烧录到目标存储介质。

  • SPL 分区的特别说明

    MMC GPT 分区时,BROM 启动过程中,固定从两个地方读取 SPL 程序的备份。 首先尝试读取 SPL 备份 1,如果验证失败,再尝试读取 SPL 备份 2。其中备份 2 是可选的。
    分区 大小/位置 备注
    GPT HEADER 17KB(LBA0~LBA33) 预留给 GPT Header
    备份 1 128KB(LBA34~LBA289) 必须
    备份 2 128KB(LBA290~LBA545) 可选

SPI NAND 分区配置

具体的分区在项目的 image_cfg.json 中配置,mk_image.py 生成镜像过程中,相关分区信息会被添加到 env.bin, 以 MTD=UBI= 格式存储在环境变量中:

MTD=size1@offset1(partition name1),size2@offset2(partition name2),-(last partition)

其中 size 是分区的大小,offset 是分区的开始位置(相对 UDA 的开始位置,单位为字节)。 如果是最后一个分区,可以不设置 size@offset,使用 - 代替,表示剩余的所有空间都分配给该分区。

例如: image_cfg.json 中的分区配置:

"spi-nand": { // Device, The name should be the same with string in image:info:media:type
    "size": "128m", // Size of SPI NAND
    "partitions": {
            "spl":    { "size": "1m" },
            "uboot":  { "size": "1m" },
            "env":    { "size": "256k" },
            "kernel": { "size": "12m" },
            "ubiroot": {
                    "size": "32m",
                    "ubi": { // Volume in UBI device
                            "rootfs": { "size": "-" },
                    },
            },
            "ubisystem": {
                    "size": "-",
                    "ubi": { // Volume in UBI device
                            "user":   { "size": "-" },
                    },
            },
    }
},

生成的环境变量内容:

MTD=spi1.0:1m(spl),1m(uboot),256k(env),12m(kernel),32m(ubiroot),-(ubisystem)
UBI=ubiroot:-(rootfs);ubisystem:-(user)

前面 MTD= 描述 MTD 分区的配置,后面 UBI= 描述被用作 UBI 的 MTD 分区的 UBI 卷分配。

注:

mtdids 与使用的 spi 接口有关系。当使用 spi0 接口时,为 spi0.0。当使用 spi1 接口时,为 spi1.0

Boot 阶段相关的几个分区有两种备选方案。

方案一: MTD 分区

分区 大小 - 备注
spl 1MB RAW 保存 SPL 备份的区域
uboot 2MB RAW 保存 U-Boot,需要预留空闲备用块
env 1 Block RAW 保存环境变量
envbak 1 Block RAW 保存环境变量备份,可不用
dtb 1 Block RAW 保存 kernel dtb
kernel . RAW 保存 kernel,需要预留空闲备用块
rootfs . UBIFS -
user . UBIFS -

方案二: UBI 分区

分区 大小 - 备注
spl 1MB RAW 保存 SPL 备份的区域
uboot 2MB RAW 保存 U-Boot,需要预留空闲备用块
env 1 Block RAW 保存环境变量
envbak 1 Block RAW 保存环境变量备份,可不用
dtb 1 Block UBI 保存 kernel dtb
kernel . UBI 保存 kernel
rootfs . UBIFS -
user . UBIFS -

上述两个方案中,差别在于 dtb/kernel 部分是否使用 UBI 分区。由于使用 UBI 分区在启动速度上比使用 MTD 分区稍微慢一点,因此后续如果没有其他原因, 优先使用方案一的分区方式,即启动阶段读取的数据统一使用 MTD 分区保存。

SPL 分区的特别说明

由于 NAND 可能会有坏块,为了尽可能的支持有坏块的 NAND 器件,ArtInChip 平台对 SPL 备份的存储方案做了一些特殊处理。

  • 首先在 NAND 存储设备中,烧录时 SPL 会保存 4 个备份,每个备份占用一个物理擦除块(PEB)。 因此在 NAND 中,共有 4 个 PEB 用来保存 SPL。

  • 保存 SPL 的 PEB 是从一个固定的候选 PEB 列表中选取的,具体可参考表 3.20 。 因此可能分布在 NAND 器件的不同位置。 由于 NAND 厂商保证前面几个块在出厂时不是坏块,因此大概率前面几个块会被选作 SPL 存储块。 因此 ArtInChip 默认将前面 1MB 分为 SPL 分区。

  • PEB 中保存的 SPL 格式,不是原始的 SPL 数据。在烧录时,SPL 数据被分切为固定 2KB 大小的数据切片, 按照页(Page)进行保存,并且使用 Page Table 对这些数据切片进行管理。

  • 被选中用于保存 SPL 的 PEB,会被标记为保留块(坏块)。因此在烧录 SPL 之后, NAND 上会出现几个被标记了的坏块,这是正常现象。

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 如果是好块,则作为启动块。写入启动镜像后标记为坏块

SPI NOR 分区配置

具体的分区在项目的 image_cfg.json 中配置,mk_image.py 生成镜像过程中,相关分区信息会被添加到 env.bin, 以 MTD= 格式存储在环境变量中:

MTD=size1@offset1(partition name1),size2@offset2(partition name2),-(last partition)

其中 size 是分区的大小,offset 是分区的开始位置(相对 UDA 的开始位置,单位为字节)。 如果是最后一个分区,可以不设置 size@offset,使用 - 代替,表示剩余的所有空间都分配给该分区。

例如:

MTD=spi0.0:128k(spl),512k(uboot),64k(env),64k(envbak),128k(bootui),128k(dtb),
    5m(kernel),8m(rootfs),-(user)
注:

mtdids 与使用的 spi 接口有关系。当使用 spi0 接口时,为 spi0.0。当使用 spi1 接口时,为 spi1.0

SPL 分区的特别说明

NOR 分区时,BROM 启动过程中,固定从两个地方读取 SPL 程序的备份。 首先尝试读取 SPL 备份 1,如果验证失败,再尝试读取 SPL 备份 2。其中备份 2 是可选的。

4. 普通 NOR 的启动分区
分区 大小/位置 备注
备份 1 128KB(0~128KB) 必须
备份 2 128KB(128KB~256KB) 可选