The GPT partition entry array is sized in bytes by the spec, so the number of blocks it takes up depends on the block size of the device. U-Boot got that wrong in gpt_fill_header(), which reserved a fixed 34 blocks at each end of the disk. On a device with 4096-byte native sectors, such as UFS flash, the backup entry array ended up 28 blocks short of the backup GPT header instead of immediately before it, and roughly 114 KiB was wasted at each end of the disk.
Patch 1 calculates the count from the block size and makes the four places that need it share one helper, since they disagreed with each other in different ways. Note that it also changes the 512-byte layout for boards that do not use the default entry count: CONFIG_EFI_PARTITION_ENTRIES_NUMBERS is "default 56 if ARCH_SUNXI" and is set to 64 by a number of Rockchip defconfigs, and on those first_usable_lba moves from 34 to 16 and 18 respectively. Existing tables stay readable, since the entry array is always located from the on-disk partition_entry_lba, and only newly written tables are affected. Partitions given without an explicit start= will be placed lower, though, and on sunxi first_usable_lba lands exactly on the 8 KiB SPL offset, so sunxi and Rockchip folks may want to look at patch 1 specifically (none of the devices I have override the default). Patch 2 has grown since v1. It started as a big-endian correctness fix noticed while auditing the file, and once the new test in patch 4 could drive a real block device on a big-endian target it turned up two more problems in the same family, both of which make a table written on big-endian useless. Patch 3 from v1 was dropped in favor of outright removal of the old MAC partition label support, as suggested by Heinrich (already in next). Patches 3 and 4 add the C tests, which are complementary rather than alternatives. Patch 3 drives gpt_fill_header()/gpt_fill_pte() with a synthetic descriptor, which is the only practical way to sweep block sizes from 512 to 32768, but it can never reach anything that touches the medium. Patch 5 backs a blkmap device with plain memory and does a full write/verify/parse round trip, covering set_protective_mbr(), is_pmbr_valid(), gpt_verify_headers(), is_gpt_valid() and part_get_info_efi(). Both live in the lib suite rather than test/dm/, because UT_DM depends on SANDBOX and test/dm/part.c is built for sandbox only, whereas test/lib/ is built for every board with CONFIG_UNIT_TEST. Patch 5 enables EFI_PARTITION and BLKMAP on malta64 so both tests are actually built and run on a big-endian target. malta64 already sets CONFIG_UNIT_TEST and already runs the full pytest suite in CI as the qemu_malta64 job, and ut subtests are collected from u-boot.sym, so no CI change is needed. malta64 rather than malta because hdr_start/pte_start in gpt_fill_pte() are size_t: on a 32-bit big-endian target an unconverted __le64 truncates to zero and the overlap check still happens to reject an overlap, while on MIPS64 it does not. Patches 6 and 7 add the sandbox-side python test. Patch 6 is a prerequisite: test_gpt_write_part_type() never binds its own disk image and has only worked because an earlier test left host 0 bound, so it breaks as soon as a test binding a different image is added above it. One known gap: test_gpt_write and test_gpt_write_part_type hardcode the 128-entry 512-byte layout, so they fail if sandbox is configured with a different CONFIG_EFI_PARTITION_ENTRIES_NUMBERS. The new tests derive their expectations instead, and pass at 56 and 64 entries. No sandbox defconfig upstream uses anything but 128, so I have left the old tests alone. Still not covered: gpt_verify_partitions() and friends now have big-endian coverage against a device U-Boot wrote itself, but nothing checks that U-Boot parses a spec-conformant table produced by someone else on big-endian. That needs a real disk image attached to the QEMU target, which means teaching u-boot-test-hooks to pass one and, for the 4Kn case, using virtio-blk rather than IDE, since drivers/block/ide.c hardcodes ATA_BLOCKSIZE. I am happy to look at that separately if it is wanted. Tested by building sandbox (default, flattree, sandbox64, spl, vpl, gcc and clang), generic-rk3576, sonoff-ihost-rv1126, A20-OLinuXino_MICRO-eMMC, turris_mox, boston64r2, qemu-ppce500 and all four malta variants, with no new warnings on any commit of the series, and by running the full sandbox pytest suite plus 'ut lib' on malta64 under qemu-system-mips64. CI passes all green: https://git.u-boot-project.org/u-boot/contributors/alchark/u-boot/-/pipelines/1326 Signed-off-by: Alexey Charkov <[email protected]> --- Changes in v2: - Rebased onto next - Patch 1: reword the commit message only. The entry array is sized from num_partition_entries and sizeof_partition_entry rather than a fixed 128-byte entry, and the two counts that could disagree are now named. No code change. - Patch 2: also convert the protective MBR fields and the GPT partition names, and fix print_efiname() to match. Both were found by running the new patch 4 test on big-endian, and both make a table written on big-endian unreadable. Dropped the v1 Reviewed-by tags from this patch, since it grew three hunks nobody has seen. - Patch 3 (old): superseded by the removal of part_mac - Patch 3: moved out of test/dm/part.c into test/lib/, so it is built and run on boards other than sandbox. - Patch 4 is new: a GPT write/verify/parse round trip against a memory-backed blkmap device, which covers the paths a synthetic descriptor cannot reach. - Patch 5 is new: enable EFI_PARTITION and BLKMAP on malta64 so both C tests run on a big-endian target in CI. - Patch 6: unbind the 4096-byte device at the end of the new test, so it does not leak into whatever runs next. - Link to v1: https://patch.msgid.link/[email protected] To: [email protected] To: Patrice Chotard <[email protected]> To: Patrick Delaunay <[email protected]> Cc: Tom Rini <[email protected]> Cc: Alexey Charkov <[email protected]> Cc: Ilias Apalodimas <[email protected]> Cc: Denis Mukhin <[email protected]> Cc: Simon Glass <[email protected]> Cc: Paul Burton <[email protected]> Cc: Heinrich Schuchardt <[email protected]> --- Alexey Charkov (7): disk: part_efi: Size the partition entry array from the block size disk: part_efi: Add missing endianness conversions test: lib: Check the GPT layout for large sector sizes test: lib: Check the GPT round trip against a real block device configs: malta64: Enable EFI_PARTITION and BLKMAP for big-endian tests test: py: gpt: Bind the disk image in test_gpt_write_part_type() test: py: gpt: Test the GPT layout on a device with 4096-byte blocks configs/malta64_defconfig | 2 + disk/part_efi.c | 66 ++++++++---- test/lib/Makefile | 1 + test/lib/part_efi.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++ test/py/tests/test_gpt.py | 120 ++++++++++++++++++++++ 5 files changed, 425 insertions(+), 21 deletions(-) --- base-commit: b8e0086b585791a771416ce51b58ce0097bc0b28 change-id: 20260731-gpt-4k-f8b9e3fad474 Best regards, -- Alexey Charkov <[email protected]>
