如何在Linux上的NASM中创建UEFI内核

Jon*_*ein 3 x86 kernel qemu osdev uefi

我一直在遵循本指南进行OS开发Windows上的OS开发

但是,我不喜欢Windows开发环境,因此我试图将这些指令转移到我首选的Linux环境中。

我已经尝试了Rod's Books的教程,并且所有内容都能正确编译,并且收到hello.efi文件...但是如何从中启动?我使用命令qemu-system-x86_64 -bios OVMF.fd -kernel hello.efi -net none,但仅获得典型的EFI shell。

我真正想要的是拥有Linux版的Hacker Pulp指南。

我还尝试过kalzlauskas的本指南以及osdev UEFI Bare Bones的本指南。

Mic*_*tch 6

TL; DR:主要问题是无法使用QEMU的选项直接运行EFI应用程序-kernel-kernel用于启动兼容Multiboot的可执行文件或加载Linux bzImage文件。


由于您的问题表明您已经设法将EFI应用程序编译并链接到其中一个教程,因此,此答案将严格集中在使用QEMU运行它的方法上。遵循哪种教程或方法来构建EFI应用程序本身并不重要。

在项目目录中使用此命令可创建一系列子目录,以用作EFI启动驱动器:

mkdir -p bootdrv/EFI/BOOT/
Run Code Online (Sandbox Code Playgroud)

您只需要创建一次目录。创建它们后,将您的hello.efi文件复制到名为的文件bootdrv/EFI/BOOT/BOOTX64.EFIEFI/BOOT/BOOTX64.EFI是64位UEFI的默认启动文件。在32位UEFI上,默认启动文件为EFI/BOOT/BOOTIA32.EFI。运行以下命令以启动您的EFI程序:

qemu-system-x86_64 -bios OVMF.fd -net none -drive file=fat:rw:bootdrv,format=raw
Run Code Online (Sandbox Code Playgroud)

这会将bootdrv目录作为FAT文件系统安装在模拟器中,作为第一个硬盘驱动器。64位EFI应自动运行文件EFI/BOOT/BOOTX64.EFI


或者,您可以将hello.efi文件复制到目录bootdrv/EFI/BOOT/,并使用bootdrv/EFI/BOOT/startup.nsh包含以下命令的名称创建启动脚本:

\EFI\BOOT\hello.efi
pause
Run Code Online (Sandbox Code Playgroud)

EFI/BOOT/startup.nsh是将在没有默认EFI应用程序的情况下运行的默认启动脚本。最后一个命令后,文件应包含一个空行。该命令\EFI\BOOT\hello.efi运行hello.efipause提示您按一个键。您不必指定pause,这很方便,如果您运行的程序退出外壳。您可以使用与以前相同的命令来运行它:

qemu-system-x86_64 -bios OVMF.fd -net none -drive file=fat:rw:bootdrv,format=raw
Run Code Online (Sandbox Code Playgroud)

这会将bootdrv目录作为FAT文件系统安装在模拟器中,作为第一个硬盘驱动器。EFIEFI/BOOT/startup.nsh作为启动脚本加载并执行其中包含的命令。那应该自动运行hello.efi

  • @JonathanDewein:它不依赖于特定的教程。如您所言,您能够构建一个名为`hello.efi'的EFI应用程序,因此我专注于运行它的实际问题。构建EFI文件后(无论您是如何构建的,也无论是什么教程的),上述方法都可以在Linux上运行。您不能使用QEMU`-kernel`选项直接运行EFI应用程序。 (2认同)