2.6. 烧录镜像

Luban-Lite SDK 编译的最终输出结果是一个用于烧录到目标平台的镜像文件。

2.6.1. 镜像烧录

2.6.1.1. 上位机烧录

工具

说明

AiBurn

用于通过 PC 烧录镜像。

串口调试工具

用于通过命令行进入烧录模式、查看烧录、启动状态。

2.6.1.1.1. 打开 AiBurn

进入“烧写镜像”页面

../../_images/open_aiburn1.png

2.6.1.1.2. 板卡进入烧录模式

板卡上电后,进入烧录模式有两种方式:

  • 按住 UBOOT 键不放,再按 RESET 键;

  • 在串口命令行输入 aicupg

进入烧录模式后, AiBurn 会识别板卡,当右下角出现 “ArtInChip 设备已连接”,表示成功进入烧录模式,如图所示。

../../_images/enter_burn1.png

2.6.1.1.3. 烧录镜像

如图所示:

../../_images/select_img1.png
  • 选择编译好的镜像文件,加载镜像时, AiBurn 会识别出镜像的基本信息;

  • 点击开始,进行烧录,烧录时,AiBurn 会显示烧录的进度、速率、用时、结果。

2.6.2. 镜像格式

ArtInChip 的烧录镜像文件由组件(FirmWare Component) 以及对应的组件元信息组成。 数据分布如下图所示。

../../_images/image_format1.png

图 2.48 烧录镜像格式

其中一些需要打包的数据文件,都被当做组件(FWC)进行处理,包括 SPL,os,rodata,data 等数据。

Image Header 的具体格式如下:

struct artinchip_fw_hdr{
    char magic[8];              // 固定为 "AIC.FW"
    char platform[64];          // 该镜像文件适用的芯片平台
    char product[64];           // 该镜像文件适用的产品型号
    char version[64];           // 该镜像的版本
    char media_type[64];        // 该镜像文件可烧录的存储介质
    u32  media_dev_id;          // 该镜像文件可烧录的存储介质 ID
    u8   nand_array_org[64];    /* NAND Array Organization */
    u32  meta_offset;           /* Meta Area start offset */
    u32  meta_size;             /* Meta Area size */
    u32  file_offset;           /* File data Area start offset */
    u32  file_size;             /* File data Area size */
};

FWC Meta 的格式如下:

struct artinchip_fwc_meta {
    char magic[8];      // 固定为 "META"
    char name[64];      // 对应组件的名字
    char partition[64]; // 该组件要烧录的分区名字
    u32  offset;        // 该组件数据在镜像文件中的偏移
    u32  size;          // 该组件数据的大小
    u32  crc32;         // 该组件数据的CRC32校验值
    u32  ram;           // 当组件要下载到平台 RAM 时,要下载的地址
    char attr[64]       // 该组件的属性,字符串表示
};

2.6.3. 制作工具

工具

说明

mk_image.py

用于:
- 制作 AIC 格式的启动镜像,包括签名和加密
- 打包固件组件,生成用于升级的固件镜像文件。
scripts/tools/mk_image.py

2.6.4. 配置文件

使用 mk_image.py 制作烧录镜像时,需要提供 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" },
            "os":  { "size": "2m" },
            "rodata":  { "size": "4m" },
            "data":  { "size": "28m" },
        },
    },
    "image": {
        "info": { // Header information about image
            "platform": "d21x",
            "product": "demo128_nand",
            "version": "1.0.0",
            "media": {
                "type": "spi-nand",
                "device_id": 0,
                "array_organization": [
                    { "page": "2k", "block": "128k", "oob": "64" },
        //            { "page": "4k", "block": "256k", "oob": "128" },
                ],
            }
        },
        "updater": { // Image writer which is downloaded to RAM by USB
            "ddr": {
                "file": "usbupg-ddr-init.aic",
                "attr": ["required", "run"],
                "ram": "0x00103000"
            },
            "bootloader": {
                "file": "bootloader.aic",
                "attr": ["required", "run"],
                "ram": "0x41000000"
            },
        },
        "target": { // Image components which will be burn to device's partitions
            "bootloader": {
                "file": "bootloader.aic",
                "attr": ["mtd", "required"],
                "part": ["spl"]
            },
            "os": {
                "file": "os.aic",
                "attr": ["mtd", "required"],
                "part": ["os"]
            },
            "res": {
                "file": "app.fatfs",
                "attr": ["mtd", "optional"],
                "part": ["rodata"]
            },
            "app": {
                "file": "page_2k_block_128k_oob_64_data.uffs",
                "attr": ["uffs", "optional"],
                "part": ["data"]
            },
        },
    },
    "temporary": { // Pre-proccess to generate image components from raw data
        "aicboot": {
            "usbupg-ddr-init.aic": { // No loader, only PreBootProgram to initialize DDR
                "head_ver": "0x00010001",
                "resource": {
                    "private": "ddr_init.bin",
                    "pbp": "d21x.pbp",
                },
            },
            "bootloader.aic": {
                "head_ver": "0x00010001",
                "loader": {
                    "file": "bootloader.bin",
                    "load address": "0x42000000",
                    "entry point":  "0x42000100",
                },
                "resource": {
                    "private": "ddr_init.bin",
                    "pbp": "d21x.pbp",
                },
            },
            "os.aic": {
                "head_ver": "0x00010001",
                "loader": {
                    "file": "d21x.bin",
                    "load address": "0x40000000",
                    "entry point":  "0x40000100",
                    "run in dram": "false",
                }
            },
        },
    },
}

2.6.4.1. 分区表描述

image_cfg.json 文件的开头首先描述的是当前要烧录的目标存储设备,以及在设备上的分区配置,以 spi-nand 为例:

"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" },
        "os":  { "size": "2m" },
        "rodata":  { "size": "4m" },
        "data":  { "size": "28m" },
    },
},

存储设备类型:

存储设备

说明

"spi-nand"

SPI NAND 设备

"spi-nor"

SPI NOR 设备

存储设备 的名字仅可使用上述列表所指定的名字。

存储设备 的可设置属性有:

存储设备对象的属性名 说明

"size"

值为字符串。
设备的存储大小(Byte),可使用 “K,M,G” 单位,e.g. “2m”

"partitions"

分区表 对象。
包含该存储设备的详细分区列表,每一个子对象为一个 分区

分区 对象的属性有:

分区对象的属性名 说明

"offset"

值为16进制字符串。
表示该 分区 的开始位置离 存储设备 的开始位置的偏移(字节)。
如果 “offset” 不出现,表示当前分区紧接上一个分区。

"size"

值为字符串。
设备的存储大小(Byte),可使用 “K,M,G” 单位,e.g. “2m”。
最后一个分区可以使用 “-” 表示使用剩下所有的空间。

"ubi"

UBI Volume 对象。
当存储设备为 “spi-nand” 时出现,表示当前 MTD 分区是一个 UBI 设备。
该对象描述 UBI 设备中的 Volume 表。每一个子对象为一个 UBI Volume

UBI Volume 对象的属性有:

UBI Volume对象的属性名

说明

"offset"

值为16进制字符串。
表示该 Volume 的开始位置离 MTD 分区的开始位置的偏移(字节)
如果 “offset” 不出现,表示当前 Volume 紧接上一个 Volume。

"size"

值为字符串。
设备的存储大小(Byte),可使用 “K,M,G” 单位,e.g. “2m”
最后一个分区可以使用 “-” 表示使用剩下所有的空间。

2.6.4.2. Image 文件描述

“image” 对象描述要生成的镜像文件的基本信息,以及要打包的数据。包含几个部分:

  • “info”

  • “updater”

  • “target”

"image": {
    "info": {
        ...
    }
    "updater": {
        ...
    }
    "target": {
        ...
    }
}

2.6.4.2.1. Info 数据描述

“info” 对象用于描述该烧录镜像的基本信息,这些信息用于生成 Image Header。以 demo128_nand 为例

"info": { // Header information about image
    "platform": "d21x",
    "product": "demo128_nand",
    "version": "1.0.0",
    "media": {
        "type": "spi-nand",
        "device_id": 0,
        "array_organization": [
            { "page": "2k", "block": "128k", "oob": "64" },
            // { "page": "4k", "block": "256k", "oob": "128" },
        ],
    }
},

info 属性

说明

"platform"

字符串,当前项目所使用的 SoC 的名字

"product"

字符串,产品名字、产品型号

"version"

字符串,按照 “x.y.z” 格式提供的版本号,其中 x,y,z 都是数字

"media"

对象,描述存储设备

media 属性

说明

"type"

字符串

"device_id"

整数,要烧录的存储设备在 U-Boot 中的索引。

"array_organization"

对象,当存储设备为 “spi-nand” 时使用,描述存储单元的排列结构

array_organization 属性

说明

"page"

当前 SPI NAND 的 Page 大小,取值 “2K”, “4K”,

"block"

当前 SPI NAND 的 Block 大小, 取值 “128K”, “256K”

2.6.4.2.2. Updater 数据描述

Updater 是指进行 USB 刷机或者进行 SD 卡刷机时需要运行的刷机程序,该程序通常由 SPL/Bootloader 实现, 可能与正常启动时所运行的 SPL/Bootloader 相同,也可能不同,因此需要单独列出。

“updater” 对象描述在刷机过程中需要使用到的组件数据,其包含多个子对象,每个子对象即为一个 组件 。 其中下列的 组件 是已知且必要的。

组件名称

说明

"spl"

第一级引导程序

"bootloader"

第二级引导程序,同时也是刷机程序

上述的组件名字并非固定,可根据项目的需要修改、增加或者删除。

Updater 中的 组件 对象都有以下的配置字段:

Updater 组件属性

说明

"file"

指定该组件的数据来源文件

"ram"

USB 刷机时,指定该文件下载的内存地址

"attr"

该数据对象的属性,可选的内容有:
- “required” : 该数据是必需的,如果指定文件不存在,则生成镜像文件出错。
- “run” : 该数据是可执行文件,USB 升级时,该数据下载完成之后会被执行。

重要

“updater” 中 组件 对象的顺序很重要。

在 USB 升级的过程中,组件数据传输和执行的顺序即为 “updater” 中组件数据出现的顺序, 因此如果组件数据之间有顺序依赖关系,需要按照正确的顺序排布。

2.6.4.2.3. Target 数据描述

“target” 描述要烧录到设备存储介质上的 组件 。与 “updater” 中的组件一样,”target” 中出现的组件根据实际需要进行添加,组件的名字也可自行定义。

“target” 中的组件,都有下面的配置字段:

Target 组件属性

说明

"file"

指定该组件的数据来源文件

"part"

指定该组件被烧录的分区
分区名字通过字符串数组的形式提供

"attr"

该数据对象的属性,可选的内容有:
- “required” : 该组件数据是必需的,如果指定文件不存在,则生成镜像文件出错。
- “optional” : 该组件数据不是必需的,如果指定文件不存在,则在生成镜像文件时忽略该数据对象。
- “burn” : 该组件数据是需要烧录到指定分区当中。
- “mtd” : 表示该组件要烧录的设备是 MTD 设备。
- “ubi” : 表示该组件要烧录的设备是 UBI 设备。
- “block” : 表示该组件要烧录的设备是块设备。

重要

“target” 中组件对象的顺序

在 USB 升级的过程中,组件数据传输和烧录的顺序即为 “target” 中组件数据出现的顺序。

2.6.4.3. 中间文件描述

“temporary” 描述的是镜像文件生成过程中需要生成的中间文件。通过描述数据对象的方式, 描述不同类型的中间文件的生成过程,可用于对组件的签名、加密、再次打包等处理。

当前支持下列数据处理:

  • “aicboot”

    描述 AIC 启动镜像的生成

AIC 启动镜像

AIC 启动镜像是 BROM 解析和执行的启动程序文件。 当需要在打包过程中生成一个中间的 AIC 启动镜像文件时,需要在 “aicboot” 对象中添加一个子对象, 其对象名字即为生成的文件名字,可配置的内容如下面的示例所示。所列的属性中,只有 “loader” 是必需的, 其他的可根据项目需要进行删减。

"aicboot": {
    "usbupg-ddr-init.aic": { // No loader, only PreBootProgram to initialize DDR
        "head_ver": "0x00010001",
        "resource": {
            "private": "ddr_init.bin",
            "pbp": "d21x.pbp",
        },
    },
    "bootloader.aic": {
        "head_ver": "0x00010001",
        "loader": {
            "file": "bootloader.bin",
            "load address": "0x42000000",
                "entry point":  "0x42000100",
        },
        "resource": {
            "private": "ddr_init.bin",
            "pbp": "d21x.pbp",
        },
    },
    "os.aic": {
        "head_ver": "0x00010001",
        "loader": {
            "file": "d21x.bin",
            "load address": "0x40000000",
            "entry point":  "0x40000100",
            "run in dram": "false",
        }
    },
}

2.6.5. SD 卡烧录

芯片支持从 SD 卡的 FAT32 文件系统启动。

2.6.5.1. 要求与步骤

对芯片与板子的要求:
  1. 板子 SD 卡接口,并且使用 SDMC1

  2. 芯片没有烧录 跳过 SD 卡的 eFuse

对 SD 卡的要求:
  1. SD 卡要求只有一个分区

  2. SD 卡格式化为 FAT32 文件系统,注意不是 exFAT、或者 FAT16

  3. SD 卡最好为专用卡,里面不要放置太多其他文件

执行步骤:
  1. 拷贝在编译输出目录(images) 下的两个文件到 SD 卡 FAT32 文件系统的 根目录

    • bootcfg.txt (注意 NAND 输出的名字有些不同,例如 bootcfg.txt(page_2k_block_128k))

    • xxx.img(例如 d13x_per1-nor_v1.0.0.img)

  2. 确保 bootcfg 文件的名字为 bootcfg.txt

    如果生成的名字为 bootcfg.txt(page_2k_block_128k),则需要改为 bootcfg.txt

  3. 将 SD 卡插入板子,重新上电,即可从 SD 卡启动到 Tiny_SPL,并执行烧录

  4. 烧录完成时,需要拔出 SD 卡,然后重新上电启动

注意

烧录完成平台并不会主动重启,以防重复进入 SD 卡烧录模式。

2.6.5.1.1. 编译配置

SDK 提供的配置,默认关闭该功能。这里进行配置使能以及注意项的说明。

2.6.5.1.1.1. SPI NAND/NOR 方案

使能 SDFAT32 烧录功能,只需要在 BootLoader 的 menuconfig 中勾选配置:

Bootloader options
    Upgrading
        [*] Upgrading by SD Card
            (1)   SDMC controller id for SD Card        # 对应板卡的 SDMC 控制器

注意

开启 SD 卡烧录功能后,编译完成生成的 bootloader.aic 文件大小不能超过 126K,若超过则可以关闭以下配置来减小 CODE SIZE。

  1. AIC_BOOTLOADER_CMD_SPI_NAND

  2. AIC_BOOTLOADER_CMD_MTD

  3. AIC_BOOTLOADER_CMD_MEM

2.6.6. U 盘升级

芯片支持通过 U 盘的 FAT32 文件系统进行升级。

2.6.6.1. 要求与步骤

对芯片与板子的要求:
  1. 板子使用 USB 接口。

  2. 芯片烧录过镜像,且镜像支持 U 盘升级

对 U盘 卡的要求:
  1. U 盘要求只有一个分区

  2. U 盘格式化为 FAT32 文件系统,注意不是 exFAT、或者 FAT16

  3. U 盘最好为专用 U 盘,里面不要放置太多其他文件

执行步骤:
  1. 拷贝在编译输出目录(images) 下的两个文件到 U 盘 FAT32 文件系统的 根目录

    • bootcfg.txt (注意 NAND 输出的名字有些不同,例如 bootcfg.txt(page_2k_block_128k) )

    • xxx.img(例如 d13x_per1-nor_v1.0.0.img)

  2. 确保 bootcfg 文件的名字为 bootcfg.txt

    如果生成的名字为 bootcfg.txt(page_2k_block_128k),则需要改为 bootcfg.txt

  3. 将 U 盘插入板子,重新上电,启动过程中则会自动检测 U 盘是否插入,检测到后进入烧录模式进行升级

  4. 烧录完成时,需要拔出 U 盘,然后重新上电启动

注意

烧录完成平台并不会主动重启,以防重复进入 U 盘烧录模式。

2.6.6.1.1. 编译配置

SDK 提供的配置,默认关闭该功能。这里进行配置使能以及注意项的说明。

2.6.6.1.1.1. SPI NAND/NOR 方案

使能 SDFAT32 烧录功能,只需要在 menuconfig 中勾选配置项 AICUPG_UDISK_ENABLE 即可:

Bootloader options  --->
    aicupg setting  --->
        [*] aicupg udisk upgrade on

同时设置:

  • AICUPG_USB_CONTROLLER_MAX_NUM=1

可用的最大 USB HOST 控制器数量,根据实际芯片平台进行设置。

注意

开启 U 盘烧录功能后,编译完成生成的 bootloader.aic 文件大小不能超过 126K,若超过则可以关闭以下配置来减小 CODE SIZE。

  1. AIC_BOOTLOADER_CMD_SPI_NAND

  2. AIC_BOOTLOADER_CMD_MTD

  3. AIC_BOOTLOADER_CMD_MEM

2.6.6.2. 注意事项

在打包镜像前,需要确保 target/<IC>/<Board>/pack 目录下的 image_cfg.json 文件中 device_id 与存储介质所使用的控制器 id 所对应。

例如 eMMC 存储介质使用的控制器为 SDMC0,则应该将 device_id 的值设为0, 如果 eMMC 存储介质所使用的控制器为 SDMC1,则应该将 device_id 设为1。