1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * misc.c |
4 | * |
5 | * This is a collection of several routines from gzip-1.0.3 |
6 | * adapted for Linux. |
7 | * |
8 | * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 |
9 | * |
10 | * Modified for ARM Linux by Russell King |
11 | * |
12 | * Nicolas Pitre <nico@visuaide.com> 1999/04/14 : |
13 | * For this code to run directly from Flash, all constant variables must |
14 | * be marked with 'const' and all other variables initialized at run-time |
15 | * only. This way all non constant variables will end up in the bss segment, |
16 | * which should point to addresses in RAM and cleared to 0 on start. |
17 | * This allows for a much quicker boot time. |
18 | * |
19 | * Modified for Alpha, from the ARM version, by Jay Estabrook 2003. |
20 | */ |
21 | |
22 | #include <linux/kernel.h> |
23 | #include <linux/slab.h> |
24 | |
25 | #include <linux/uaccess.h> |
26 | |
27 | #define memzero(s,n) memset ((s),0,(n)) |
28 | #define puts srm_printk |
29 | extern long srm_printk(const char *, ...) |
30 | __attribute__ ((format (printf, 1, 2))); |
31 | |
32 | /* |
33 | * gzip declarations |
34 | */ |
35 | #define OF(args) args |
36 | #define STATIC static |
37 | |
38 | typedef unsigned char uch; |
39 | typedef unsigned short ush; |
40 | typedef unsigned long ulg; |
41 | |
42 | #define WSIZE 0x8000 /* Window size must be at least 32k, */ |
43 | /* and a power of two */ |
44 | |
45 | static uch *inbuf; /* input buffer */ |
46 | static uch *window; /* Sliding window buffer */ |
47 | |
48 | static unsigned insize; /* valid bytes in inbuf */ |
49 | static unsigned inptr; /* index of next byte to be processed in inbuf */ |
50 | static unsigned outcnt; /* bytes in output buffer */ |
51 | |
52 | /* gzip flag byte */ |
53 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ |
54 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ |
55 | #define 0x04 /* bit 2 set: extra field present */ |
56 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ |
57 | #define 0x10 /* bit 4 set: file comment present */ |
58 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ |
59 | #define RESERVED 0xC0 /* bit 6,7: reserved */ |
60 | |
61 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) |
62 | |
63 | /* Diagnostic functions */ |
64 | #ifdef DEBUG |
65 | # define Assert(cond,msg) {if(!(cond)) error(msg);} |
66 | # define Trace(x) fprintf x |
67 | # define Tracev(x) {if (verbose) fprintf x ;} |
68 | # define Tracevv(x) {if (verbose>1) fprintf x ;} |
69 | # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} |
70 | # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} |
71 | #else |
72 | # define Assert(cond,msg) |
73 | # define Trace(x) |
74 | # define Tracev(x) |
75 | # define Tracevv(x) |
76 | # define Tracec(c,x) |
77 | # define Tracecv(c,x) |
78 | #endif |
79 | |
80 | static int fill_inbuf(void); |
81 | static void flush_window(void); |
82 | static void error(char *m); |
83 | |
84 | static char *input_data; |
85 | static int input_data_size; |
86 | |
87 | static uch *output_data; |
88 | static ulg output_ptr; |
89 | static ulg bytes_out; |
90 | |
91 | static void error(char *m); |
92 | |
93 | extern int end; |
94 | static ulg free_mem_ptr; |
95 | static ulg free_mem_end_ptr; |
96 | |
97 | #define HEAP_SIZE 0x3000 |
98 | |
99 | #include "../../../lib/inflate.c" |
100 | |
101 | /* =========================================================================== |
102 | * Fill the input buffer. This is called only when the buffer is empty |
103 | * and at least one byte is really needed. |
104 | */ |
105 | int fill_inbuf(void) |
106 | { |
107 | if (insize != 0) |
108 | error(m: "ran out of input data" ); |
109 | |
110 | inbuf = input_data; |
111 | insize = input_data_size; |
112 | |
113 | inptr = 1; |
114 | return inbuf[0]; |
115 | } |
116 | |
117 | /* =========================================================================== |
118 | * Write the output window window[0..outcnt-1] and update crc and bytes_out. |
119 | * (Used for the decompressed data only.) |
120 | */ |
121 | void flush_window(void) |
122 | { |
123 | ulg c = crc; |
124 | unsigned n; |
125 | uch *in, *out, ch; |
126 | |
127 | in = window; |
128 | out = &output_data[output_ptr]; |
129 | for (n = 0; n < outcnt; n++) { |
130 | ch = *out++ = *in++; |
131 | c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); |
132 | } |
133 | crc = c; |
134 | bytes_out += (ulg)outcnt; |
135 | output_ptr += (ulg)outcnt; |
136 | outcnt = 0; |
137 | /* puts("."); */ |
138 | } |
139 | |
140 | static void error(char *x) |
141 | { |
142 | puts("\n\n" ); |
143 | puts(x); |
144 | puts("\n\n -- System halted" ); |
145 | |
146 | while(1); /* Halt */ |
147 | } |
148 | |
149 | unsigned int |
150 | decompress_kernel(void *output_start, |
151 | void *input_start, |
152 | size_t ksize, |
153 | size_t kzsize) |
154 | { |
155 | output_data = (uch *)output_start; |
156 | input_data = (uch *)input_start; |
157 | input_data_size = kzsize; /* use compressed size */ |
158 | |
159 | /* FIXME FIXME FIXME */ |
160 | free_mem_ptr = (ulg)output_start + ksize; |
161 | free_mem_end_ptr = (ulg)output_start + ksize + 0x200000; |
162 | /* FIXME FIXME FIXME */ |
163 | |
164 | /* put in temp area to reduce initial footprint */ |
165 | window = malloc(WSIZE); |
166 | |
167 | makecrc(); |
168 | /* puts("Uncompressing Linux..."); */ |
169 | gunzip(); |
170 | /* puts(" done, booting the kernel.\n"); */ |
171 | return output_ptr; |
172 | } |
173 | |