我一直在遵循本指南进行操作系统开发 OS Development on Windows
但是,我不喜欢 windows 开发环境,因此我尝试将这些说明转移到我喜欢的 Linux 环境中。
我已经尝试了 Rod's Books 的教程,一切都正确编译,我收到了 hello.efi 文件……但是我如何从它启动?我使用命令 qemu-system-x86_64 -bios OVMF.fd -kernel hello.efi -net none
,但我只得到典型的 EFI shell。
我真正想要的是 Hacker Pulp 指南的 Linux 版本。
我也尝试过 kalzlauskas 的这个指南,以及 osdev UEFI Bare Bones 的这个说明。
最佳答案
TL;DR :主要问题是您不能直接使用 QEMU 的 -kernel
选项运行 EFI 应用程序。 -kernel
用于启动符合 Multiboot 的可执行文件或加载 Linux bzImage 文件。
由于您的问题表明您已设法通过其中一个教程编译和链接 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.efi
并且 pause
提示按下一个键。您不必指定 pause
,如果您运行的程序退出回 shell 会很方便。您可以使用与以前相同的命令运行它:qemu-system-x86_64 -bios OVMF.fd -net none -drive file=fat:rw:bootdrv,format=raw
这会将
bootdrv
目录作为 FAT 文件系统安装在模拟器中作为第一个硬盘驱动器。 EFI 将加载 EFI/BOOT/startup.nsh
作为启动脚本并执行其中包含的命令。那应该自动运行 hello.efi
。关于x86 - 如何在 Linux 上的 NASM 中创建 UEFI 内核,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55408415/