首页 > 解决方案 > 如何在 Linux 上的 NASM 中创建 UEFI 内核

问题描述

我一直在关注本指南以进行操作系统开发Windows 上的操作系统开发

但是,我不喜欢 windows 开发环境,所以我试图将这些指令转移到我喜欢的 Linux 环境中。

我已经尝试了Rod's Books中的教程,并且一切都正确编译,并且我收到了 hello.efi 文件......但是我如何从它启动呢?我使用 command qemu-system-x86_64 -bios OVMF.fd -kernel hello.efi -net none,但我只得到了典型的 EFI shell。

我真正想要的是有一个 Linux 版本的 Hacker Pulp 指南。

我也试过 kalzlauskas 的这个指南,以及 osdev UEFI Bare Bones的这个指令。

标签: x86kernelqemuosdevuefi

解决方案


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


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

在您的项目目录中使用此命令创建一系列子目录以用作EFI引导驱动器:

mkdir -p bootdrv/EFI/BOOT/

您只需创建一次目录。hello.efi创建它们后,将文件复制到名为bootdrv/EFI/BOOT/BOOTX64.EFI. EFI/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

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


作为替代方案,您可以将hello.efi文件复制到目录bootdrv/EFI/BOOT/,并创建一个名称bootdrv/EFI/BOOT/startup.nsh包含以下命令的启动脚本:

\EFI\BOOT\hello.efi
pause

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

qemu-system-x86_64 -bios OVMF.fd -net none -drive file=fat:rw:bootdrv,format=raw

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


推荐阅读