powerpc/boot: Use the pre-boot decompression API

Currently the powerpc boot wrapper has its own wrapper around zlib to
handle decompressing gzipped kernels. The kernel decompressor library
functions now provide a generic interface that can be used in the
pre-boot environment. This allows boot wrappers to easily support
different compression algorithms. This patch converts the wrapper to use
this new API, but does not add support for using new algorithms.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
Oliver O'Halloran
2016-09-22 16:54:31 +10:00
committed by Michael Ellerman
parent 22750d98b0
commit 1b7898ee27
4 changed files with 190 additions and 25 deletions

View File

@@ -15,11 +15,8 @@
#include "string.h"
#include "stdio.h"
#include "ops.h"
#include "gunzip_util.h"
#include "reg.h"
static struct gunzip_state gzstate;
struct addr_range {
void *addr;
unsigned long size;
@@ -30,15 +27,14 @@ struct addr_range {
static struct addr_range prep_kernel(void)
{
char elfheader[256];
void *vmlinuz_addr = _vmlinux_start;
unsigned char *vmlinuz_addr = (unsigned char *)_vmlinux_start;
unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start;
void *addr = 0;
struct elf_info ei;
int len;
long len;
/* gunzip the ELF header of the kernel */
gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
partial_decompress(vmlinuz_addr, vmlinuz_size,
elfheader, sizeof(elfheader), 0);
if (!parse_elf64(elfheader, &ei) && !parse_elf32(elfheader, &ei))
fatal("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
@@ -51,7 +47,7 @@ static struct addr_range prep_kernel(void)
* the kernel bss must be claimed (it will be zero'd by the
* kernel itself)
*/
printf("Allocating 0x%lx bytes for kernel ...\n\r", ei.memsize);
printf("Allocating 0x%lx bytes for kernel...\n\r", ei.memsize);
if (platform_ops.vmlinux_alloc) {
addr = platform_ops.vmlinux_alloc(ei.memsize);
@@ -71,16 +67,21 @@ static struct addr_range prep_kernel(void)
"device tree\n\r");
}
/* Finally, gunzip the kernel */
printf("gunzipping (0x%p <- 0x%p:0x%p)...", addr,
/* Finally, decompress the kernel */
printf("Decompressing (0x%p <- 0x%p:0x%p)...\n\r", addr,
vmlinuz_addr, vmlinuz_addr+vmlinuz_size);
/* discard up to the actual load data */
gunzip_discard(&gzstate, ei.elfoffset - sizeof(elfheader));
len = gunzip_finish(&gzstate, addr, ei.loadsize);
len = partial_decompress(vmlinuz_addr, vmlinuz_size,
addr, ei.loadsize, ei.elfoffset);
if (len < 0)
fatal("Decompression failed with error code %ld\n\r", len);
if (len != ei.loadsize)
fatal("ran out of data! only got 0x%x of 0x%lx bytes.\n\r",
len, ei.loadsize);
printf("done 0x%x bytes\n\r", len);
fatal("Decompression error: got 0x%lx bytes, expected 0x%lx.\n\r",
len, ei.loadsize);
printf("Done! Decompressed 0x%lx bytes\n\r", len);
flush_cache(addr, ei.loadsize);