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