3. 问题分析
BIN 文件是最纯粹的二进制机器代码, 或者说是"顺序格式"。按照 assembly code 顺序翻译
成 binary machine code,内部没有地址标记。 Bin 是直接的内存映象表示,二进制文件大小即为
文件所包含的数据的实际大小。 BIN 文件就是直接的二进制文件,一般用编程器烧写时从 00 开
始,而如果下载运行,则下载到编译时的地址即可。
STM32CubeIDE 依赖链接脚本文件生成目标 ELF 文件,生成 ELF 目标文件之后,
STM32CubeIDE 会依赖 GNU Objcopy 工具把 ELF 文件转为 BIN 文件。这个过程简单一点来
说,就是提取 ELF 文件中的代码段以及可加载数据段按照地址信息顺序生成 BIN 文件。
所以,如果 BIN 文件很大,那说明可加载的代码段和数据段很大。在我们的测试项目中,
代码段是固定的; 现在 BIN 文件很大,说明是数据段过大导致的。
通过查看编译产生的 list 文件,我们可以清楚的看到每个段的大小。
从上图的 Sections Map 中,每个 Section 会有几个关键的参数和类型。 Size 为每个
Section 的大小, VMA 是指 Section 在程序运行时候的地址, LMA 是指 Section 在 Flash 中的加
载地址。 通常情况下从 Flash 执行的程序, Code 段 VMA 和 LMA 是一样的。 Data 段的 VMA 会
放在 RAM 中, LMA 会放在 Flash 中,所以 Data 段的 VMA 和 LMA 通常不一样。 在每个段的类
型中,还有一个关键的属性是 LOAD,如果定义了 LOAD 属性,那说明这个段是需要写入 Flash
中的。
GNU Objcopy 工具生成 BIN 文件的过程,实际上就是把 ELF 文件中各个定义了 LOAD 属
性的 SECTION 按照 LMA 的先后顺序提取出来,写入 BIN 文件中。 SECTION 的地址如果不是连
续的, 则会填充 DUMMY 数据。所以 BIN 文件的大小为最大 LMA 加上对应的 SECTION 的
Size。
结合上图, 该工程最终生成的 BIN 文件大小为 0x30000000+0x4000 -0x8000000 =
671105024 和图 4 的文件属性显示的大小是一致的。
|