[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