- Package:
- u-boot-sunxi
- Source:
- u-boot
- Submitter:
- Domenico Andreoli
- Date:
- 2025-09-02 22:41:01 UTC
- Severity:
- wishlist
- Tags:
Hi, Salsa MR #6 adds support for GPT partition tables with up to 4 entries to u-boot-install-sunxi64. Regards, Domenico
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
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 ?
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
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 ?
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
(...) 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.