Gcc 从.elf到.bin的转换增加了文件大小

Gcc 从.elf到.bin的转换增加了文件大小,gcc,arm,elf,objcopy,Gcc,Arm,Elf,Objcopy,当我们将从arm gcc工具链生成的.elf文件转换为.bin文件时,它的大小从40kB增加到1.1Gb 对于转换,我们使用: /arm none eabi objcopy-O binary test.elf test.bin 这可能是因为非连续内存映射和内存区域之间的间隙正被零填充 objcopy中可以使用哪些选项?或者是否有其他转换方法? 以下是elf信息: 标签CPU名称:“Cortex-M7”标签CPU拱门:v7E-M Tag_CPU_arch_配置文件:微控制器Tag_THUMB_I

当我们将从arm gcc工具链生成的.elf文件转换为.bin文件时,它的大小从40kB增加到1.1Gb

对于转换,我们使用:
/arm none eabi objcopy-O binary test.elf test.bin

这可能是因为非连续内存映射和内存区域之间的间隙正被零填充

objcopy中可以使用哪些选项?或者是否有其他转换方法?

以下是elf信息:

  • 标签CPU名称:“Cortex-M7”标签CPU拱门:v7E-M
    Tag_CPU_arch_配置文件:微控制器Tag_THUMB_ISA_使用:THUMB-2
    用于ARMv8的标签FP-arch:FPv5/FP-D16标签ABI-PC:4
    Tag_ABI_FP_非规范性:需要Tag_ABI_FP_异常:需要
    标签ABI FP编号型号:IEEE 754所需标签ABI align:8字节
    标记ABI枚举大小:小标记ABI VFP参数:VFP寄存器
    标记ABI优化目标:积极调试
    标记\u CPU\u未对齐\u访问:v6
ELF文件中包含的节列表为-共有25个节头,从偏移量0x3e982c开始:

节头:
[Nr]姓名
类型Addr Off Size ES Lk Inf Al
旗帜
[ 0] 
NULL 00000000000000000000 0
[00000000]: 
[1]。闪存配置
程序位60000000200000 0002000004
[00000002]:ALLOC
[2].ivt
程序位60001000 021000 00003000 0 4
[00000002]:ALLOC
[3]中断
程序位60002000000400004
[00000002]:ALLOC
[4]文本
程序位6000240002240031200800 0 16
[00000006]:ALLOC,EXEC
[5]手臂
ARM_EXIDX 60314408 334408 000008 00 4 0 4
[00000082]:ALLOC,链接顺序
[6].初始化数组
初始化数组60314410 334410 000004 04 0 4
[00000003]:写入,分配
[7]。fini_数组
FINI_阵列60314414 334414 000004 04 0 4
[00000003]:写入,分配
[8]。中断内存
程序位2020000038000000000001
[00000001]:写入
[9]。数据
程序位20200000340000014BD0 00 8
[0000000 7]:写入、分配、执行
[10] .ncache.init
程序位20214bd0 354bd0 011520 00 4
[00000003]:写入,分配
[11] 恩卡奇先生
NOBITS 20226100 366100 0021d8 00 64
[00000003]:写入,分配
[12] .bss
NOBITS 20229000 369000 077ce8 00 4096
[00000003]:写入,分配
[13] .NVM_表
PROGBITS 2000001000000000C 00 0 4
[00000003]:写入,分配
[14] .堆
NOBITS 200000C 01000c 00040400 01
[00000003]:写入,分配
[15] .堆栈
NOBITS 20000410 01000c 000400 00 1
[00000003]:写入,分配
[16] .NVM
程序位6057000 370000 010000 00 1
[00000003]:写入,分配
[17] .武器属性
ARM_属性00000000 380000 00002e 00 0 1
[00000000]: 
[18] .评论
程序位00000000 38002e 00004c 01 0 1
[00000030]:合并,字符串
[19] .debug_帧
程序位0000000038007C 001174004
[00000000]: 
[20] .刺
程序位00000000 3811f0 0000cc 0c 21 0 4
[00000000]: 
[21]stabstr
STRTAB 00000000 3812bc 0001b9 00 0 1
[00000000]: 
[22].symtab
SYMTAB 00000000 381478 046620 10 23 13540 4
[00000000]: 
[23].strtab
STRTAB 00000000 3c7a98 021cb2 00 1
[00000000]: 
[24].shstrtab
STRTAB 00000000 3e974a 0000df 00 1
[00000000]: 
so.s

so.ld

建造

来自readelf

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x00000000 0x00000000 0x00002 0x00002 R E 0x10000
  LOAD           0x020000 0x20000000 0x20000000 0x00004 0x00004 RW  0x10000
现在这么说吧

MEMORY
{
    one : ORIGIN = 0x00000000, LENGTH = 0x1000
    two : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > one
    .bss : { *(.bss*) } > two AT > one
    .data : { *(.data*) } > two AT > one
}
实际上是.bss在这里发挥了神奇的作用,这是其他一些研究项目,我本可以从一个.C文件开始,但尝试了asm

      6 Apr 28 15:30 so.bin
 131556 Apr 28 15:29 so.elf
现在可能需要6个字节,不需要填充,但当然,您必须在链接器脚本中添加标签,并在引导代码中使用标签将.data移动到ram和zero.bss等

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x00000000 0x00000000 0x00002 0x00002 R E 0x10000
  LOAD           0x020000 0x20000000 0x00000002 0x00004 0x00004 RW  0x10000
请注意,现在物理值是如何在0x00000000范围内的,它被固定在.text使用的空间的末尾。但是虚拟机(它想要居住的地方,需要居住的地方,不要认为这里有mmu或者类似的东西,只要想想两个地址空间(在闪存上和它使用的地方))

如果不清楚:

MEMORY
{
    one : ORIGIN = 0xE0000000, LENGTH = 0x1000
    two : ORIGIN = 0xE0000100, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > one
    .data : { *(.data*) } > two
}

   260 Apr 28 15:46 so.bin
 66276 Apr 28 15:46 so.elf

objcopy以最低定义(可加载)地址启动二进制文件,而不是零…文件大小是最低地址字节和最高地址字节的差值(包括两者)。

您可能应该将您正在使用的链接器脚本加入到您的问题中。我没有理解您的意思,我没有使用链接器脚本进行elf到bin的转换,直接使用objcopyNot是正确的,但您肯定是间接使用了它,因为它的内容指导了在链接阶段在.elf文件中创建的节数以及它们的属性,大小和位置。您可能至少应该为命令
arm none eabi readelf-t test.elf
加入输出。这是非常常见的,取决于您的内存映射,您的链接中可能有一些位置不正确。数据如果您的闪存定义为0x00000000,并且您定义了0x20000000。数据,则转换为-O二进制将使文件至少有0x20000000字节长,即使整个二进制是两个字节的指令和一个字节的数据…(是的,obcopy添加了填充)因此,为了得到1.1GBytes,您可以进行数学运算,估计您为该范围放置的地址空间,然后将其添加到指定的最低地址。
      6 Apr 28 15:30 so.bin
 131556 Apr 28 15:29 so.elf
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x00000000 0x00000000 0x00002 0x00002 R E 0x10000
  LOAD           0x020000 0x20000000 0x00000002 0x00004 0x00004 RW  0x10000
MEMORY
{
    one : ORIGIN = 0xE0000000, LENGTH = 0x1000
    two : ORIGIN = 0xE0000100, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > one
    .data : { *(.data*) } > two
}

   260 Apr 28 15:46 so.bin
 66276 Apr 28 15:46 so.elf