问题描述
当我们将 arm-gcc 工具链生成的 .elf 文件转换为 .bin 文件时,其大小从 40kB 增加到 1.1Gb。
对于转换,我们使用:
./arm-none-eabi-objcopy -O binary test.elf test.bin
可能是因为内存映射不连续,内存区域之间的间隙只是用零填充。
objcopy 中可以使用哪些选项?或者还有其他转换方法吗?
以下是精灵信息:
- Tag_cpu_name: "Cortex-M7" Tag_cpu_arch: v7E-M
Tag_cpu_arch_profile:微控制器 Tag_THUMB_ISA_use:Thumb-2
Tag_FP_arch:用于 ARMv8 的 FPv5/FP-D16 Tag_ABI_PCS_wchar_t:4
Tag_ABI_FP_denormal:需要 Tag_ABI_FP_exceptions:需要
Tag_ABI_FP_number_model:IEEE 754 Tag_ABI_align_needed:8 字节
Tag_ABI_enum_size:小 Tag_ABI_VFP_args:VFP 寄存器
Tag_ABI_optimization_goals:积极调试
Tag_cpu_unaligned_access:v6
包含在 ELF 文件中的节列表是 - 有 25 个节头,从偏移量 0x3e982c 开始:
Section Headers:
[Nr] Name
Type Addr Off Size ES Lk Inf Al
Flags
[ 0]
NULL 00000000 000000 000000 00 0 0 0
[00000000]:
[ 1] .flash_config
PROGBITS 60000000 020000 000200 00 0 0 4
[00000002]: ALLOC
[ 2] .ivt
PROGBITS 60001000 021000 000030 00 0 0 4
[00000002]: ALLOC
[ 3] .interrupts
PROGBITS 60002000 022000 000400 00 0 0 4
[00000002]: ALLOC
[ 4] .text
PROGBITS 60002400 022400 312008 00 0 0 16
[00000006]: ALLOC,EXEC
[ 5] .ARM
ARM_EXIDX 60314408 334408 000008 00 4 0 4
[00000082]: ALLOC,LINK ORDER
[ 6] .init_array
INIT_ARRAY 60314410 334410 000004 04 0 0 4
[00000003]: WRITE,ALLOC
[ 7] .fini_array
FINI_ARRAY 60314414 334414 000004 04 0 0 4
[00000003]: WRITE,ALLOC
[ 8] .interrupts_ram
PROGBITS 20200000 380000 000000 00 0 0 1
[00000001]: WRITE
[ 9] .data
PROGBITS 20200000 340000 014bd0 00 0 0 8
[00000007]: WRITE,ALLOC,EXEC
[10] .ncache.init
PROGBITS 20214bd0 354bd0 011520 00 0 0 4
[00000003]: WRITE,ALLOC
[11] .ncache
NOBITS 20226100 366100 0021d8 00 0 0 64
[00000003]: WRITE,ALLOC
[12] .bss
NOBITS 20229000 369000 077ce8 00 0 0 4096
[00000003]: WRITE,ALLOC
[13] .NVM_TABLE
PROGBITS 20000000 010000 00000c 00 0 0 4
[00000003]: WRITE,ALLOC
[14] .heap
NOBITS 2000000c 01000c 000404 00 0 0 1
[00000003]: WRITE,ALLOC
[15] .stack
NOBITS 20000410 01000c 000400 00 0 0 1
[00000003]: WRITE,ALLOC
[16] .NVM
PROGBITS 60570000 370000 010000 00 0 0 1
[00000003]: WRITE,ALLOC
[17] .ARM.attributes
ARM_ATTRIBUTES 00000000 380000 00002e 00 0 0 1
[00000000]:
[18] .comment
PROGBITS 00000000 38002e 00004c 01 0 0 1
[00000030]: MERGE,STRINGS
[19] .debug_frame
PROGBITS 00000000 38007c 001174 00 0 0 4
[00000000]:
[20] .stab
PROGBITS 00000000 3811f0 0000cc 0c 21 0 4
[00000000]:
[21] .stabstr
STRTAB 00000000 3812bc 0001b9 00 0 0 1
[00000000]:
[22] .symtab
SYMTAB 00000000 381478 046620 10 23 13540 4
[00000000]:
[23] .strtab
STRTAB 00000000 3c7a98 021cb2 00 0 0 1
[00000000]:
[24] .shstrtab
STRTAB 00000000 3e974a 0000df 00 0 0 1
[00000000]:
解决方法
所以.s
.thumb
nop
.data
.word 0x11223344
资源
MEMORY
{
one : ORIGIN = 0x00000000,LENGTH = 0x1000
two : ORIGIN = 0x20000000,LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > one
.data : { *(.data*) } > two
}
构建
arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -T so.ld so.o -o so.elf
arm-none-eabi-objdump -D so.elf
arm-none-eabi-objcopy -O binary so.elf so.bin
536870916 Apr 28 15:23 so.bin
131556 Apr 28 15:23 so.elf
来自阅读
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
}
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 和零 .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 在最低定义(可加载)地址而不是零开始二进制文件......文件大小是最低地址字节和最高地址字节的差值。