Image Layout
Flash 布局
RTL8752H 的 Flash 布局 如下,由 Reserved,OEM Header(即 Config File 的存储空间),OTA Bank0,OTA Bank1,FTL,OTA TMP,User Data1 和 User Data2 组成。访问 Flash 的起始地址为 0x00800000。

Flash 布局
内存段 |
起始地址 |
大小(字节) |
功能 |
是否支持 DFU 升级 |
---|---|---|---|---|
OEM Header |
0x00801000 |
0x1000 |
配置信息存储区域,包括蓝牙地址和用户可修改的 Flash 布局等内容 |
否 |
OTA Bank0 |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
OTA Bank0 主要用于存储设备的固件和运行时数据 具体功能请参考 OTA Bank Flash 布局 |
是 |
OTA Bank1 |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
对于支持 Bank 切换的 DFU 方案
|
是 |
FTL |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
该区域空间支持以逻辑地址访问 Flash |
否 |
OTA TMP |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
使用不支持 Bank 切换的 DFU 方式下,作为 OTA 备份区使用 大小必须不小于 OTA Bank0 最大的 image 大小 |
否 |
User Data1 |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
Flash 剩余未划分区域,用户可以自由使用 |
是 |
User Data2 |
可变(由 OEM Header 决定) |
可变(由 OEM Header 决定) |
Flash 剩余未划分区域,用户可以自由使用 |
是 |
OTA Bank 内部的布局和说明如下:

OTA Bank 布局
内存段 |
起始地址 |
大小(字节) |
功能 |
是否支持 DFU 升级 |
---|---|---|---|---|
OTA Header |
由 OEM Header 决定 |
4KB |
存储 OTA Header 的版本信息,Bank 中存在 image 的起始地址和大小 |
是(当支持Bank切换) 否(当不支持Bank切换) |
ROM Patch |
由 OTA Header 决定 |
可变 |
对 ROM 中平台功能的优化和扩展代码 |
是 |
Secure Boot Loader |
由 OTA Header 决定 |
可变 |
启动过程中对代码安全级别检查的代码 |
是 |
BT Stack Patch |
由 OTA Header 决定 |
可变 |
蓝牙 controller 协议栈优化和扩展代码 |
是 |
Upperstack |
由 OTA Header 决定 |
可变 |
实现 HCI 及以上蓝牙协议栈部分代码 |
是 |
APP |
由 OTA Header 决定 |
可变 |
开发方案的运行代码 |
是 |
APP Data1 |
由 OTA Header 决定 |
可变 |
开发方案中使用的数据区 |
是 |
APP Data2 |
由 OTA Header 决定 |
可变 |
开发方案中使用的数据区 |
是 |
APP Data3 |
由 OTA Header 决定 |
可变 |
开发方案中使用的数据区 |
是 |
APP Data4 |
由 OTA Header 决定 |
可变 |
开发方案中使用的数据区 |
是 |
APP Data5 |
由 OTA Header 决定 |
可变 |
开发方案中使用的数据区 |
是 |
APP Config File |
由 OTA Header 决定 |
可变 |
APP Config 信息 |
是 |
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 总大小为 1MB 的示例布局 |
大小(字节) |
起始地址 |
---|---|---|
Reserved |
4K |
0x00800000 |
OEM Header |
4K |
0x00801000 |
OTA Bank0 |
344K |
0x00802000 |
|
4K |
0x00802000 |
|
4K |
0x0080A000 |
|
28K |
0x00803000 |
|
28K |
0x0080B000 |
|
144K |
0x00812000 |
|
132K |
0x00836000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
4K |
0x00857000 |
OTA Bank1 |
344K |
0x00858000 |
|
4K |
0x00858000 |
|
4K |
0x00860000 |
|
28K |
0x00859000 |
|
28K |
0x00861000 |
|
144K |
0x00868000 |
|
132K |
0x0088C000 |
|
0K |
0x008AD000 |
|
0K |
0x008AD000 |
|
0K |
0x008AD000 |
|
0K |
0x008AD000 |
|
0K |
0x008AD000 |
|
4K |
0x008AD000 |
FTL |
16K |
0x008AE000 |
OTA TMP |
0K |
0x008B2000 |
user data1 |
0K |
0x008B2000 |
user data2 |
0K |
0x008B2000 |
备注
Flash 布局需要根据用户实际 image 和 data 的大小进行合理划分。
不支持 Bank 切换方案
flash总大小为 512KB 的示例布局 |
大小 (字节) |
起始地址 |
---|---|---|
Reserved |
4K |
0x00800000 |
OEM Header |
4K |
0x00801000 |
OTA Bank0 |
344K |
0x00802000 |
|
4K |
0x00802000 |
|
4K |
0x0080A000 |
|
28K |
0x00803000 |
|
28K |
0x0080B000 |
|
144K |
0x00812000 |
|
132K |
0x00836000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
0K |
0x00857000 |
|
4K |
0x00857000 |
OTA Bank1(等于0) |
0K |
0x00858000 |
FTL |
16K |
0x00858000 |
OTA TMP |
144K |
0x0085C000 |
user data1 |
0K |
0x00880000 |
user data2 |
0K |
0x00880000 |
备注
此处没有分配 APP data,Flash 布局需要根据用户实际 image 和 data 的大小进行合理划分。
Image 格式
OTA Bank Flash 布局 中所有可支持升级的 image 都是由一个 1024 Bytes 大小的 image header 和不定长的 payload 部分组成。
Image header 会包含 image 类型、大小、版本号、哈希值和签名信息等,具体介绍如下:
内存段 |
大小(字节) |
功能 |
---|---|---|
image_cmac |
16 |
image 的 CMAC 值,用于在开启 secure boot 时进行认证 |
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 时进行认证 |
image_info |
92 |
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,RTL8752H IC type 值为 16。
- secure_version:
表示启动安全检查 image 的版本。
- image_id:
标识不同的 image 的类型枚举如下,其中 SCCD,OCCD 不能 DFU 升级。
typedef enum { IMAGE_FIRST = 0x278D, SCCD = 0x278D, OCCD = 0x278E, FactoryCode = 0x278F, OTA = 0x2790, /**< OTA header */ SecureBoot = 0x2791, RomPatch = 0x2792, AppPatch = 0x2793, AppData1 = 0x2794, AppData2 = 0x2795, AppData3 = 0x2796, AppData4 = 0x2797, AppData5 = 0x2798, AppConfigFile = 0x2799, UpperStack = 0x279a, IMG_BT_STACKPATCH = 0x279b, IMAGE_MAX, IMAGE_USER_DATA2 = 0xFFFD, /**<the image only support unsafe single bank ota*/ IMAGE_USER_DATA = 0xFFFE, /**<the image only support unsafe single bank ota*/ } T_IMG_ID;
参数说明:
- payload_len:
单位是字节,表示 image 的大小,不包括 1024 Bytes 的 image header,image total length = payload_len + 1024。
- 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,防止重复搬运。