initramfs 程序可以访问所有内存吗?它们是在实模式还是保护模式下运行?

initramfs 程序可以访问所有内存吗?它们是在实模式还是保护模式下运行?

这是在当前 64 位处理器和当前 Linux 内核的上下文中(我使用的是 4.6.4。)

我是否可以编写一个程序,在启动期间可以检查 640k 及以下的基本内存,而不需要它是内核模块?

我正在尝试使用 InfiniBand 协议 SRP 通过 InfiniBand 网络远程启动卷。这很像 iSCSI 引导,但似乎没有任何公开的内容可以实际执行此操作。

我正在使用 iPXE(网络启动固件)。它能够使用 SRP 协议连接到远程卷,并成功加载内核和 initramfs。但是,当执行传递给内核时,内核尚未连接到远程卷,因此它不知道或看到它。

iPXE 将有关连接对象和连接方式的信息保留在名为 sBFT(一种 ACPI 表)的基本内存(< 640k)中。

iSCSI 做的事情非常相似,引导加载程序将该信息保留在 ACPI 表中,称为 iBFT,但有一个内核模块 iscsi_ibft,它为 iBFT 结构提供了 sysfs 接口。我还没有看到 InfiniBand sBFT 的等效项,例如 ib_sbft 内核模块。

所以,我想知道我是否希望它能够工作,如果有人(也许是我)需要编写不存在的 ib_sbft 内核模块。

或者,有没有办法让程序能够访问基本(< 640k)内存而不会发生内存冲突,并且在它(大概)被其他东西覆盖之前?

我正在使用 Arch Linux,它使用 mkinitcpio 来制作初始 ramdisk 并在早期启动过程中运行程序,但我认为到那时已经太晚了并且在保护模式下运行。 (除非进行更改,否则实模式将以 16 位运行,并且我没有看到任何有关需要以 16 位编译的初始 ramdisk 程序的信息,这让我相信为时已晚。)

答案1

initramfs就所有意图和目的而言,文件系统只是在 处加载的另一个文件系统,/并且在其中运行的程序是从用户空间在运行的内核下。这意味着它们与任何其他程序具有相同的限制。

您可能会通过以下方式找到所需的数据,/dev/mem但您可能不应该依赖于特定的iPXE实现;不同的供应商和不同的 PXEboot 流程很容易改变事情。

通常,这些信息应该作为内核调用命令的一部分传递,因此在/proc/cmdline用户空间程序可以解析它并执行任何必要操作的地方可见。

答案2

从 initramfs 运行的程序是完全普通的程序。它们像任何其他 Linux 进程一样运行。

从实模式(32 位 x86 处理器的启动时传统模式)到保护模式(自 286 一代以来的 32 位 x86 处理器的正常工作模式)的切换发生在 Linux 内核启动过程的早期。甚至连司机都还没有起步。

如果您的外设在特定的物理地址存储某些内容,那么您可以通过该设备访问它/dev/mem。您需要告诉内核不要使用该范围的物理地址,我不知道该怎么做(IIRC 有一个内核命令行选项,但我现在找不到它)。

然而,您所需要的可能已经作为通用 ACPI 功能的一部分存在,使您可以访问原始 ACPI 数据,但无法访问已解析的数据,例如iscsi_bft.

相关内容