1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Definitions and wrapper functions for kernel decompressor |
4 | * |
5 | * Copyright IBM Corp. 2010 |
6 | * |
7 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> |
8 | */ |
9 | |
10 | #include <linux/kernel.h> |
11 | #include <linux/string.h> |
12 | #include <asm/page.h> |
13 | #include "decompressor.h" |
14 | #include "boot.h" |
15 | |
16 | /* |
17 | * gzip declarations |
18 | */ |
19 | #define STATIC static |
20 | |
21 | #undef memset |
22 | #undef memcpy |
23 | #undef memmove |
24 | #define memmove memmove |
25 | #define memzero(s, n) memset((s), 0, (n)) |
26 | |
27 | #if defined(CONFIG_KERNEL_BZIP2) |
28 | #define BOOT_HEAP_SIZE 0x400000 |
29 | #elif defined(CONFIG_KERNEL_ZSTD) |
30 | #define BOOT_HEAP_SIZE 0x30000 |
31 | #else |
32 | #define BOOT_HEAP_SIZE 0x10000 |
33 | #endif |
34 | |
35 | static unsigned long free_mem_ptr = (unsigned long) _end; |
36 | static unsigned long free_mem_end_ptr = (unsigned long) _end + BOOT_HEAP_SIZE; |
37 | |
38 | #ifdef CONFIG_KERNEL_GZIP |
39 | #include "../../../../lib/decompress_inflate.c" |
40 | #endif |
41 | |
42 | #ifdef CONFIG_KERNEL_BZIP2 |
43 | #include "../../../../lib/decompress_bunzip2.c" |
44 | #endif |
45 | |
46 | #ifdef CONFIG_KERNEL_LZ4 |
47 | #include "../../../../lib/decompress_unlz4.c" |
48 | #endif |
49 | |
50 | #ifdef CONFIG_KERNEL_LZMA |
51 | #include "../../../../lib/decompress_unlzma.c" |
52 | #endif |
53 | |
54 | #ifdef CONFIG_KERNEL_LZO |
55 | #include "../../../../lib/decompress_unlzo.c" |
56 | #endif |
57 | |
58 | #ifdef CONFIG_KERNEL_XZ |
59 | #include "../../../../lib/decompress_unxz.c" |
60 | #endif |
61 | |
62 | #ifdef CONFIG_KERNEL_ZSTD |
63 | #include "../../../../lib/decompress_unzstd.c" |
64 | #endif |
65 | |
66 | #define decompress_offset ALIGN((unsigned long)_end + BOOT_HEAP_SIZE, PAGE_SIZE) |
67 | |
68 | unsigned long mem_safe_offset(void) |
69 | { |
70 | /* |
71 | * due to 4MB HEAD_SIZE for bzip2 |
72 | * 'decompress_offset + vmlinux.image_size' could be larger than |
73 | * kernel at final position + its .bss, so take the larger of two |
74 | */ |
75 | return max(decompress_offset + vmlinux.image_size, |
76 | vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size); |
77 | } |
78 | |
79 | void *decompress_kernel(void) |
80 | { |
81 | void *output = (void *)decompress_offset; |
82 | |
83 | __decompress(buf: _compressed_start, len: _compressed_end - _compressed_start, |
84 | NULL, NULL, out_buf: output, vmlinux.image_size, NULL, error); |
85 | return output; |
86 | } |
87 | |