如何检查当前运行的Linux内核是否已经被kexec加载?

如何检查当前运行的Linux内核是否已经被kexec加载?

通过检查我的意思是一些非常可靠的东西,即尝试分析加载程序的配置或可用的内核文件并匹配 uname 的输出显然不是一个选项。

答案1

在一般情况下,不,这是不可能的,因为之前的状态都不可信任,并且无法与常规重新启动区分开来。

举个例子,您的系统在启动时不会擦除 RAM(某些安全启动规范等需要在启动时擦除内存);初始启动过程和每次正常重新启动通常会在相同的偏移量处发生,并随着时间的推移擦除上次启动的所有内容。内核本身几乎总是被加载到相同的地址。

现在考虑使用 kexec 而不是正常的重新启动,并意识到所有内容都应该以相同的偏移量结束,并且基本上无法区分。

是否存在可以检测到 kexec 的特殊情况?是的!

  • Kdump 显式地在不同的地址加载新内核,并希望保留先前内核的内存以捕获错误状态。
  • 如果 BIOS 和内核以不同的方式初始化硬件,则可能会注意到这一点(显然),因为每次启动时都会使用开关“usual/kexec”进行更改。
  • 作为一个具体的例子,EFI 帧缓冲区肯定会在引导期间被内核更改,并且永远不会在 kexec 上返回到原始状态。
  • 由此得出的结论是,如果您不控制 kexec 内核的启动,并且它接触到硬件,那么以后几乎没有办法确定它是否是一个真实的引导或执行程序启动。

作为演示,我启动了一个带有内核的虚拟机,捕获了 dmesg,然后立即对其执行了硬 kexec,再次捕获了 dmesg。这是两次运行 dmesg 之间的差异:https://gist.github.com/robbat2/7609be2715591eac8ace3f46e852c549

答案2

我刚刚在代码中找到了答案,我想分享一下。

要检查用于加载正在运行的内核的引导加载程序,请检查:

/proc/sys/kernel/bootloader_type

然后需要右移 4 位来获取 bootloader_type,它在以下 x86 文件中进行了描述(在内核树中):文档/x86/boot.rst

kexec 加载程序在移位后将显示 0xD(从 kexec-tools 代码中,我们可以看到它定义为#define LOADER_TYPE_KEXEC 0x0D)。

不幸的是,这是一个仅限 x86 的技巧!希望能帮助到你。

相关内容