// SPDX-License-Identifier: GPL-2.0-only // SPDX-FileCopyrightText: 2010-2013 Sascha Hauer , Pengutronix // SPDX-FileCopyrightText: 2012 Jean-Christophe PLAGNIOL-VILLARD /* uncompress.c - uncompressor code for self extracing pbl image */ #define pr_fmt(fmt) "uncompress.c: " fmt #include #include #include #include #include #include #include #include #include #include "entry.h" unsigned long free_mem_ptr; unsigned long free_mem_end_ptr; extern unsigned char input_data[]; extern unsigned char input_data_end[]; void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize, void *fdt) { uint32_t pg_len, uncompressed_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); unsigned long endmem = membase + memsize; unsigned long barebox_base; void *pg_start, *pg_end; unsigned long pc = get_pc(); pg_start = input_data + get_runtime_offset(); pg_end = input_data_end + get_runtime_offset(); /* * If we run from inside the memory just relocate the binary * to the current address. Otherwise it may be a readonly location. * Copy and relocate to the start of the memory in this case. */ if (pc > membase && pc - membase < memsize) relocate_to_current_adr(); else relocate_to_adr(membase); pg_len = pg_end - pg_start; uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4)); barebox_base = riscv_mem_barebox_image(membase, endmem, uncompressed_len + MAX_BSS_SIZE); setup_c(); pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize); free_mem_ptr = riscv_mem_early_malloc(membase, endmem); free_mem_end_ptr = riscv_mem_early_malloc_end(membase, endmem); pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx (uncompressed size: 0x%08x)\n", pg_start, pg_len, barebox_base, uncompressed_len); pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); barebox = (void *)barebox_base; pr_debug("jumping to uncompressed image at 0x%p. dtb=0x%p\n", barebox, fdt); barebox(membase, memsize, fdt); }