在纯 UEFI 中启动时谁启用了 A20 线?

Posted

技术标签:

【中文标题】在纯 UEFI 中启动时谁启用了 A20 线?【英文标题】:Who enables the A20 line when booting in pure UEFI? 【发布时间】:2020-01-04 22:50:24 【问题描述】:

这是由 UEFI 固件处理还是由 GRUB grubx64.efi 引导加载程序处理?

我查看了https://wiki.osdev.org/UEFI,它声称:

UEFI 固件 ... 还准备了具有平面分段的保护模式环境,对于 x86-64 CPU,还准备了具有标识映射分页的长模式环境。 A20 门也已启用。

但找不到任何官方来源来支持此信息。 UEFI 规范没有提到这一点。

linux 内核提供了一个 efi-stub 可以充当引导加载程序,但是在检查了它的源代码后,我看不到它是否启用了 A20。所以我仍然不知道它是 UEFI 固件的工作还是引导加载程序的工作。

(我想为 UEFI 编写自己的引导加载程序,并想了解 UEFI 固件提供“开箱即用”的设置以及必须由我实现的部分)

【问题讨论】:

【参考方案1】:

UEFI 固件启用 A20(如果尚未启用),使用平面描述符设置 GDT,进入保护模式等。在 64 位 CPUS 上,它还进入涉及启用身份映射分页的长模式。为了使 UEFI 按预期运行,它需要启用 A20 才能正确访问所有物理内存。

在一些更现代的处理器上,A20 会在开机时启用,甚至可能无法关闭。英特尔已开始摆脱传统要求,包括放弃支持 pre-286 环境。可以切换的 A20 门的存在是为了使 286(和更高版本的处理器)保持与旧的 8086/80186(或等效)处理器的兼容性。无法更改 A20 状态以及放弃旧版 Bios 是朝着这个方向迈出的一步。

一旦您的 UEFI 引导加载程序代码开始运行,您就可以保证 A20 将在此时启用。从启用它的角度来看,A20 只是您不关心的东西。

虽然UEFI specification中没有特别提到A20,但似乎是隐含的:

2.3.2.1 切换状态 加载 32 位 UEFI 操作系统时,系统固件将控制权交给 平面 32 位模式的操作系统。全部 描述符设置为 4GiB 限制,以便所有内存段都可以访问所有内存

在禁用 A20 的情况下,并非所有内存都可以从所有段访问,因此我推断必须在处理器或 UEFI 固件中默认启用 A20。

【讨论】:

感谢您的回答!您能否向我建议一份文档/规范,以便我可以阅读更多关于 UEFI 固件在启动时处理的内容?基本上是这些信息的来源:) @user10607 :虽然规范没有特别提到 A20,但我相信我现在在更新的答案中引用的部分推断必须启用 A20,否则并非所有内存都可以从所有段访问。 我同意这个推理,但建议 2.3.2(对于 IA32)和 2.3.4(对于 X64)的第一部分已经暗示了这一点。我认为这是相关的,因为 2.3.x.1 真正谈论的是 ExitBootServices() 之后的状态,而 2.3.x 甚至谈论的是在那之前的状态(驱动程序、引导加载程序)。对于 IA32,这不太清楚,但我认为强制保护模式和“如果启用分页模式,则 UEFI 内存映射定义的任何内存空间都是身份映射”和“选择器设置为平坦的,否则不是used" 如果不启用 A20 将很难实现。

以上是关于在纯 UEFI 中启动时谁启用了 A20 线?的主要内容,如果未能解决你的问题,请参考以下文章

安装WIN7提示,硬盘不支持启动磁盘,请确保BIOS菜单中磁盘控制器启用

我对A20线检查代码的理解是否正确?

UEFI启动流程

KVM创建支持UEFI启动的虚拟机

戴尔g3如何启用legacy模式?

如何让A20,android开机自动启动C程序