U-Boot interferes with initrd binary — Revert "efi: Correct smbios-table installation" ?
Christian Kohlschütter
christian at kohlschutter.com
Mon Mar 31 18:49:56 CEST 2025
Hi all,
After upgrading some rather old U-Boot/IPXE setup on two aarch64 boards (Amlogic S922X-based ODROID N2+ and RK3399-based NanoPi R4S), I noticed strange errors in the initrd phase of my Linux kernel — usually something like "Illegal instruction" coming from "udhcpc", etc.
The setup I have boots iPXE from U-Boot (either stored on SD or SPI), which then loads a Linux kernel, two initrds and a dtb from the local network, and boots Alpine Linux.
I found that the busybox binary used in my initrd had an md5sum mismatch compared to what was expected. I ruled out network problems since checksums from within iPXE were correct.
So some code, either U-Boot, iPXE, or the Linux kernel, were interfering with the busybox binary at runtime. Since a single binary is used for many commands, and the changes were not always in the same location, there was wide variety of how things could fail, and — many times — fail in way that did not prevent booting.
As a workaround, via iPXE, I added a "padding" initrd to be loaded first, containing an 8MB long zero-byte filled file named /.aaaaargh. If there were any modifications, the would hit the padding file, not the busybox binary.
If there were modifications, the file would remain completely empty upon boot.
However, they weren't:
Example dumps from two runs:
# hexdump /.aaaaargh
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0044100 ffff ffff ffff 15dc f9c8 6f16 e188 0000
0044110 00a0 52b0 a01c 6d59 0000 0000 0000 0000
0044120 0000 0000 0000 0000 0000 0000 0000 0000
0044130 0000 0000 0000 0000 0000 0000 e1a8 6097
0044140 0000 0000 0000 0000 0000 0000 0000 0000
*
0155840 0320 0040 0000 0000 0000 0000 0000 0000
0155850 0000 0000 0000 0000 0000 0000 0000 0000
*
0800000
# hexdump /.aaaaargh
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
001f800 ffff ffff ffff 15dc f9c8 6f16 e188 0000
001f810 00a0 52b0 a01c 6d59 0000 0000 0000 0000
001f820 0000 0000 0000 0000 0000 0000 0000 0000
001f830 0000 0000 0000 0000 0000 0000 e1a8 6097
001f840 0000 0000 0000 0000 0000 0000 0000 0000
*
0094f40 0320 0040 0000 0000 0000 0000 0000 0000
0094f50 0000 0000 0000 0000 0000 0000 0000 0000
*
0800000
By git-bisect'ing the codebase I found that the following U-Boot commit must have triggered the bug:
> commit 06ef8089f876b6dabf56caba31a05c003f03c629 (HEAD)
> Author: Simon Glass <sjg at chromium.org>
> Date: Sun Dec 31 08:25:55 2023 -0700
>
> efi: Correct smbios-table installation
> At present this code allocates memory when writing the tables and
> then unnecessarily adds another memory map when installing it.
> Adjust the code to allocate the tables using the normal U-Boot
> mechanism. This avoids doing an EFI memory allocation early in
> U-Boot, which may use memory that would be overwritten by a
> 'load' command, for example.
> Signed-off-by: Simon Glass <sjg at chromium.org>
>
> lib/efi_loader/efi_smbios.c | 16 +++++++---------
> 1 file changed, 7 insertions(+), 9 deletions(-)
From what I gather from the code, the use of "memalign" instead of "efi_allocate_pages" could be the reason for the observed memory corruption, but I'm no expert in this codebase.
For what it's worth, the commit can cleanly be reverted from a recent U-Boot HEAD, and indeed, the system boots fine afterwards.
I also once noticed that one time the memory corruption happened after the first few calls within initrd, so maybe it's a "free" corresponding to that memalign that is triggering this bug.
Or, maybe it's all good from u-boot's side but iPXE needs to do something, I don't know. I'm just the messenger here...
I wonder what can be done other than reverting this change (or using a padding initrd during boot) ?
Thanks,
Christian
More information about the U-Boot
mailing list