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