Operating system 我应该制作自己的操作系统内核ELF还是原始二进制文件?

Operating system 我应该制作自己的操作系统内核ELF还是原始二进制文件?,operating-system,kernel,elf,bootloader,osdev,Operating System,Kernel,Elf,Bootloader,Osdev,我已经开始了我的操作系统开发之旅。人们通常会大声疾呼,使用原始二进制而不是ELF(或其他结构化格式)是定制操作系统中应用程序的常见错误。我可以支持这一点,因为ELF提供了其他好处(存储元信息的位置,如符号表、.debug和.line)。但是,让我们考虑一下内核二进制文件本身。它是否应该结构化(如ELF),如果是,为什么?否则,编写ELF加载程序并在stage1加载程序之后立即压缩它似乎是一种浪费 AFAIK Linux内核是一个ELF文件,但我不知道为什么。a.out可能是原始/平面二进制文件和

我已经开始了我的操作系统开发之旅。人们通常会大声疾呼,使用原始二进制而不是ELF(或其他结构化格式)是定制操作系统中应用程序的常见错误。我可以支持这一点,因为ELF提供了其他好处(存储元信息的位置,如符号表、.debug和.line)。但是,让我们考虑一下内核二进制文件本身。它是否应该结构化(如ELF),如果是,为什么?否则,编写ELF加载程序并在stage1加载程序之后立即压缩它似乎是一种浪费


AFAIK Linux内核是一个ELF文件,但我不知道为什么。

a.out可能是原始/平面二进制文件和ELF之间更好的折衷方案。在a.out中,您可以像在ELF中一样将代码从数据和未序列化的数据中分离出来,并且您可以进行重新定位(和符号,如果您愿意的话),如果不明确地重新创建其中的一部分,您就无法在原始/平面二进制文件中获得它们。然而,a.out比ELF简单得多,几乎和raw/flat一样简单。非常容易解析和加载(除非您像我在编译器的DPMI存根中那样使用16位汇编代码:)。

我讨论了是否应该深入探讨一个广泛的问题,从而得出自以为是的答案。我通常会投票结束这样的问题,但在这种情况下,我会给出一个可能对其他人有益的回答。如果你问为什么?我这样做是为了这个问题——历史已经在Stackoverflow上表明,这个问题通常是作为更具体的操作系统开发问题的一部分间接提出的


ELF对内核的一些优势?

  • 调试信息可以嵌入到对象中
  • ELF加载程序可以在内存中设置映像,自动将BSS部分归零等
  • 未初始化或零初始化的全局数据不会占用映像内部的空间
  • 与多引导兼容的引导加载程序(如GRUB)可以加载正确设计的ELF可执行文件
  • 可设计为可重新定位
缺点?

  • ELF头放在可执行文件的开头,这可能会干扰可执行文件将在其中运行的预期目标环境(如引导加载程序)
  • 对于小程序,ELF头对于某些用途来说可能太大(引导加载程序)
  • 需要代码(最小ELF加载程序)将可执行文件引导到内存中并开始执行它

为什么不使用ELF作为最终引导扇区映像(MBR)?

主要原因是ELF格式将头信息放在代码之前。遗留BIOS(非EFI)将无法理解它,并开始以代码形式执行头信息


能否使用ELF映像调试16位引导加载程序?

这取决于环境和调试器。通过QEMU中的远程GDB调试,这是非常可能的。您可以在汇编程序(如NASM/GAS等)中生成一个16位实模式可执行文件作为ELF对象(具有Dwarf调试信息),将其链接到最终的ELF可执行文件,然后使用类似objcopy的程序剥离ELF头以生成最终的平面二进制文件

如果将引导加载程序拆分为一个简单的二进制文件,为什么还要为它生成ELF对象呢?

尽管精简的二进制文件将在目标环境中运行,但具有远程调试功能(如QEMU)的环境可以使用本地ELF二进制文件解析变量名、标签、常量,并允许导航原始源文件(而不仅仅是原始程序集)

您能为16位调试提供此技术的示例吗?

是的,这类问题以前也出现过。我提供了一些答案,说明了如何使用GDB的远程调试服务和QEMU中的远程调试器来实现这一点。一个这样的例子可以在这里找到。该示例是一个可以使用GDB调试的16位引导加载程序示例。GDB的16位调试存在问题,因为它不了解16位代码中的段:偏移对。提供了一个指向脚本的链接,在这方面提供了帮助,并提供了QEMU使用示例


与多引导加载程序一起使用ELF可执行文件是否有优势?

对!!GRUB这样的多引导兼容引导加载程序的一大优势是它能够理解ELF映像。如果您正在编写一个受保护模式内核,并且为您的内核使用了一个正确构造的多引导兼容可执行文件,那么您可以省去设置受保护模式环境、启用A20门、获取内存映射和初始化启动视频模式的苦差事(在x86系统上)

QEMU能否直接启动符合多引导的ELF内核可执行文件?

是的,通过使用
-kernel
选项的适当命令行,这是可能的。他有一个例子

能否使用带有调试信息的ELF二进制文件调试32位受保护模式?

是的,这比在实模式下运行的16位引导加载程序更简单。在本文中,我提供了一个这种技术的示例。尽管该技术适用于使用ISO映像的QEMU,但您也可以使用
-kernel
选项直接使用多引导内核加载QEMU


为什么现代版本的Linux内核使用ELF格式?

在Linux开发的古代,Linux有自己的引导加载程序、设置保护模式、启用A20门等。这个过程在不同的体系结构中是不同的。Linux内核开发人员选择将这项工作留给第三方引导加载程序来完成

在现代桌面系统中,您会发现GRUB用作Muliboot加载程序;可以使用ELILO;在一些嵌入式系统上,U-Boot成为引导加载程序的首选。多重引导规范是出于引导Linux内核的需要而产生的,但它独立于操作系统。internet上的许多玩具内核示例都被编码为用作ELF execut