我们有一个带有自定义部分的链接脚本,出于某些IEC一致性测试的原因而添加了该脚本。但是,自从添加此部分以来,通过objcopy -O binary input output
创建的二进制大小已经从〜150kbytes膨胀到了〜512bbytes。
我已将其追溯到缺少(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)
,则二进制文件大小约为512Mb。
我正在寻找此二进制文件变得如此大的原因。 (NOLOAD)
(或没有它)对于objcopy
生成二进制文件意味着什么?
第二个问题,在本节末尾我们说} > CUSTOM_SECTION AT > ram
,如果没有此指令,我们可以做什么?可以将其替换为} > ram
吗? (这可以从CUSTOM_SECTION
部分中删除MEMORY
吗?
我发现生成的map
文件中没有差异
答案 0 :(得分:1)
当objcopy创建一个二进制文件时,它基本上与OS ELF加载器执行相同的工作:它将可加载的ELF文件节写入一个表示运行时内存的文件中。
二进制文件将包含代码和数据的每个字节,从基地址到最高字节。如果内存映像稀疏(存在“无”区域),则二进制文件也将包含大的无区域。只能在哑的二进制文件中将其表示为零。
您的elf文件具有从地址0x00000000(ROM的底部)到0x20000fff(CUSTOM_SECTION的顶部)的数据,其范围刚刚超过500MB,因此可以认为二进制文件必须具有那么多字节容纳一切。通过使该部分不可装载,您说的是在运行时不需要数据,因此不需要在二进制映像中。调试信息,注释和其他非程序ELF数据通常是这种情况。
好消息是:a)许多文件系统仅将磁盘空间用于文件的非零部分,因此它使用的磁盘数量不如显示的少(“稀疏文件”),并且b)二进制文件将易于压缩。