summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/head-inflate-data.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-16 21:50:35 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-16 21:50:35 +0100
commit441692aafc1731087bbaf657a8b6059d95c2a6df (patch)
tree9d3dd6d6e882bc9bb69e3389715b720ee9001ead /arch/arm/kernel/head-inflate-data.c
parentMerge tag 'powerpc-4.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/p... (diff)
parentMerge branch 'devel-stable' into for-next (diff)
downloadlinux-441692aafc1731087bbaf657a8b6059d95c2a6df.tar.xz
linux-441692aafc1731087bbaf657a8b6059d95c2a6df.zip
Merge branch 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM updates from Russell King: - add support for ELF fdpic binaries on both MMU and noMMU platforms - linker script cleanups - support for compressed .data section for XIP images - discard memblock arrays when possible - various cleanups - atomic DMA pool updates - better diagnostics of missing/corrupt device tree - export information to allow userspace kexec tool to place images more inteligently, so that the device tree isn't overwritten by the booting kernel - make early_printk more efficient on semihosted systems - noMMU cleanups - SA1111 PCMCIA update in preparation for further cleanups * 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm: (38 commits) ARM: 8719/1: NOMMU: work around maybe-uninitialized warning ARM: 8717/2: debug printch/printascii: translate '\n' to "\r\n" not "\n\r" ARM: 8713/1: NOMMU: Support MPU in XIP configuration ARM: 8712/1: NOMMU: Use more MPU regions to cover memory ARM: 8711/1: V7M: Add support for MPU to M-class ARM: 8710/1: Kconfig: Kill CONFIG_VECTORS_BASE ARM: 8709/1: NOMMU: Disallow MPU for XIP ARM: 8708/1: NOMMU: Rework MPU to be mostly done in C ARM: 8707/1: NOMMU: Update MPU accessors to use cp15 helpers ARM: 8706/1: NOMMU: Move out MPU setup in separate module ARM: 8702/1: head-common.S: Clear lr before jumping to start_kernel() ARM: 8705/1: early_printk: use printascii() rather than printch() ARM: 8703/1: debug.S: move hexbuf to a writable section ARM: add additional table to compressed kernel ARM: decompressor: fix BSS size calculation pcmcia: sa1111: remove special sa1111 mmio accessors pcmcia: sa1111: use sa1111_get_irq() to obtain IRQ resources ARM: better diagnostics with missing/corrupt dtb ARM: 8699/1: dma-mapping: Remove init_dma_coherent_pool_size() ARM: 8698/1: dma-mapping: Mark atomic_pool as __ro_after_init ..
Diffstat (limited to 'arch/arm/kernel/head-inflate-data.c')
-rw-r--r--arch/arm/kernel/head-inflate-data.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/arch/arm/kernel/head-inflate-data.c b/arch/arm/kernel/head-inflate-data.c
new file mode 100644
index 000000000000..6dd0ce5e6058
--- /dev/null
+++ b/arch/arm/kernel/head-inflate-data.c
@@ -0,0 +1,62 @@
+/*
+ * XIP kernel .data segment decompressor
+ *
+ * Created by: Nicolas Pitre, August 2017
+ * Copyright: (C) 2017 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/zutil.h>
+
+/* for struct inflate_state */
+#include "../../../lib/zlib_inflate/inftrees.h"
+#include "../../../lib/zlib_inflate/inflate.h"
+#include "../../../lib/zlib_inflate/infutil.h"
+
+extern char __data_loc[];
+extern char _edata_loc[];
+extern char _sdata[];
+
+/*
+ * This code is called very early during the boot process to decompress
+ * the .data segment stored compressed in ROM. Therefore none of the global
+ * variables are valid yet, hence no kernel services such as memory
+ * allocation is available. Everything must be allocated on the stack and
+ * we must avoid any global data access. We use a temporary stack located
+ * in the .bss area. The linker script makes sure the .bss is big enough
+ * to hold our stack frame plus some room for called functions.
+ *
+ * We mimic the code in lib/decompress_inflate.c to use the smallest work
+ * area possible. And because everything is statically allocated on the
+ * stack then there is no need to clean up before returning.
+ */
+
+int __init __inflate_kernel_data(void)
+{
+ struct z_stream_s stream, *strm = &stream;
+ struct inflate_state state;
+ char *in = __data_loc;
+ int rc;
+
+ /* Check and skip gzip header (assume no filename) */
+ if (in[0] != 0x1f || in[1] != 0x8b || in[2] != 0x08 || in[3] & ~3)
+ return -1;
+ in += 10;
+
+ strm->workspace = &state;
+ strm->next_in = in;
+ strm->avail_in = _edata_loc - __data_loc; /* upper bound */
+ strm->next_out = _sdata;
+ strm->avail_out = _edata_loc - __data_loc;
+ zlib_inflateInit2(strm, -MAX_WBITS);
+ WS(strm)->inflate_state.wsize = 0;
+ WS(strm)->inflate_state.window = NULL;
+ rc = zlib_inflate(strm, Z_FINISH);
+ if (rc == Z_OK || rc == Z_STREAM_END)
+ rc = strm->avail_out; /* should be 0 */
+ return rc;
+}