By checking I mean something quite rock-solid, i. e., trying to analyse loader's configuration or available kernel files and matching to uname's output clearly isn't an option.
2 Answers
In the general case, no, it's not possible, because nothing of the previous state can be trusted, and cannot be distinguished from a regular reboot.
Just say for a example you have a system that does NOT wipe RAM at boot (memory wipe on boot is required by some secure boot specs etc); The initial boot process and every normal reboot will generally happen at the same offsets, and wipe over everything from the previous boot over time. The kernel itself will almost always be loaded at the same address.
Now consider kexec instead of a normal reboot, and realize that everything should wind up at the same offsets, and be mostly indistinguishable.
Are there special cases where kexec CAN be detected? YES!
- Kdump explicitly loads the new kernel at a different address, and hopes to preserve the previous kernel's memory for capture of error state.
- If BIOS and kernel initialize hardware differently it (obviously) might be noted since there would be changes on each boot with switch "usual/kexec".
- As a specific example of this, the EFI frame buffer is definitely altered by the kernel during boot, and never returns to the original state on kexec.
- The corollary of this, is that if you don't control the boot of the kexec'd kernel, and it touches the hardware, there is pretty much no way to later decide if it was a real boot or a kexec boot.
As a demo, I booted a VM with a kernel, captured dmesg, then immediately did a hard kexec on it, captured dmesg again. Here's the diff between the two runs of dmesg: https://gist.github.com/robbat2/7609be2715591eac8ace3f46e852c549
-
> This only lets you detect the FIRST reboot with kexec — why you emphasised FIRST? If you boot normally state would return to BIOS's and it can be detected. So each time you know whether it wasn't BIOS boot. ;)– poigeFeb 16, 2018 at 14:33
-
-
Still unsure why. kexec looks same no matter whether they're few in row or just single. In case you boot w/o kexec dmesg would be different. So that's why I see no point in this emphasising– poigeFeb 21, 2018 at 8:09
I just found the answer in code, and I'd like to share.
To check what was the bootloader used to load the running kernel, check:
/proc/sys/kernel/bootloader_type
One need then to shift-right 4 bits to get the bootloader_type, which is described in the following file for x86 (in the kernel tree): Documentation/x86/boot.rst [0]
The kexec loader would show 0xD after the shift (from kexec-tools code, we can see it defined as #define LOADER_TYPE_KEXEC 0x0D).
It's a x86-only trick, unfortunately!!! Hope it helps.
[0] www.kernel.org/doc/Documentation/x86/boot.rst
-
1no need for sorry here, it's way more reasonable to provide opportunities to reply to a topic instead of urging people to skip sharing theirs findings or urging them to open new instances of the same questions. I've personally seen this on Apple's forum which I dislike a lot partially due to this limitation (but not only).– poigeFeb 19, 2020 at 6:32
-
1
-
1Thanks for the addition, but I've seen cases where it's NOT correct, like EFI loaded systems that have the value 0x06 in that file, which would be 0x0 after the shift, supposedly legacy-LILO– robbat2Oct 10, 2021 at 23:44
cat /proc/cmdline
?dmesg
orcat /proc/cmdline
?kexec
from a Linux based bootloader.