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