[PATCH] uboot-lantiq: danube: fix hanging lzma kernel uncompression

Daniel Schwierzeck daniel.schwierzeck at gmail.com
Wed Nov 3 06:25:01 PDT 2021


Am Dienstag, dem 02.11.2021 um 23:35 +0100 schrieb Mathias Kresin:
> At least since gcc 7.3.0 (OpenWrt 18.06) lwr/lwl are used in the
> assembly  of LzmaProps_Decode. The instructions are using unaligned
> access, which locks up danube boards using memory mapped NOR flash.
> 
> It isn't clear whether it is a limitation of the flash chip or a
> limitation of the EBU.
> 
> Moving the pointer to the next int position and accessing accessing
> just
> the first byte, let gcc use sll instead of lwr/lwl and prevents the
> unaligned access.
> 
> Signed-off-by: Mathias Kresin <dev at kresin.me>
> ---
>  .../0030-lzma-fix-unaligned-access.patch      | 32
> +++++++++++++++++++
>  1 file changed, 32 insertions(+)
>  create mode 100644 package/boot/uboot-lantiq/patches/0030-lzma-fix-
> unaligned-access.patch
> 
> diff --git a/package/boot/uboot-lantiq/patches/0030-lzma-fix-
> unaligned-access.patch b/package/boot/uboot-lantiq/patches/0030-lzma-
> fix-unaligned-access.patch
> new file mode 100644
> index 0000000000..de9afe0bf5
> --- /dev/null
> +++ b/package/boot/uboot-lantiq/patches/0030-lzma-fix-unaligned-
> access.patch
> @@ -0,0 +1,32 @@
> +From a335c4c0532cf0d09b31e73f8461d3b4d0ce6f9a Mon Sep 17 00:00:00
> 2001
> +From: Mathias Kresin <dev at kresin.me>
> +Date: Sun, 31 Oct 2021 23:04:54 +0100
> +Subject: [PATCH] lzma: fix unaligned access
> +
> +At least since gcc 7.3.0 (OpenWrt 18.06) lwr/lwl are used in the
> +assembly  of LzmaProps_Decode. The instructions are using unaligned
> +access, which locks up danube boards using memory mapped NOR flash.
> +
> +It isn't clear whether it is a limitation of the flash chip or a
> +limitation of the EBU.

I think the problem is not the unaligned access but the 32bit read
operation. The internal EBU data bus has a 16 bit width and can access
8bit or 16bit flash devices. So 8bit read operations at odd addresses
shouldn't be a problem. I'm not sure what happens exactly at 32bit
reads but this maybe involves multiple reads from flash and also some
internal endianess swapping.

Maybe a more robust solution would be to use readb(data[n] to always
force 8bit reads.

> +
> +Moving the pointer to the next int position and accessing accessing
> just
> +the first byte, let gcc use sll instead of lwr/lwl and prevents the
> +unaligned access.
> +
> +Signed-off-by: Mathias Kresin <dev at kresin.me>
> +---
> + lib/lzma/LzmaDec.c | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +--- a/lib/lzma/LzmaDec.c
> ++++ b/lib/lzma/LzmaDec.c
> +@@ -929,7 +929,7 @@ SRes LzmaProps_Decode(CLzmaProps *p, con
> +   if (size < LZMA_PROPS_SIZE)
> +     return SZ_ERROR_UNSUPPORTED;
> +   else
> +-    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3]
> << 16) | ((UInt32)data[4] << 24);
> ++    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3]
> << 16) | ((UInt32)(data+1)[0] << 24);
> + 
> +   if (dicSize < LZMA_DIC_MIN)
> +     dicSize = LZMA_DIC_MIN;
-- 
- Daniel




More information about the openwrt-devel mailing list