ELF文件和bin文件有什么区别?


97

编译器生成的最终图像包含bin文件和扩展的加载程序格式ELf文件,两者之间有什么区别,尤其是ELF文件的实用程序。


这就是NASM必须说的。不是特定于ARM的,但可能是相同的概念。例如,如果您编译的文件中仅包含NOP不带-f(或-fbin)的文件,则该文件将被编译为一个字节0x90,而不是一个包含400个字节的ELF容器-felf32。所以只有原始代码,没有容器元数据。NASM说,它主要用于MS-DOS .COM和.SYS文件。section指令通常被忽略,仅产生对齐。
Ciro Santilli郝海东冠状病六四事件法轮功2015年

这是可以使用bin文件的一种方式:使引导扇区部署操作系统:stackoverflow.com/a/32483545/895245
Ciro Santilli郝海东冠状病六四事件法轮功

Answers:


93

Bin文件是一个纯二进制文件,没有内存修复或重定位,很可能它有明确的指令要加载到特定的内存地址。而...

ELF文件是可执行的可链接格式,它由符号查找和可重定位表组成,也就是说,内核可以将其加载到任何内存地址,并且所有使用的符号都会自动调整为与该内存地址的偏移量。被装入。通常,ELF文件具有多个部分,例如“数据”,“文本”,“ bss”等,但其中有一些...在这些部分中,运行时可以计算出调整符号的内存引用的位置。在运行时动态地。


“很有可能在特定的内存地址上有明确的指令要加载”:这是否意味着bin文件生成过程添加了用于将数据加载到特定地址的附加代码?
Penghe耿

1
据我了解,bin文件就像从偏移量0开始运行程序,并且数据段已嵌入其中。如果这是错误的,请纠正我。
Martin Kersten 2015年

@MartinKersten正确,Bin文件从偏移0开始
t0mm13b

1
@ t0mm13b因此,.elf文件可以像普通的.hex文件一样被刻录到微控制器上,但是它需要更多的闪存,并且每次重置微控制器时,节的地址都会更改吗?
Aelgawad

@BlackyDucky,我认为这是不可能的。如果微控制器试图直接执行ELF数据,则会将标头和其他数据误解为指令,对吗?
iX3

40

Bin文件只是进入rom或运行程序的特定地址的位和字节。您可以获取此数据并直接按原样加载它,您需要知道基址是什么,因为该地址通常不在其中。

一个elf文件包含bin信息,但周围有许多其他信息(可能的调试信息,符号)可以将代码与二进制文件中的数据区分开。允许多于一个的二进制数据块(当您将其中一个转储到bin时,您将获得一个包含填充数据的大bin文件,以将其填充到下一个块中)。告诉您有多少二进制文件以及要初始化为零的bss数据有多少(gnu工具在正确创建bin文件时遇到问题)。

elf文件格式是一种标准,arm会在该标准上发布其增强/变化。我建议每个人都编写一个elf解析程序以了解其中的内容,而不必理会库,仅使用规范中的信息和结构就非常简单。帮助克服一般创建.bin文件以及调试链接程序脚本和其他可能会弄乱bin或elf输出的事物的gnu问题。


1
0x7C00听起来像一个引导加载程序,它不一定使用elf。这是一个普遍的问题。操作系统将具有(虚拟)地址空间的规则,工具链将需要针对该操作系统规则,然后文件格式将指示具有地址的可加载项以及加载后的入口点以及其他内容。elf只是一个容器,就像一个盒子一样,您必须针对目标用例将其正确包装。
old_timer

1
如果您想将某些ascii打印到VGA,则编写一个程序来执行该操作,该程序具有一些数据,或者在运行中或以某种组合方式数学生成数据,然后将该程序加载到操作系统定义的代码空间中,然后运行它。通常,您通常不会将数据直接推送到物理外围设备中,而罕见的操作系统会让您无论如何都可以这样做,或者允许它的加载器执行该操作。
old_timer

1
对于裸机,尤其是如果此elf文件是引导加载程序和/或第一个程序运行,则入口点和_start不相关,因为您将elf文件用作编程闪存的工具的垫脚石(例如openocd jtag)或通过任何-objobjcopy -O二进制file.elf file.bin然后将该文件以某种方式加载到闪存中。并没有尝试在x86上尝试引导加载程序,但假设BIOS无法解析elf文件,因此它也必须是内存映像。因此,-O二进制类型的bin文件
old_timer

1
单独的实体是硬件/逻辑或其他设计。对于操作系统,则操作系统制定规则;对于微控制器,芯片/处理器设计制定规则。例如,如果有一个向量表,然后向量指向处理程序,则必须将所有这些数据都滚动到链接描述文件中,以此类推,以便将可加载的数据发送到事物所要从其中存储的闪存中。
old_timer

1
要扩大目标系统的规则范围,无论是操作系统,处理器还是多级引导程序等。您都需要根据这些规则构建“二进制文件”,其中引导程序和链接描述文件最为重要。然后就每个目标以及如何应用该二进制文件以及所支持的文件格式进行了非常广泛的介绍。假设在许多主机开发平台上使用gnu,则elf文件格式是默认输出,然后根据需要使用工具(如果目标特定的实用程序/加载程序)从elf提取或转换为其他文件。
old_timer

30

一些资源:

  1. 用于ARM体系结构的ELF
    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
  2. 来自Wiki的ELF
    http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

ELF格式通常是编译的默认输出。如果使用GNU工具链,则可以使用objcopy将其转换为二进制格式,例如:

  arm-elf-objcopy -O binary [elf-input-file] [binary-output-file]

或使用fromELF实用程序(尽管内置在大多数IDE(例如ADS)中):

 fromelf -bin -o [binary-output-file] [elf-input-file]

6
此文件是在回答bin文件的详细信息后添加的,并且确实附加了一种实用的技术。+1。
erbdex

-1

我只想在这里纠正一点。ELF文件是由链接器而不是编译器生成的。

从源代码文件生成目标文件(* .o)后,编译任务结束。链接器将所有.o文件链接在一起,并生成ELF。


拒绝投票是因为它没有回答问题,也不一定正确。广义上讲,编译包括链接。从ld文档中引用:通常,编译程序的最后一步是运行ld。
bzeaman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.