1
0
0

Copy/Clear Table

2026-09-14

问题发现:

在EAS OS移植时,当把变量添加到某个App的内存保护Section后,这些被保护的变量在MCU上电后没有初始化了(data数据没有值,bss数据不为零)。

原因查明:

该内存保护Section没有在ld链接文件中放置到Copy Table或Clear Table

Copy Table

一张由链接器生成的“初始化搬运任务清单”,启动代码根据这张表,把位于 Flash 中的初始化数据复制到 RAM 的运行地址。

处理数据为.data数据

  • 程序和初始数据需要在上电后保存在Flash 中;

  • 运行时变量需要位于 RAM 中;

  • 因此同一个 section 往往有两个地址:

    • Load Address,加载地址:程序镜像在 Flash 中的地址;

    • Run Address,运行地址:程序运行时在 RAM 中的地址。

copy table 就是记录这两个地址以及复制长度的数据结构

在ld文件中data数据的链接方式为:

其中

} > CPU0_DMI_DSPR AT > int_rom

可以解释为

} > 运行地址区域 AT > 加载地址区域

运行地址 VMA:CPU0_DMI_DSPR

加载地址 LMA:int_rom

AT > int_rom 表示 .CPU0_PRIVATE_DATA 的初始化镜像放在 int_rom 中,但程序运行时这段数据位于 CPU0_DMI_DSPR;启动阶段通常需要把它从 int_rom 复制到 CPU0_DMI_DSPR。

所以在对应ld文件的Copy Section中

source      = LOADADDR(.CPU0_PRIVATE_DATA)   // Flash 中的加载地址
destination = ADDR(.CPU0_PRIVATE_DATA)       // RAM 中的运行地址
length      = SIZEOF(.CPU0_PRIVATE_DATA)     // 该section大小

在startup中 对应的copy代码为

Clear Table

与copy table类似,只不过只需要赋值为零即可

对于bss类型,只需要链接到DSPR RAM区域即可

destination = ADDR(.CPU0_PRIVATE_BSS)        // RAM 中的运行地址
length      = SIZEOF(.CPU0_PRIVATE_BSS)     // 该section大小

在startup中 对应的clear代码为

Support

If this article helped you, feel free to share it or give support!