Image Layout
Flash 布局
RTL87x2G 的 Flash 布局 如下,由 Reserved,OEM Header(即 Config File 的存储空间),Bank0 Boot Patch,Bank1 Boot Patch,OTA Bank0,OTA Bank1,Secure APP,OTA TMP,FTL 和 APP Defined Section 组成。访问 Flash 的起始地址为 0x04000000。

Flash 布局
内存段 |
起始地址 |
大小(字节) |
功能 |
是否支持 DFU 升级 |
---|---|---|---|---|
OEM Header |
0x04010000 |
0x1000 |
配置信息存储区域,包括蓝牙地址和用户可修改的 Flash 布局等内容 |
否 |
Bank0 Boot Patch |
可变(由 eFuse 决定) |
可变(由 eFuse 决定) |
Flash boot loader,Bank0 Boot Patch 和 Bank1 Boot Patch 作用相同,互为备份区 |
是 |
Bank1 Boot Patch |
可变(由 eFuse 决定) |
可变(由 eFuse 决定) |
Flash boot loader |
是 |
OTA Bank0 |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
OTA Bank0 主要用于存储设备的固件和运行时数据。 具体的功能参考 OTA Bank Flash 布局 |
是 |
OTA Bank1 |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
对于支持 Bank 切换的 DFU 方案,如果 OTA Bank0 是运行区,那么 OTA Bank1 将作为备份区。 反之,如果 OTA Bank1 是运行区,OTA Bank0 将作为备份区 |
是 |
Bank0 Secure APP |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
当开启 TrustZone 时,Secure APP(安全应用程序)可以在 TrustZone 环境中运行,确保敏感数据和操作得到安全保护。 在这种情况下,Bank0 Secure APP 和 Bank1 Secure APP 作用相同,互为备份区 |
是 |
Bank1 Secure APP |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
和 Bank0 Secure APP 作用相同,互为备份区 |
是 |
OTA TMP |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
使用不支持 Bank 切换的 DFU 方案下,作为 OTA 备份区使用,大小必须不小于 OTA Bank0 最大的 image 大小 |
否 |
FTL |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
该区域空间支持以逻辑地址访问 Flash |
否 |
APP Defined Section |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
Flash 剩余未划分区域,用户可以自由使用,但默认不支持 DFU 升级 |
否 |
OTA Bank 内部的布局和说明如下:

OTA Bank 布局
内存段 |
起始地址 |
大小(字节) |
功能 |
是否支持 DFU 升级 |
---|---|---|---|---|
OTA Header |
由 OEM Header 定义决定 |
4KB |
存储 OTA Header 的版本信息,Bank 中存在 image 的起始地址和大小 |
是 —— 支持 Bank 切换 否 —— 不支持 Bank 切换 |
System Patch |
由 OTA Header 定义决定 |
Variable |
对 non-secure ROM 中系统的优化和扩展代码 |
是 |
BT Stack Patch |
由 OTA Header 定义决定 |
Variable |
蓝牙 controller 协议栈优化和扩展代码 |
是 |
BT Host |
由 OTA Header 定义决定 |
Variable |
实现 HCI 及以上蓝牙协议栈部分代码 |
是 |
APP |
由 OTA Header 定义决定 |
Variable |
开发方案的运行代码 |
是 |
APP Config File |
由 OTA Header 定义决定 |
Variable |
APP Config 信息 |
是 |
APP Data1 |
由 OTA Header 定义决定 |
Variable |
开发方案中使用的数据区 |
是 |
APP Data2 |
由 OTA Header 定义决定 |
Variable |
开发方案中使用的数据区 |
是 |
APP Data3 |
由 OTA Header 定义决定 |
Variable |
开发方案中使用的数据区 |
是 |
APP Data4 |
由 OTA Header 定义决定 |
Variable |
开发方案中使用的数据区 |
是 |
APP Data5 |
由 OTA Header 定义决定 |
Variable |
开发方案中使用的数据区 |
是 |
APP Data6 |
由 OTA Header 定义决定 |
Variable |
开发方案中使用的数据区 |
是 |
Flash 布局调整
Flash 布局设置分为以下两级:
High Level Flash map —— 由 OEM Header 决定
OTA Bank map —— 由 OTA Header 文件决定
用户可通过 MP Tool 中 Config Set 选项加载自定义的 Flash 布局文件并生成 Config File。

通过 MP Tool 生成 Config File
为方便用户使用,Realtek 提供 Flash Map Generate Tool 用于生成 Flash 布局文件,说明如下:
flash map.ini
文件 —— 导入到 MP Tool,用于生成 Config File 和 OTA header。flash_map.h
文件 —— 需要拷贝到 APP 的工程目录下,编译出正确可运行的 APP image。

Flash Map Generate Tool 配置 Flash Map
Flash 布局调整原则
如果选择 支持 Bank 切换 的 DFU 方案,需保证 OTA Bank0 的大小等于 OTA Bank1 的大小,并且将 OTA TMP 区域的大小设置为 0。
如果选择 不支持 Bank 切换 的 DFU 方案,将 OTA Bank1 的大小设置为 0,OTA TMP 区域的大小不小于 OTA Bank0 中最大的 image 的大小。
为了将所有的 code 区域都上锁,以防止非预期的 flash 写入和擦除操作,尽可能地将 OTA Bank1 结束地址相对于 flash 起始地址的偏移对齐到实际所选用的 flash 所支持的某个保护级别对应的范围,详细请参考: 软件块保护。
Flash 布局示例
基于 Flash 布局调整 的规则,本节提供 支持 Bank 切换方案 和 不支持 Bank 切换方案 下的 Flash 布局示例。
支持 Bank 切换方案
Flash 总大小为 2MB 的示例布局 |
大小(字节) |
起始地址 |
---|---|---|
Reserved |
4K |
0x04000000 |
OEM Header |
4K |
0x04001000 |
Bank0 Boot Patch |
32K |
0x04002000 |
Bank1 Boot Patch |
32K |
0x0400A000 |
OTA Bank0 |
596K |
0x04012000 |
|
4K |
0x04012000 |
|
32K |
0x04013000 |
|
60K |
0x0401B000 |
|
212K |
0x0402A000 |
|
284K |
0x0405F000 |
|
4K |
0x040A6000 |
|
0K |
0x040A7000 |
|
0K |
0x040A7000 |
|
0K |
0x040A7000 |
|
0K |
0x040A7000 |
|
0K |
0x040A7000 |
|
0K |
0x040A7000 |
OTA Bank1 |
596K |
0x040A7000 |
|
4K |
0x040A7000 |
|
32K |
0x040A8000 |
|
60K |
0x040B0000 |
|
212K |
0x040BF000 |
|
284K |
0x040F4000 |
|
4K |
0x0413B000 |
|
0K |
0x0413C000 |
|
0K |
0x0413C000 |
|
0K |
0x0413C000 |
|
0K |
0x0413C000 |
|
0K |
0x0413C000 |
|
0K |
0x0413C000 |
Bank0 Secure APP code |
0K |
0x0413C000 |
Bank0 Secure APP Data |
0K |
0x0413C000 |
Bank1 Secure APP code |
0K |
0x0413C000 |
Bank1 Secure APP Data |
0K |
0x0413C000 |
OTA Temp |
32K |
0x0413C000 |
FTL |
16K |
0x04148000 |
APP Defined Section |
736K |
0x040FF000 |
备注
Flash 布局需要根据用户实际 image 和 data 的大小进行合理划分。
不支持 Bank 切换方案
Flash 总大小为 1MB 的示例布局 |
大小(字节) |
起始地址 |
---|---|---|
Reserved |
4K |
0x04000000 |
OEM Header |
4K |
0x04001000 |
Bank0 Boot Patch |
32K |
0x04002000 |
Bank1 Boot Patch |
32K |
0x0400A000 |
OTA Bank0 |
612K |
0x04012000 |
|
4K |
0x04012000 |
|
32K |
0x04013000 |
|
60K |
0x0401B000 |
|
212K |
0x0402A000 |
|
304K |
0x0405F000 |
|
4K |
0x040AC000 |
|
0K |
0x040AD000 |
|
0K |
0x040AD000 |
|
0K |
0x040AD000 |
|
0K |
0x040AD000 |
|
0K |
0x040AD000 |
|
0K |
0x040AD000 |
OTA Bank1(等于0) |
0K |
0x040AD000 |
Bank0 Secure APP code |
0K |
0x040AD000 |
Bank0 Secure APP Data |
0K |
0x040AD000 |
Bank1 Secure APP code |
0K |
0x040AD000 |
Bank1 Secure APP Data |
0K |
0x040AD000 |
OTA Temp |
312K |
0x040AD000 |
FTL |
16K |
0x040FB000 |
APP Defined Section |
4K |
0x040FF000 |
备注
此处没有分配 APP data,Flash 布局需要根据用户实际 image 和 data 的大小进行合理划分。
Image 格式
OTA Bank Flash 布局 中所有可支持升级的 image 都是由一个 1280 Bytes 大小的 image header 和不定长的 payload 部分组成。
Image header 会包含 image 类型、大小、版本号、哈希值和签名信息等,具体介绍如下:
字段 |
大小(字节) |
功能 |
---|---|---|
image_signature |
384 |
image 的签名,用于在开启 secure boot 时进行认证 |
image_hash |
32 |
image 的哈希校验,用于 image 完整性校验 |
image_control_header |
12 |
image 的控制信息,详细请参考 image_control_header 格式 |
uuid |
16 |
image 的 UUID 值 |
exe_base |
4 |
image 的执行地址 |
load_src |
4 |
加载到 RAM 的代码起始地址 |
load_len |
4 |
加载到 RAM 的代码大小 |
image_base |
4 |
image 的 flash 地址 |
dev_id |
2 |
Not used |
flash_layout_size_4k |
2 |
flash layout 大小(单位: 4KB) |
magic_pattern |
4 |
image 的 pattern 信息 |
dec_key |
16 |
Not used |
load_dst |
4 |
加载到 flash 的代码起始地址 |
ex_info |
24 |
image 的 heap 和 ram 信息 |
git_ver |
16 |
image 的版本信息 |
RSA Public Key |
388 |
用于在开启 secure boot 时进行认证 |
flash_sec_cfg |
20 |
flash sec 配置信息 |
image_info |
344 |
OTA Header 的 image_info 为 OTA Bank 内各 image 的起始地址和 size,其它 image 的 image_info 为 reserved |
Image Header 中 image_control_header 格式如下:
typedef struct _IMG_CTRL_HEADER_FORMAT
{
uint16_t crc16;
uint8_t ic_type;
uint8_t secure_version;
union
{
uint16_t value;
struct
{
uint16_t xip: 1; // payload is executed on flash
uint16_t enc: 1; // all the payload is encrypted
uint16_t load_when_boot: 1; // load image when boot
uint16_t enc_load: 1; // encrypt load part or not
uint16_t enc_key_select: 3; // referenced to ENC_KEY_SELECT
uint16_t not_ready: 1; //for copy image in ota
uint16_t not_obsolete: 1; //for copy image in ota
uint16_t integrity_check_en_in_boot: 1; // enable image integrity check in boot flow
uint16_t compressed_not_ready: 1;
uint16_t compressed_not_obsolete: 1;
uint16_t rsvd: 1;
uint16_t image_type: 3; /*for app 000b: normal image, 001b:compressed image, other for more types
for patch in temp bank consist of 001b: patch+fsbl, 010b: patch+app, 011b: patch+fsbl+app*/
};
} ctrl_flag;
uint16_t image_id;
uint32_t payload_len;
} T_IMG_CTRL_HEADER_FORMAT;
参数说明:
- ic_type:
表示 IC type,RTL87x2G IC type 值为 15。
- secure_version:
表示启动安全检查 image 的版本。
- image_id:
标识不同的 image 的类型枚举如下,其中 SCCD,OCCD 不能 DFU 升级。
typedef enum
{
IMG_SCCD = 0x379D,
IMG_OCCD = 0x379E,
IMG_BOOTPATCH = 0x379F, /*!< KM4 boot patch */
IMG_DFU_FIRST = IMG_BOOTPATCH,
IMG_OTA = 0x37A0, /*!< OTA header */
IMG_SECUREMCUAPP = 0x37A2, /*!< KM4 secure app */
IMG_SECUREMCUAPPDATA = 0x37A3, /*!< KM4 secure app data */
IMG_BT_STACKPATCH = 0x37A6, /*!< BT stack patch */
IMG_BANK_FIRST = IMG_BT_STACKPATCH,
IMG_MCUPATCH = 0x37A7, /*!< KM4 non-secure rom patch */
IMG_UPPERSTACK = 0x37A8, /*!< KM4 non-secure Upperstack */
IMG_MCUAPP = 0x37A9, /*!< KM4 non-secure app */
IMG_MCUCFGDATA = 0x37AA, /*!< KM4 MCUConfigData */
IMG_MCUAPPDATA1 = 0x37AE,
IMG_MCUAPPDATA2 = 0x37AF,
IMG_MCUAPPDATA3 = 0x37B0,
IMG_MCUAPPDATA4 = 0x37B1,
IMG_MCUAPPDATA5 = 0x37B2,
IMG_MCUAPPDATA6 = 0x37B3,
IMG_ZIGBEESTACK = 0x37B4, /*!< KM4 Zigbee stack */
IMG_MAX = 0x37B5,
IMG_DFU_MAX = IMG_MAX,
IMG_RO_DATA1 = 0x3A81,
IMG_RO_DATA2 = 0x3A82,
IMG_RO_DATA3 = 0x3A83,
IMG_RO_DATA4 = 0x3A84,
IMG_RO_DATA5 = 0x3A85,
IMG_RO_DATA6 = 0x3A86,
IMG_USER_DATA8 = 0xFFF7, /*!< the image data only supports unsafe single bank ota */
IMG_USER_DATA_FIRST = IMG_USER_DATA8,
IMG_USER_DATA7 = 0xFFF8, /*!< the image data only supports unsafe single bank ota */
IMG_USER_DATA6 = 0xFFF9, /*!< the image data only supports unsafe single bank ota */
IMG_USER_DATA5 = 0xFFFA, /*!< the image data only supports unsafe single bank ota */
IMG_USER_DATA4 = 0xFFFB, /*!< the image data only supports unsafe single bank ota */
IMG_USER_DATA3 = 0xFFFC, /*!< the image data only supports unsafe single bank ota */
IMG_USER_DATA2 = 0xFFFD, /*!< the image data only supports unsafe single bank ota */
IMG_USER_DATA1 = 0xFFFE, /*!< the image data only supports unsafe single bank ota */
IMG_USER_DATA_MAX = 0xFFFF, /*!< the image data only supports unsafe single bank ota */
} IMG_ID;
参数说明:
- payload_len:
单位是字节,表示 image 的大小,不包括 1280 Bytes 的 image header,image total length = payload_len + 1280。
- crc16:
表示对 image 的 crc16 校验值,image 默认使用 sha256 校验,校验值存在 image_hash 中,crc16 可忽略。
- ctrl_flag:
和 DFU 相关的位域只有 not_ready 和 not_obsolete 。
not_ready: 标识 image 是否为有效。默认发布、编译或者通过工具生成的文件的 image header 中 not_ready 字段均为 0。
通过蓝牙传输将 image 写入到备份区,中间可能存在断电的风险。所以在写入备份区前,需要将 not_ready 修改为 1 再写入 Flash。
只有当 image 传输完成,并且 image 完整性校验成功后,修改备份区 image 中的 not_ready 为 0,标识备份区 image 有效。
系统重启后,由 BootLoader 完成备份 image 的激活流程。
not_obsolete: 标识 image 是否废弃,默认编译的 image 中 not_obsolete 为 1。
当支持 Bank 切换时,not_obsolete 在 DFU 过程中无效。
当不支持 Bank 切换时,DFU 升级完成后,启动代码判断 not_ready 为 0 且 not_obsolete 为 1,此时将 image 从 OTA TMP 区搬运到 OTA Bank0 内的对应 image 的运行区域,搬运成功后,将 OTA TMP 区 image 中 not_obsolete 写为 0,防止重复搬运。