1

我们有一个带有自定义部分的链接器脚本,出于某些 IEC 合规性测试原因而添加了该部分。然而,自从添加这个部分之后,通过创建的二进制大小objcopy -O binary input output已经从 ~150kbytes 激增到 ~512Mbytes。

我已将其追溯到缺少该(NOLOAD)属性的部分。而且我也可以解释为什么二进制文件是 512Mbytes。

我们的记忆如下:

MEMORY
{
    rom    (rx)  : ORIGIN = 0x00000000, LENGTH = 0x00040000
    ram    (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00007580

    CUSTOM_SECTION (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00001000
}

最初定义的部分是:

    CUSTOM_LOCATION:
    {
        CUSTOM_BEGIN = .;
        KEEP(*(CUSTOM_LOCATION));
        CUSTOM_END = .;

    } > CUSTOM_SECTION AT > ram

如果CUSTOM_LOCATION:替换CUSTOM_LOCATION (NOLOAD):为生成的二进制文件是正常的。没有(NOLOAD)二进制大小是~512Mbytes。

我正在寻找这个二进制文件变得如此之大的原因。生成二进制文件(NOLOAD)(或不存在)意味着什么?objcopy

第二个问题,在本节的最后我们说} > CUSTOM_SECTION AT > ram我们可以不用这个指令吗?可以直接替换} > ram吗?(这可以CUSTOM_SECTIONMEMORY零件中删除吗?

我在生成的map文件中没有看到任何差异

4

1 回答 1

1

当 objcopy 创建一个二进制文件时,它基本上与 OS ELF 加载器执行相同的工作:它将可加载的 ELF 文件部分写入一个表示运行时内存的文件中。

二进制文件将包含代码和数据的每个字节,从基地址到最高字节。如果内存映像是稀疏的(有“无”的区域),那么二进制文件也将包含大面积的无。这只能在哑二进制文件中表示为零。

您的 elf 文件包含从地址 0x00000000(ROM 的基址)到 0x20000fff(CUSTOM_SECTION 的顶部)的数据,其范围刚刚超过 500MB,因此二进制文件必须有那么多字节来保存它是有道理的全部。通过使该部分不可加载,您是在说运行时不需要数据,因此不需要在二进制映像中。这通常是调试信息、注释和其他非程序 ELF 数据的情况。

好消息是 a) 许多文件系统只会将磁盘空间用于文件的非零部分,因此它不会像看起来那样使用磁盘空间(“稀疏文件”),并且 b)二进制将很容易压缩。

于 2019-03-13T17:23:59.413 回答