这是在当前 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
.