[BOOTWRAPPER PATCH] aarch64: Account for kernel header image_size when placing FDT/XEN

Vladimir Murzin vladimir.murzin at arm.com
Tue Jan 20 07:28:38 PST 2026


We currently use fixed memory offsets for object loaded into
memory. In particular, FDT_OFFSET is hardcoded to 0x08000000 (128MiB).
This can fail when the kernel's loaded image fits just below FDT_OFFSET,
but its (non-loaded) .bss extends past it at runtime and overwrites the
FDT.

Let's compute FDT_OFFSET from the kernel header image_size (fallback to
0x08000000 when the header is missing). Also place XEN_OFFSET 2 MiB
after FDT_OFFSET.

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
---
 Makefile.am                |  6 +++---
 scripts/AA64Image.pm       |  7 +++++++
 scripts/aa64-fdt-offset.pl | 39 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 3 deletions(-)
 create mode 100644 scripts/aa64-fdt-offset.pl

diff --git a/Makefile.am b/Makefile.am
index 0178e5d..4efca15 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -100,10 +100,12 @@ if KERNEL_32
 MBOX_OFFSET	:= 0x7ff8
 TEXT_LIMIT	:= 0x3000
 KERNEL_OFFSET	:= 0x8000
+FDT_OFFSET	:= 0x08000000
 else
 MBOX_OFFSET	:= 0xfff8
 TEXT_LIMIT	:= 0x80000
 KERNEL_OFFSET	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/aa64-load-offset.pl $(KERNEL_IMAGE) $(TEXT_LIMIT))
+FDT_OFFSET	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/aa64-fdt-offset.pl $(KERNEL_IMAGE) $(KERNEL_OFFSET) 0x08000000)
 endif
 
 LD_SCRIPT	:= model.lds.S
@@ -113,11 +115,9 @@ FILESYSTEM_START:= $(shell echo $$(($(PHYS_OFFSET) + $(FS_OFFSET))))
 FILESYSTEM_SIZE	:= $(shell stat -Lc %s $(FILESYSTEM) 2>/dev/null || echo 0)
 FILESYSTEM_END	:= $(shell echo $$(($(FILESYSTEM_START) + $(FILESYSTEM_SIZE))))
 
-FDT_OFFSET	:= 0x08000000
-
 if XEN
 XEN		:= -DXEN=$(XEN_IMAGE)
-XEN_OFFSET	:= 0x08200000
+XEN_OFFSET	:= $(shell echo $$(($(FDT_OFFSET) + 0x00200000)))
 KERNEL_SIZE	:= $(shell stat -Lc %s $(KERNEL_IMAGE) 2>/dev/null || echo 0)
 DOM0_OFFSET	:= $(shell echo $$(($(PHYS_OFFSET) + $(KERNEL_OFFSET))))
 XEN_CHOSEN	:= xen,xen-bootargs = \"$(XEN_CMDLINE)\";		\
diff --git a/scripts/AA64Image.pm b/scripts/AA64Image.pm
index 8c441ec..3b22be6 100755
--- a/scripts/AA64Image.pm
+++ b/scripts/AA64Image.pm
@@ -84,4 +84,11 @@ sub get_load_offset
 	return $min + $offset;
 }
 
+sub get_size
+{
+	my $self = shift;
+
+	return  $self->{image_size};
+}
+
 1;
diff --git a/scripts/aa64-fdt-offset.pl b/scripts/aa64-fdt-offset.pl
new file mode 100644
index 0000000..a10f2a4
--- /dev/null
+++ b/scripts/aa64-fdt-offset.pl
@@ -0,0 +1,39 @@
+#!/usr/bin/perl -w
+# Find the FDT offset of an AArch64 Linux Image
+#
+# Usage: ./$0 <Image> <kernel-offset> <fallback-offset>
+#
+# Copyright (C) 2025 ARM Limited. All rights reserved.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE.txt file.
+
+use warnings;
+use strict;
+
+use AA64Image;
+
+sub align{
+    my ($offset, $alignment) = @_;
+
+    return ($offset + $alignment - 1) & ~($alignment - 1);
+}
+
+my $filename = shift;
+die("No filename provided") unless defined($filename);
+
+my $kernel_offset = shift;
+$kernel_offset = oct($kernel_offset) if $kernel_offset =~ /^0/;
+
+my $fallback = shift;
+$fallback = oct($fallback) if $fallback =~ /^0/;
+
+open (my $fh, "<:raw", $filename) or die("Unable to open file '$filename'");
+
+my $image = AA64Image->parse($fh) or die("Unable to parse Image");
+
+my $image_size = $image->get_size();
+
+my $fdt_offset = ($image_size == 0) ? $fallback : align($image_size + $kernel_offset, 0x200000);
+
+printf("0x%08x\n", $fdt_offset);
-- 
2.34.1




More information about the linux-arm-kernel mailing list