我了解像Linux或Windows这样的操作系统是用C / C ++编写的,并已编译为给定的体系结构(例如AMD64),以生成适合该体系结构的机器代码。
我的问题-
您可能已经猜到,可执行文件格式不仅仅包含机器代码。例如,他们可以:
指定OS的元数据,例如可执行文件的目标体系结构。此元数据包含文件的头。
指定程序在内存中的布局。在现代OS上,大多数可执行文件不会以单个块的形式加载到内存中-它们通常具有许多单独的区域/部分/段。这些段中的一些将包含可执行代码。其中一些将包含不可变的数据,例如文本字符串。其中一些将被指定为程序堆的可写内存。
对于这些部分的大小,不同的程序将有不同的要求(要求)。所有这些都在标题中指定。
某些格式还允许您嵌入数字签名,该签名可以验证二进制文件的来源。
- 为什么二进制代码需要单独的规范-Linux使用ELF,Windows使用可移植可执行格式?
原因主要是历史原因,并且操作系统倾向于坚持使用其现有的“本机”(或“默认”)格式,除非有令人信服的理由进行切换(例如,从NT 3.1中的DOS MZ格式转换为PE,以及从NT 3.1中转换为PE)。 .out到Linux 1.2中的ELF,以及多年来从各种Unix中的COFF到ELF)。
应当注意的是,底层机器代码取决于CPU体系结构,但其他方面(除了syscalls和链接库)在操作系统之间可移植性很强。实际上,现代Windows和Linux都可以运行两种可执行格式:ELF可执行文件将通过WSL在Windows上运行,PE可执行文件将通过WINE在Linux上运行。
- 是否可以在没有此二进制格式规范的情况下创建操作系统和在该操作系统上运行的程序?
我们回到这些格式的主要目的。如果没有元数据告诉OS将程序的某些部分加载到何处,则大多数现代可执行文件将无法运行。一些非常古老的格式(例如COM)几乎都包含纯代码,但不是特别灵活,因此不受欢迎。
实际上,甚至不需要操作系统。在硬件级别上,假设存在(旧版)BIOS,BIOS会简单地在磁盘(MBR)上的特定位置开始执行,该位置可以是任意机器代码,然后由它们接管并启动操作系统或执行任何操作其他喜欢。(您可以将MBR本身视为二进制格式,尽管它与可执行代码没有直接关系。)但是,更现代的UEFI确实指定了更复杂的可执行格式(PE)。
- 二进制格式体系结构是依赖于操作系统还是依赖于操作系统?
确实取决于格式。某些格式采用特定的体系结构。其他允许您从标题中指定的“魔数”列表中选择体系结构。还有一些是完全与体系结构无关的(例如Java和.NET / CIL字节码)。
同样,格式通常不会对OS施加任何限制,尽管将限制OS可以(本机)识别和执行的格式。当然,核心操作系统之上的兼容性层可以执行核心操作系统可能无法识别的其他格式(例如JVM,.NET / CLR,WSL&WINE等)。
- 二进制格式仅适用于可执行文件还是适用于操作系统代码?
在大多数现代操作系统中,很大一部分只是“正常”可执行文件的集合。但是,操作系统的某些部分是“特殊的”,不一定使用与其余部分相同的格式。通常,这仅适用于引导加载程序和内核。
举一个特定的,非常常见的例子,传统的BIOS引导加载程序将既不是Linux操作系统,也不是Windows操作系统使用的ELF或PE格式。Linux内核通常以GRB引导加载程序可以加载的ELF派生格式构建,但可以采用不同的格式来与所使用的引导加载程序兼容。Linux内核还支持EFI存根模式,该模式包含最小的PE / COFF标头,以便与直接UEFI引导兼容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句