* [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt
@ 2025-11-19 19:32 Marek Vasut
2025-11-19 19:32 ` [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses Marek Vasut
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Marek Vasut @ 2025-11-19 19:32 UTC (permalink / raw)
To: u-boot
Cc: Marek Vasut, Aaron Kling, Eddie Kovsky, George Chan,
Julien Masson, Mattijs Korpershoek, Nicolas Belin, Sam Day,
Simon Glass, Tom Rini
Newer versions of libfdt strictly check whether the FDT blob
passed to them is at 8-byte aligned offset, if it is not, then
the library fails checks with -FDT_ERR_ALIGNMENT . Currently,
android_image_print_dtb_contents() passed FDT directly mapped
from abootimg to libfdt, and this FDT is not always aligned to
8-byte offset. Specifically, the FDTs are somewhat packed in
the abootimg, therefore if the first FDT blob is e.g. 0xfd bytes
long, then the next FDT blob ends up at 0xfd offset, which is
not 8-byte aligned.
Fix this by first extracting the header into 8-byte aligned buffer,
checking only the header for validity, and then by copying the
entire FDT into newly allocated 8-byte aligned buffer. While this
is not efficient, it is the correct way to handle DTs, which must
be at 8-byte aligned offsets. Mitigate the inefficiency for the
common case by checking whether the DT might be 8-byte aligned and
if it is, map it directly.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Aaron Kling <webgeek1234@gmail.com>
Cc: Eddie Kovsky <ekovsky@redhat.com>
Cc: George Chan <gchan9527@gmail.com>
Cc: Julien Masson <jmasson@baylibre.com>
Cc: Mattijs Korpershoek <mkorpershoek@kernel.org>
Cc: Nicolas Belin <nbelin@baylibre.com>
Cc: Sam Day <me@samcday.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Tom Rini <trini@konsulko.com>
Cc: u-boot@lists.denx.de
---
V2: - Turn the two conditionals into single conditional
- Use IS_ALIGNED()
V3: - Flip the IS_ALIGNED() conditional to check the right thing
---
boot/image-android.c | 42 +++++++++++++++++++++++++++++++-----------
1 file changed, 31 insertions(+), 11 deletions(-)
diff --git a/boot/image-android.c b/boot/image-android.c
index e46dee0d9b3..ea47869a64c 100644
--- a/boot/image-android.c
+++ b/boot/image-android.c
@@ -721,17 +721,19 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img,
dtb_addr = dtb_img_addr;
while (dtb_addr < dtb_img_addr + dtb_img_size) {
const struct fdt_header *fdt;
+ struct fdt_header fdth __aligned(8);
u32 dtb_size;
fdt = map_sysmem(dtb_addr, sizeof(*fdt));
- if (fdt_check_header(fdt) != 0) {
- unmap_sysmem(fdt);
+ memcpy(&fdth, fdt, sizeof(*fdt));
+ unmap_sysmem(fdt);
+
+ if (fdt_check_header(&fdth) != 0) {
printf("Error: Invalid FDT header for index %u\n", i);
return false;
}
- dtb_size = fdt_totalsize(fdt);
- unmap_sysmem(fdt);
+ dtb_size = fdt_totalsize(&fdth);
if (i == index) {
if (size)
@@ -885,23 +887,41 @@ bool android_image_print_dtb_contents(ulong hdr_addr)
dtb_addr = dtb_img_addr;
while (dtb_addr < dtb_img_addr + dtb_img_size) {
const struct fdt_header *fdt;
+ struct fdt_header *fulldt;
+ struct fdt_header fdth __aligned(8);
u32 dtb_size;
fdt = map_sysmem(dtb_addr, sizeof(*fdt));
- if (fdt_check_header(fdt) != 0) {
- unmap_sysmem(fdt);
+ memcpy(&fdth, fdt, sizeof(*fdt));
+ unmap_sysmem(fdt);
+
+ if (fdt_check_header(&fdth) != 0) {
printf("Error: Invalid FDT header for index %u\n", i);
return false;
}
- res = android_image_print_dtb_info(fdt, i);
- if (!res) {
+ dtb_size = fdt_totalsize(&fdth);
+
+ /* The device tree must be at an 8-byte aligned address */
+ if (!IS_ALIGNED((uintptr_t)fdt, 8)) {
+ fulldt = memalign(8, dtb_size);
+ if (!fulldt)
+ return false;
+
+ fdt = map_sysmem(dtb_addr, dtb_size);
+ memcpy(fulldt, fdt, dtb_size);
unmap_sysmem(fdt);
- return false;
+ res = android_image_print_dtb_info(fulldt, i);
+ free(fulldt);
+ } else {
+ fulldt = map_sysmem(dtb_addr, dtb_size);
+ res = android_image_print_dtb_info(fulldt, i);
+ unmap_sysmem(fulldt);
}
- dtb_size = fdt_totalsize(fdt);
- unmap_sysmem(fdt);
+ if (!res)
+ return false;
+
dtb_addr += dtb_size;
++i;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses
2025-11-19 19:32 [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Marek Vasut
@ 2025-11-19 19:32 ` Marek Vasut
2025-11-20 9:39 ` Mattijs Korpershoek
2025-11-19 19:39 ` [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Tom Rini
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Marek Vasut @ 2025-11-19 19:32 UTC (permalink / raw)
To: u-boot
Cc: Marek Vasut, Aaron Kling, Eddie Kovsky, George Chan,
Julien Masson, Mattijs Korpershoek, Nicolas Belin, Sam Day,
Simon Glass, Tom Rini
Newer versions of libfdt strictly check whether the FDT blob
passed to them is at 8-byte aligned offset, if it is not, then
the library fails checks with -FDT_ERR_ALIGNMENT . Currently,
'abootimg get dtb --index=1 addr size' may return non 8-byte
aligned FDT address which points directly into the abootimg.
Copy the result into temporary location before validation to
avoid FDT alignment check failure.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Aaron Kling <webgeek1234@gmail.com>
Cc: Eddie Kovsky <ekovsky@redhat.com>
Cc: George Chan <gchan9527@gmail.com>
Cc: Julien Masson <jmasson@baylibre.com>
Cc: Mattijs Korpershoek <mkorpershoek@kernel.org>
Cc: Nicolas Belin <nbelin@baylibre.com>
Cc: Sam Day <me@samcday.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Tom Rini <trini@konsulko.com>
Cc: u-boot@lists.denx.de
---
V2: No change
V3: No change
---
test/py/tests/test_android/test_abootimg.py | 28 ++++++++++++++++-----
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/test/py/tests/test_android/test_abootimg.py b/test/py/tests/test_android/test_abootimg.py
index 2aadb692b30..daa87643e93 100644
--- a/test/py/tests/test_android/test_abootimg.py
+++ b/test/py/tests/test_android/test_abootimg.py
@@ -93,10 +93,16 @@ dtb_dump_resp="""## DTB area contents (concat format):
loadaddr = 0x1000
# Address in RAM where to load the vendor boot image ('abootimg' looks in $vloadaddr)
vloadaddr= 0x10000
+# Expected DTB #1 size
+dtb1_size = 0x7d
+# Expected DTB #2 size
+dtb2_size = 0x7d
# Expected DTB #1 offset from the boot image start address
-dtb1_offset = 0x187d
+dtb1_offset = 0x1800 + dtb1_size
# Expected DTB offset from the vendor boot image start address
-dtb2_offset = 0x207d
+dtb2_offset = 0x2000 + dtb2_size
+# Expected DTB aligned offset
+dtba_offset = 0x4000
# DTB #1 start address in RAM
dtb1_addr = loadaddr + dtb1_offset
# DTB #2 start address in RAM
@@ -214,11 +220,16 @@ def test_abootimg(abootimg_disk_image, ubman):
assert response == 'a=11f00000'
ubman.log.action('Testing \'abootimg get dtb --index\'...')
- ubman.run_command('abootimg get dtb --index=1 dtb1_start')
+ ubman.run_command('abootimg get dtb --index=1 dtb1_start dtb1_size')
response = ubman.run_command('env print dtb1_start')
correct_str = "dtb1_start=%x" % (dtb1_addr)
assert response == correct_str
- ubman.run_command('fdt addr $dtb1_start')
+ response = ubman.run_command('env print dtb1_size')
+ correct_str = "dtb1_size=%x" % (dtb1_size)
+ assert response == correct_str
+ ubman.run_command('setenv dtbaaddr 0x%x' % (dtba_offset))
+ ubman.run_command('cp.b $dtb1_start $dtbaaddr $dtb1_size')
+ ubman.run_command('fdt addr $dtbaaddr')
ubman.run_command('fdt get value v / model')
response = ubman.run_command('env print v')
assert response == 'v=x2'
@@ -257,12 +268,17 @@ def test_abootimgv4(abootimgv4_disk_image_vboot, abootimgv4_disk_image_boot, ubm
assert response == 'a=11f00000'
ubman.log.action('Testing \'abootimg get dtb --index\'...')
- ubman.run_command('abootimg get dtb --index=1 dtb2_start')
+ ubman.run_command('abootimg get dtb --index=1 dtb2_start dtb2_size')
response = ubman.run_command('env print dtb2_start')
correct_str = "dtb2_start=%x" % (dtb2_addr)
assert response == correct_str
+ response = ubman.run_command('env print dtb2_size')
+ correct_str = "dtb2_size=%x" % (dtb2_size)
+ assert response == correct_str
- ubman.run_command('fdt addr $dtb2_start')
+ ubman.run_command('setenv dtbaaddr 0x%x' % (dtba_offset))
+ ubman.run_command('cp.b $dtb2_start $dtbaaddr $dtb2_size')
+ ubman.run_command('fdt addr $dtbaaddr')
ubman.run_command('fdt get value v / model')
response = ubman.run_command('env print v')
assert response == 'v=x2'
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt
2025-11-19 19:32 [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Marek Vasut
2025-11-19 19:32 ` [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses Marek Vasut
@ 2025-11-19 19:39 ` Tom Rini
2025-11-20 9:38 ` Mattijs Korpershoek
2025-12-05 16:22 ` Mattijs Korpershoek
3 siblings, 0 replies; 6+ messages in thread
From: Tom Rini @ 2025-11-19 19:39 UTC (permalink / raw)
To: Marek Vasut
Cc: u-boot, Aaron Kling, Eddie Kovsky, George Chan, Julien Masson,
Mattijs Korpershoek, Nicolas Belin, Sam Day, Simon Glass
[-- Attachment #1: Type: text/plain, Size: 1504 bytes --]
On Wed, Nov 19, 2025 at 08:32:51PM +0100, Marek Vasut wrote:
> Newer versions of libfdt strictly check whether the FDT blob
> passed to them is at 8-byte aligned offset, if it is not, then
> the library fails checks with -FDT_ERR_ALIGNMENT . Currently,
> android_image_print_dtb_contents() passed FDT directly mapped
> from abootimg to libfdt, and this FDT is not always aligned to
> 8-byte offset. Specifically, the FDTs are somewhat packed in
> the abootimg, therefore if the first FDT blob is e.g. 0xfd bytes
> long, then the next FDT blob ends up at 0xfd offset, which is
> not 8-byte aligned.
>
> Fix this by first extracting the header into 8-byte aligned buffer,
> checking only the header for validity, and then by copying the
> entire FDT into newly allocated 8-byte aligned buffer. While this
> is not efficient, it is the correct way to handle DTs, which must
> be at 8-byte aligned offsets. Mitigate the inefficiency for the
> common case by checking whether the DT might be 8-byte aligned and
> if it is, map it directly.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Thanks for doing this. We had talked off-list and I looked at the code
in question more and while it would be nice to abstract those two
similar loops in those functions, they're ultimately both different
enough in usage and small enough that it wouldn't really be a win, to
pull that out to a function of its own.
Reviewed-by: Tom Rini <trini@konsulko.com>
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt
2025-11-19 19:32 [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Marek Vasut
2025-11-19 19:32 ` [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses Marek Vasut
2025-11-19 19:39 ` [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Tom Rini
@ 2025-11-20 9:38 ` Mattijs Korpershoek
2025-12-05 16:22 ` Mattijs Korpershoek
3 siblings, 0 replies; 6+ messages in thread
From: Mattijs Korpershoek @ 2025-11-20 9:38 UTC (permalink / raw)
To: Marek Vasut, u-boot
Cc: Marek Vasut, Aaron Kling, Eddie Kovsky, George Chan,
Julien Masson, Mattijs Korpershoek, Nicolas Belin, Sam Day,
Simon Glass, Tom Rini
Hi Marek,
Thank you for the patch.
On Wed, Nov 19, 2025 at 20:32, Marek Vasut <marek.vasut+renesas@mailbox.org> wrote:
> Newer versions of libfdt strictly check whether the FDT blob
> passed to them is at 8-byte aligned offset, if it is not, then
> the library fails checks with -FDT_ERR_ALIGNMENT . Currently,
> android_image_print_dtb_contents() passed FDT directly mapped
> from abootimg to libfdt, and this FDT is not always aligned to
> 8-byte offset. Specifically, the FDTs are somewhat packed in
> the abootimg, therefore if the first FDT blob is e.g. 0xfd bytes
> long, then the next FDT blob ends up at 0xfd offset, which is
> not 8-byte aligned.
>
> Fix this by first extracting the header into 8-byte aligned buffer,
> checking only the header for validity, and then by copying the
> entire FDT into newly allocated 8-byte aligned buffer. While this
> is not efficient, it is the correct way to handle DTs, which must
> be at 8-byte aligned offsets. Mitigate the inefficiency for the
> common case by checking whether the DT might be 8-byte aligned and
> if it is, map it directly.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@kernel.org>
> ---
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses
2025-11-19 19:32 ` [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses Marek Vasut
@ 2025-11-20 9:39 ` Mattijs Korpershoek
0 siblings, 0 replies; 6+ messages in thread
From: Mattijs Korpershoek @ 2025-11-20 9:39 UTC (permalink / raw)
To: Marek Vasut, u-boot
Cc: Marek Vasut, Aaron Kling, Eddie Kovsky, George Chan,
Julien Masson, Mattijs Korpershoek, Nicolas Belin, Sam Day,
Simon Glass, Tom Rini
Hi Marek,
Thank you for the patch.
On Wed, Nov 19, 2025 at 20:32, Marek Vasut <marek.vasut+renesas@mailbox.org> wrote:
> Newer versions of libfdt strictly check whether the FDT blob
> passed to them is at 8-byte aligned offset, if it is not, then
> the library fails checks with -FDT_ERR_ALIGNMENT . Currently,
> 'abootimg get dtb --index=1 addr size' may return non 8-byte
> aligned FDT address which points directly into the abootimg.
> Copy the result into temporary location before validation to
> avoid FDT alignment check failure.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@kernel.org>
> ---
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt
2025-11-19 19:32 [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Marek Vasut
` (2 preceding siblings ...)
2025-11-20 9:38 ` Mattijs Korpershoek
@ 2025-12-05 16:22 ` Mattijs Korpershoek
3 siblings, 0 replies; 6+ messages in thread
From: Mattijs Korpershoek @ 2025-12-05 16:22 UTC (permalink / raw)
To: u-boot, Marek Vasut
Cc: Aaron Kling, Eddie Kovsky, George Chan, Julien Masson,
Nicolas Belin, Sam Day, Simon Glass, Tom Rini
Hi,
On Wed, 19 Nov 2025 20:32:51 +0100, Marek Vasut wrote:
> Newer versions of libfdt strictly check whether the FDT blob
> passed to them is at 8-byte aligned offset, if it is not, then
> the library fails checks with -FDT_ERR_ALIGNMENT . Currently,
> android_image_print_dtb_contents() passed FDT directly mapped
> from abootimg to libfdt, and this FDT is not always aligned to
> 8-byte offset. Specifically, the FDTs are somewhat packed in
> the abootimg, therefore if the first FDT blob is e.g. 0xfd bytes
> long, then the next FDT blob ends up at 0xfd offset, which is
> not 8-byte aligned.
>
> [...]
Thanks, Applied to https://source.denx.de/u-boot/custodians/u-boot-dfu (u-boot-dfu-next)
[1/2] boot: android: Always use 8-byte aligned DT with libfdt
https://source.denx.de/u-boot/custodians/u-boot-dfu/-/commit/2da3af2f9ee0dbacaf26e95e1ae5261445f1a43c
[2/2] test/py: android: Point fdt command to aligned addresses
https://source.denx.de/u-boot/custodians/u-boot-dfu/-/commit/42ee514ed049d5e689e39bb4a8b6b5fb519aa3be
--
Mattijs
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-12-05 16:22 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-19 19:32 [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Marek Vasut
2025-11-19 19:32 ` [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses Marek Vasut
2025-11-20 9:39 ` Mattijs Korpershoek
2025-11-19 19:39 ` [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Tom Rini
2025-11-20 9:38 ` Mattijs Korpershoek
2025-12-05 16:22 ` Mattijs Korpershoek
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.