x86 - 如何在 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的这个指令。
解决方案
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.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
。
推荐阅读
- objective-c - 子项目中的 Xcode 导入库头
- python-3.x - 带有python的Docker Cassandra给出连接错误
- python-3.x - 布尔运算符无法始终如一地工作。正确打印“a”,但错误打印“b”
- .net - 应用程序失败:未找到 Microsoft.AspNetCore.Antiforgery
- html - Bootstrap 可折叠不降低视差
- python - 我的浏览器可以访问的资源上的 python urllib.request 超时错误
- java - 使用 -Xss 重现 OutOfMemoryError
- javascript - JavaScript - 无法读取未定义的属性“toLowerCase”
- javascript - jstree检测多个正在移动的项目
- c# - C# 创建文件夹结构的最佳方法