1
2
3
4
5
6
7
8
9
10
11#include "gzip.h"
12#include "lzw.h"
13
14#include <linux/segment.h>
15
16
17
18
19
20struct screen_info {
21 unsigned char orig_x;
22 unsigned char orig_y;
23 unsigned char unused1[2];
24 unsigned short orig_video_page;
25 unsigned char orig_video_mode;
26 unsigned char orig_video_cols;
27 unsigned short orig_video_ega_ax;
28 unsigned short orig_video_ega_bx;
29 unsigned short orig_video_ega_cx;
30 unsigned char orig_video_lines;
31};
32
33
34
35
36#define EXT_MEM_K (*(unsigned short *)0x90002)
37#define DRIVE_INFO (*(struct drive_info *)0x90080)
38#define SCREEN_INFO (*(struct screen_info *)0x90000)
39#define RAMDISK_SIZE (*(unsigned short *)0x901F8)
40#define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
41#define AUX_DEVICE_INFO (*(unsigned char *)0x901FF)
42
43#define EOF -1
44
45DECLARE(uch, inbuf, INBUFSIZ);
46DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);
47DECLARE(uch, window, WSIZE);
48
49unsigned outcnt;
50unsigned insize;
51unsigned inptr;
52
53extern char input_data[];
54extern int input_len;
55
56int input_ptr;
57
58int method, exit_code, part_nb, last_member;
59int test = 0;
60int force = 0;
61int verbose = 1;
62long bytes_in, bytes_out;
63
64char *output_data;
65unsigned long output_ptr;
66
67extern int end;
68long free_mem_ptr = (long)&end;
69
70int to_stdout = 0;
71int hard_math = 0;
72
73void (*work)(int inf, int outf);
74void makecrc(void);
75
76local int get_method(int);
77
78char *vidmem = (char *)0xb8000;
79int lines, cols;
80
81void *malloc(int size)
82{
83 void *p;
84
85 if (size <0) error("Malloc error\n");
86 if (free_mem_ptr <= 0) error("Memory error\n");
87
88 free_mem_ptr = (free_mem_ptr + 3) & ~3;
89
90 p = (void *)free_mem_ptr;
91
92 free_mem_ptr += size;
93
94 if (free_mem_ptr > 0x90000) error("\nOut of memory\n");
95
96 if (p == NULL) error("malloc = NULL\n");
97 return p;
98}
99
100void free(void *where)
101{
102}
103
104static void scroll()
105{
106 int i;
107
108 memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
109 for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
110 vidmem[i] = ' ';
111}
112
113static void puts(char *s)
114{
115 int x,y;
116 char c;
117
118 x = SCREEN_INFO.orig_x;
119 y = SCREEN_INFO.orig_y;
120
121 while ( ( c = *s++ ) != '\0' ) {
122 if ( c == '\n' ) {
123 x = 0;
124 if ( ++y >= lines ) {
125 scroll();
126 y--;
127 }
128 } else {
129 vidmem [ ( x + cols * y ) * 2 ] = c;
130 if ( ++x >= cols ) {
131 x = 0;
132 if ( ++y >= lines ) {
133 scroll();
134 y--;
135 }
136 }
137 }
138 }
139
140 SCREEN_INFO.orig_x = x;
141 SCREEN_INFO.orig_y = y;
142}
143
144__ptr_t memset(__ptr_t s, int c, size_t n)
145{
146 int i;
147 char *ss = (char*)s;
148
149 for (i=0;i<n;i++) ss[i] = c;
150}
151
152__ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
153 size_t __n)
154{
155 int i;
156 char *d = (char *)__dest, *s = (char *)__src;
157
158 for (i=0;i<__n;i++) d[i] = s[i];
159}
160
161extern ulg crc_32_tab[];
162
163
164
165
166
167
168ulg updcrc(s, n)
169 uch *s;
170 unsigned n;
171{
172 register ulg c;
173
174 static ulg crc = (ulg)0xffffffffL;
175
176 if (s == NULL) {
177 c = 0xffffffffL;
178 } else {
179 c = crc;
180 while (n--) {
181 c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
182 }
183 }
184 crc = c;
185 return c ^ 0xffffffffL;
186}
187
188
189
190
191void clear_bufs()
192{
193 outcnt = 0;
194 insize = inptr = 0;
195 bytes_in = bytes_out = 0L;
196}
197
198
199
200
201
202int fill_inbuf()
203{
204 int len, i;
205
206
207 insize = 0;
208 do {
209 len = INBUFSIZ-insize;
210 if (len > (input_len-input_ptr+1)) len=input_len-input_ptr+1;
211 if (len == 0 || len == EOF) break;
212
213 for (i=0;i<len;i++) inbuf[insize+i] = input_data[input_ptr+i];
214 insize += len;
215 input_ptr += len;
216 } while (insize < INBUFSIZ);
217
218 if (insize == 0) {
219 error("unable to fill buffer\n");
220 }
221 bytes_in += (ulg)insize;
222 inptr = 1;
223 return inbuf[0];
224}
225
226
227
228
229
230void flush_window()
231{
232 if (outcnt == 0) return;
233 updcrc(window, outcnt);
234
235 memcpy(&output_data[output_ptr], (char *)window, outcnt);
236
237 bytes_out += (ulg)outcnt;
238 output_ptr += (ulg)outcnt;
239 outcnt = 0;
240}
241
242
243
244
245
246
247ulg crc_32_tab[256];
248
249void
250makecrc(void)
251{
252
253
254 unsigned long c;
255 unsigned long e;
256 int i;
257 int k;
258
259
260 static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
261
262
263 e = 0;
264 for (i = 0; i < sizeof(p)/sizeof(int); i++)
265 e |= 1L << (31 - p[i]);
266
267 crc_32_tab[0] = 0;
268
269 for (i = 1; i < 256; i++)
270 {
271 c = 0;
272 for (k = i | 256; k != 1; k >>= 1)
273 {
274 c = c & 1 ? (c >> 1) ^ e : c >> 1;
275 if (k & 1)
276 c ^= e;
277 }
278 crc_32_tab[i] = c;
279 }
280}
281
282void error(char *x)
283{
284 puts("\n\n");
285 puts(x);
286 puts("\n\n -- System halted");
287
288 while(1);
289}
290
291#define STACK_SIZE (4096)
292
293long user_stack [STACK_SIZE];
294
295struct {
296 long * a;
297 short b;
298 } stack_start = { & user_stack [STACK_SIZE] , KERNEL_DS };
299
300void decompress_kernel()
301{
302 if (SCREEN_INFO.orig_video_mode == 7)
303 vidmem = (char *) 0xb0000;
304 else
305 vidmem = (char *) 0xb8000;
306
307 lines = SCREEN_INFO.orig_video_lines;
308 cols = SCREEN_INFO.orig_video_cols;
309
310 if (EXT_MEM_K < 1024) error("<2M of mem\n");
311
312 output_data = (char *)1048576;
313 output_ptr = 0;
314
315 exit_code = 0;
316 test = 0;
317 input_ptr = 0;
318 part_nb = 0;
319
320 clear_bufs();
321 makecrc();
322
323 puts("Uncompressing Linux...");
324
325 method = get_method(0);
326
327 work(0, 0);
328
329 puts("done.\n");
330
331 puts("Now booting the kernel\n");
332}
333
334
335
336
337
338
339
340
341
342
343
344local int get_method(in)
345 int in;
346{
347 uch flags;
348 char magic[2];
349
350 magic[0] = (char)get_byte();
351 magic[1] = (char)get_byte();
352
353 method = -1;
354 part_nb++;
355 last_member = 0;
356
357
358 if (memcmp(magic, GZIP_MAGIC, 2) == 0
359 || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
360
361 work = unzip;
362 method = (int)get_byte();
363 flags = (uch)get_byte();
364 if ((flags & ENCRYPTED) != 0) {
365 error("Input is encrypted\n");
366 exit_code = ERROR;
367 return -1;
368 }
369 if ((flags & CONTINUATION) != 0) {
370 error("Multi part input\n");
371 exit_code = ERROR;
372 if (force <= 1) return -1;
373 }
374 if ((flags & RESERVED) != 0) {
375 error("Input has invalid flags\n");
376 exit_code = ERROR;
377 if (force <= 1) return -1;
378 }
379 (ulg)get_byte();
380 ((ulg)get_byte()) << 8;
381 ((ulg)get_byte()) << 16;
382 ((ulg)get_byte()) << 24;
383
384 (void)get_byte();
385 (void)get_byte();
386
387 if ((flags & CONTINUATION) != 0) {
388 unsigned part = (unsigned)get_byte();
389 part |= ((unsigned)get_byte())<<8;
390 if (verbose) {
391 error("Input is not part number 1\n");
392 }
393 }
394 if ((flags & EXTRA_FIELD) != 0) {
395 unsigned len = (unsigned)get_byte();
396 len |= ((unsigned)get_byte())<<8;
397 while (len--) (void)get_byte();
398 }
399
400
401 if ((flags & ORIG_NAME) != 0) {
402 if (to_stdout || part_nb > 1) {
403
404 while (get_byte() != 0) ;
405 } else {
406 }
407 }
408
409
410 if ((flags & COMMENT) != 0) {
411 while (get_byte() != 0) ;
412 }
413
414 } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2
415 && memcmp(inbuf, PKZIP_MAGIC, 4) == 0) {
416
417
418
419 inptr = 0;
420 work = unzip;
421 if (check_zipfile(in) == -1) return -1;
422
423 last_member = 1;
424
425 } else if (memcmp(magic, PACK_MAGIC, 2) == 0) {
426 error("packed input");
427 } else if (memcmp(magic, LZW_MAGIC, 2) == 0) {
428 error("compressed input");
429 last_member = 1;
430 }
431 if (method == -1) {
432 error("Corrupted input\n");
433 if (exit_code != ERROR) exit_code = part_nb == 1 ? ERROR : WARNING;
434 return part_nb == 1 ? -1 : -2;
435 }
436 return method;
437}
438