Re: Commit 1b7898ee276b "powerpc/boot: Use the pre-boot decompression API" breaks boot
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: 2016-10-08 22:14:11
Subsystem:
linux for powerpc (32-bit and 64-bit), the rest · Maintainers:
Madhavan Srinivasan, Linus Torvalds
Am 07.10.2016 um 21:26 schrieb Heiner Kallweit:
Am 07.10.2016 um 07:51 schrieb Oliver O'Halloran:quoted
Hi, Heiner Could you send me a copy of the kernel .config (or which defconfig) that you're using, the name of the HW platform that you're using and if possible the kernel image itself? Thanks, OliverThanks for the quick reply. Attached are .config and cuImage. HW is a TP-Link TL-WDR4900 WiFi router (P1014-based) running OpenWRT. Rgds, Heiner
After further checking I think I found the issue. The old gunzip code handled uncompressed data transparently whilst the new one bails out if it doesn't find a proper gzip header. And in my case the actual kernel image is uncompressed. With the following patch the system boots fine again (at least for me). Rgds, Heiner
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index f7a184b..9796491 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c@@ -32,9 +32,16 @@ static struct addr_range prep_kernel(void) void *addr = 0; struct elf_info ei; long len; + int uncompressed_image = 0; - partial_decompress(vmlinuz_addr, vmlinuz_size, + len = partial_decompress(vmlinuz_addr, vmlinuz_size, elfheader, sizeof(elfheader), 0); + /* assume uncompressed data if -1 is returned */ + if (len == -1) { + uncompressed_image = 1; + memcpy(elfheader, vmlinuz_addr, sizeof(elfheader)); + printf("No valid compressed data found, assume uncompressed data\n\r"); + } if (!parse_elf64(elfheader, &ei) && !parse_elf32(elfheader, &ei)) fatal("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
@@ -67,6 +74,12 @@ static struct addr_range prep_kernel(void) "device tree\n\r"); } + if (uncompressed_image) { + memcpy(addr, vmlinuz_addr + ei.elfoffset, ei.loadsize); + printf("%ld bytes of uncompressed data copied\n\r", ei.loadsize); + goto out; + } + /* Finally, decompress the kernel */ printf("Decompressing (0x%p <- 0x%p:0x%p)...\n\r", addr, vmlinuz_addr, vmlinuz_addr+vmlinuz_size);
@@ -82,7 +95,7 @@ static struct addr_range prep_kernel(void) len, ei.loadsize); printf("Done! Decompressed 0x%lx bytes\n\r", len); - +out: flush_cache(addr, ei.loadsize); return (struct addr_range){addr, ei.memsize};
--
2.10.0