#928643 u-boot-sunsi: Allow u-boot-install-sunxi64 on GPT with up to 4 entries

Package:
u-boot-sunxi
Source:
u-boot
Submitter:
Domenico Andreoli
Date:
2025-09-02 22:41:01 UTC
Severity:
wishlist
Tags:
#928643#5
Date:
2019-05-08 07:34:24 UTC
From:
To:
Hi,

  Salsa MR #6 adds support for GPT partition tables with up to 4 entries
to u-boot-install-sunxi64.

Regards,
Domenico

#928643#10
Date:
2023-12-03 11:19:38 UTC
From:
To:

Hi Domenico and Vagrant,

I was interested in this idea so I found the patch on salsa:
--- a/debian/bin/u-boot-install-sunxi64 +++ b/debian/bin/u-boot-install-sunxi64 @@ -69,11 +69,22 @@ if [ -z "$FORCE" ]; then exit 1 fi - # But, on sunxi64, spl will trample upon GPT. + # But, on sunxi64, spl will trample upon GPT (except when the number of entries is <= 4) printf "EFI PART" >gpt-sign if cmp -s -i 0:512 -n 8 gpt-sign "$DEV"; then - echo >&2 "$0: device/image ($DEV) uses GPT partition table, unusable on sunxi64" - exit 1 + GPT_OK=false + for GPT_ENTRIES in `seq 4`; do + # Need printf from coreutils so to correctly handle zero bytes + /usr/bin/printf '%b' "\0$GPT_ENTRIES\0\0\0" >gpt-entries + if cmp -s -i 0:592 -n 4 gpt-entries "$DEV"; then + GPT_OK=true + break + fi + done + if ! $GPT_OK; then + echo >&2 "$0: device/image ($DEV) uses GPT partition table with more than 4 entries, unusable on sunxi64" + exit 1 + fi fi fi I think that as long as the partition entry size is the standard 128 bytes it's OK to have up to 56 entries, because the total size of MBR + GPT header + GPT entries still doesn't exceed 8K. u-boot-install-sunxi does already work with such a GPT if the user specifies the -f option. But it would be good if the script could support a standard-sized GPT, and a possible way is suggested by this note in doc/board/allwinner/sunxi.rst: The traditional SD card location the Allwinner BootROM loads from is 8KB (sector 16). This works fine with the old MBR partitioning scheme, which most SD cards come formatted with. However this is in the middle of a potential GPT partition table, which will become invalid in this step. Newer SoCs (starting with the H3 from late 2014) also support booting from 128KB, which is beyond even a GPT and thus a safer location. So perhaps there could be a new command-line option that made dd write to 128K instead of 8K, and the error message upon detecting a GPT could suggest using that option. I've suggested a simple patch below. (It assumes that the GPT doesn't extend beyond 128K.) Best wishes, Harold.
--- a/debian/bin/u-boot-install-sunxi +++ b/debian/bin/u-boot-install-sunxi @@ -53,14 +53,22 @@ if [ -z "$TARGET" ] && [ -f "${dtmodel}" ]; then esac fi +wroff="8K" +while [ -n "$1" ]; do case "$1" in + -a|--alt-offset) + wroff="128K" + shift;; -f|--force) FORCE=y shift;; -*) echo >&2 "$0: unknown option '$1'" exit 1;; + *) + break;; esac +done DEV="$1" if [ -z "$DEV" ] || ! shift || [ -n "$*" ]; then @@ -87,9 +95,10 @@ if [ -z "$FORCE" ]; then exit 1 fi - # But, on sunxi64, spl will trample upon GPT. - if printf 'EFI PART' | cmp -s -i 0:512 -n 8 - "$DEV"; then - echo >&2 "$0: device/image ($DEV) uses GPT partition table, unusable on sunxi64" + # But writing at offset 8K will trample upon GPT. + if [ "$wroff" = "8K" ] && printf 'EFI PART' | cmp -s -i 0:512 -n 8 - "$DEV"; then + echo >&2 "$0: device/image ($DEV) uses GUID partition table" + echo >&2 "$0: Use -a to install at alternative offset" exit 1 fi fi @@ -100,5 +109,5 @@ if [ ! -f "$imfile" ]; then exit 1 fi
#928643#17
Date:
2025-08-28 12:40:21 UTC
From:
To:
Hi all,

I discovered the GPT vs U-Boot overlapping issue while using the Debian
installer because the default disk label (partition table) type defined
in partman-partitioning is GPT on EFI or arm64 platforms.
I intend to submit patches against partman-partitioning to set MSDOS as
default if GPT would overwrite U-Boot, but it would be nice if
u-boot-install-sunxi could use the GPT-friendly alternate boot location
on platforms which support it.

Right, but the partition entry array offset and even the partition entry
size are defined in the GPT header and may vary. A safe non-overlapping
requirement check should be:

(u-boot offset >= partition entry array offset + (partition entry size *
partition entry count)) or (partition array offset >= U-Boot offset +
image size)

True with H3, A64, H5 and H6 but H616 (and maybe other SOCs) set the
alternate boot location at 256KiB instead of 128KiB. I do not see any
image for this SoC in u-boot-sunxi packages though.

Or/and maybe the offset could be automatically selected based on the SoC
model ?

#928643#24
Date:
2025-09-01 02:51:12 UTC
From:
To:
Hi Pascal,

Thanks for your interest in this issue.

Yes exactly; if u-boot-install-sunxi had gained an "--alt-offset" feature I would have suggested using it to regenerate the sunxi arm64 installer images with U-Boot positioned at 128K rather than at 8K. As you've described on #1112448, currently the installer doesn't always produce a bootable system.

You're right but I think u-boot-install-sunxi is only meant to be a simple convenience wrapper around dd, with some basic sanity checks. That earlier comment of mine was just to question the choice of 4 as an upper limit.

Ah I didn't know the H616 was different. So yes, automatically selecting a suitable offset seems a better way to go; a revised patch is below.

Thanks for your suggestions,
Harold.

diff --git a/debian/bin/u-boot-install-sunxi b/debian/bin/u-boot-install-sunxi
index fca4ddc436..8b2a5cb667 100755
--- a/debian/bin/u-boot-install-sunxi
+++ b/debian/bin/u-boot-install-sunxi
@@ -79,6 +79,31 @@ if [ ! -w "$DEV" ] && [ -z "$FORCE" ]; then
     exit 1
 fi

+board=$(basename "$TARGET")
+echo >&2 "Selected board: ${board}"
+
+# Select write offset based on board
+case "$board" in
+	# H2+ or H3 SoC
+	"nanopi_neo" | "nanopi_neo_air" | "orangepi_pc_plus" | "orangepi_plus" | "orangepi_zero" )
+		wroff="128K" ;;
+	# A64, H5 or H6 SoC
+	"a64-olinuxino" | "a64-olinuxino-emmc" | "nanopi_neo2" | "nanopi_neo_plus2" |\
+	"orangepi_one_plus" | "orangepi_zero_plus2" | "pine64-lts" | "pine64_plus" |\
+	"pinebook" | "pinephone" | "pinetab" | "sopine_baseboard" | "teres_i" )
+		wroff="128K" ;;
+	# Older SoC
+	*)
+		wroff="8K" ;;
+esac
+echo >&2 "Selected offset: ${wroff}"
+
+# Warn about boot priority
+if [ "$wroff" != "8K" ] && printf 'eGON.BT0' | cmp -s -i 0:8196 -n 8 - "$DEV"; then
+	echo >&2 "WARNING: device/image ($DEV) has boot program"
+	echo >&2 "         at offset 8K which might take priority"
+fi
+
 if [ -z "$FORCE" ]; then
     # A very simple sanity check.  GPT mandates a "protective MBR" so this works
     # even with GPT partitioning.
@@ -87,9 +112,9 @@ if [ -z "$FORCE" ]; then
        exit 1
     fi

-    # But, on sunxi64, spl will trample upon GPT.
-    if printf 'EFI PART' | cmp -s -i 0:512 -n 8 - "$DEV"; then
-       echo >&2 "$0: device/image ($DEV) uses GPT partition table, unusable on sunxi64"
+    # But writing at offset 8K will trample upon GPT.
+    if [ "$wroff" = "8K" ] && printf 'EFI PART' | cmp -s -i 0:512 -n 8 - "$DEV"; then
+       echo >&2 "$0: device/image ($DEV) uses GUID partition table, would overwrite it"
        exit 1
     fi
 fi
@@ -100,5 +125,5 @@ if [ ! -f "$imfile" ]; then
     exit 1
 fi

#928643#29
Date:
2025-09-01 20:57:04 UTC
From:
To:
Glad to see you are still interested in this.

Note that debian-installer uses u-boot-install-sunxi to build SD card
images only for arm64 platforms, not armhf ones.

Looks good to me. Can you open a merge request in salsa ? Domenico's
original one was closed. Just one comment:

Is warning enough ? If a boot loader is present at offset 8KiB, its part
beyond offset 128KiB will be overwritten and boot will probably fail.
Shouldn't the magic number be deleted too ? Or maybe
u-boot-install-sunxi should require --force to proceed, or exit ?

#928643#34
Date:
2025-09-02 03:42:42 UTC
From:
To:
Hi Pascal, thanks for your quick reply.

OK. So we might want some adjustments to build/boot/arm/u-boot-image-config
in debian-installer as well.

I'd like to know Vagrant's opinion on this idea, but if he's happy with the
proposed patch then yes certainly I can make a merge request.

You're absolutely right. The user expects the newly-installed boot program
to become the active one. So yes the script should disable any boot program
at 8K when installing elsewhere. Thanks very much for questioning that.

Please see the revised patch below.

Best wishes,
Harold.

diff --git a/debian/bin/u-boot-install-sunxi b/debian/bin/u-boot-install-sunxi
index fca4ddc436..32748ee646 100755
--- a/debian/bin/u-boot-install-sunxi
+++ b/debian/bin/u-boot-install-sunxi
@@ -79,6 +79,32 @@ if [ ! -w "$DEV" ] && [ -z "$FORCE" ]; then
     exit 1
 fi

+board=$(basename "$TARGET")
+echo >&2 "Selected board: ${board}"
+
+# Select write offset based on board
+case "$board" in
+	# H2+ or H3 SoC
+	"nanopi_neo" | "nanopi_neo_air" | "orangepi_pc_plus" | "orangepi_plus" | "orangepi_zero" )
+		wroff="128K" ;;
+	# A64, H5 or H6 SoC
+	"a64-olinuxino" | "a64-olinuxino-emmc" | "nanopi_neo2" | "nanopi_neo_plus2" |\
+	"orangepi_one_plus" | "orangepi_zero_plus2" | "pine64-lts" | "pine64_plus" |\
+	"pinebook" | "pinephone" | "pinetab" | "sopine_baseboard" | "teres_i" )
+		wroff="128K" ;;
+	# Older SoC
+	*)
+		wroff="8K" ;;
+esac
+echo >&2 "Selected offset: ${wroff}"
+
+# Check for any other boot program that would take precedence
+disable8k="n"
+if [ "$wroff" != "8K" ] && printf 'eGON.BT0' | cmp -s -i 0:8196 -n 8 - "$DEV"; then
+	echo >&2 "Found boot program in ${DEV} at offset 8K, needs disabling"
+	disable8k="y"
+fi
+
 if [ -z "$FORCE" ]; then
     # A very simple sanity check.  GPT mandates a "protective MBR" so this works
     # even with GPT partitioning.
@@ -87,10 +113,12 @@ if [ -z "$FORCE" ]; then
        exit 1
     fi

-    # But, on sunxi64, spl will trample upon GPT.
-    if printf 'EFI PART' | cmp -s -i 0:512 -n 8 - "$DEV"; then
-       echo >&2 "$0: device/image ($DEV) uses GPT partition table, unusable on sunxi64"
-       exit 1
+    # But writing at offset 8K will trample upon GPT.
+    if [ "$wroff" = "8K" ] || [ "$disable8k" = "y" ]; then
+        if printf 'EFI PART' | cmp -s -i 0:512 -n 8 - "$DEV"; then
+            echo >&2 "$0: device/image ($DEV) uses GUID partition table, would overwrite it"
+            exit 1
+        fi
     fi
 fi

@@ -100,5 +128,10 @@ if [ ! -f "$imfile" ]; then
     exit 1
 fi

#928643#39
Date:
2025-09-02 22:38:20 UTC
From:
To:
(...)

Should the combination of GPT + boot loader found at offset 8KiB really
be a blocker here ? I see two cases:
- GPT and boot loader overlap (e.g. standard GPT), the primary GPT is
invalid, partitioning tools would rewrite it from the backup GPT and
overwrite the boot loader.
- GPT and boot loader do not overlap (non-standard GPT, e.g. partition
entries <= 56 or primary GPT at offset ~1MiB).
So IMO 'eGON.BT0' can safely be deleted in both cases.