This source file includes following definitions.
- malloc
- free
- gzip_mark
- gzip_release
- scroll
- puts
- memset
- memcpy
- fill_inbuf
- flush_window_low
- flush_window_high
- flush_window
- error
- gzip_mark
- gzip_release
- main
- setup_normal_output_buffer
- setup_output_buffer_if_we_run_high
- close_output_buffer_if_we_run_high
- decompress_kernel
1
2
3
4
5
6
7
8
9
10
11
12 #include <string.h>
13
14 #include <asm/segment.h>
15 #include <asm/io.h>
16
17
18
19
20
21 #define OF(args) args
22 #define STATIC static
23
24 #define memzero(s, n) memset ((s), 0, (n))
25
26 typedef unsigned char uch;
27 typedef unsigned short ush;
28 typedef unsigned long ulg;
29
30 #define WSIZE 0x8000
31
32
33 static uch *inbuf;
34 static uch window[WSIZE];
35
36 static unsigned insize = 0;
37 static unsigned inptr = 0;
38 static unsigned outcnt = 0;
39
40
41 #define ASCII_FLAG 0x01
42 #define CONTINUATION 0x02
43 #define EXTRA_FIELD 0x04
44 #define ORIG_NAME 0x08
45 #define COMMENT 0x10
46 #define ENCRYPTED 0x20
47 #define RESERVED 0xC0
48
49 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
50
51
52 #ifdef DEBUG
53 # define Assert(cond,msg) {if(!(cond)) error(msg);}
54 # define Trace(x) fprintf x
55 # define Tracev(x) {if (verbose) fprintf x ;}
56 # define Tracevv(x) {if (verbose>1) fprintf x ;}
57 # define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
58 # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
59 #else
60 # define Assert(cond,msg)
61 # define Trace(x)
62 # define Tracev(x)
63 # define Tracevv(x)
64 # define Tracec(c,x)
65 # define Tracecv(c,x)
66 #endif
67
68 static int fill_inbuf(void);
69 static void flush_window(void);
70 static void error(char *m);
71 static void gzip_mark(void **);
72 static void gzip_release(void **);
73
74
75
76
77
78 struct screen_info {
79 unsigned char orig_x;
80 unsigned char orig_y;
81 unsigned char unused1[2];
82 unsigned short orig_video_page;
83 unsigned char orig_video_mode;
84 unsigned char orig_video_cols;
85 unsigned short unused2;
86 unsigned short orig_video_ega_bx;
87 unsigned short unused3;
88 unsigned char orig_video_lines;
89 unsigned char orig_video_isVGA;
90 };
91
92
93
94
95 #define EXT_MEM_K (*(unsigned short *)0x90002)
96 #define DRIVE_INFO (*(struct drive_info *)0x90080)
97 #define SCREEN_INFO (*(struct screen_info *)0x90000)
98 #define RAMDISK_SIZE (*(unsigned short *)0x901F8)
99 #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
100 #define AUX_DEVICE_INFO (*(unsigned char *)0x901FF)
101
102 extern char input_data[];
103 extern int input_len;
104
105 static long bytes_out = 0;
106 static uch *output_data;
107 static unsigned long output_ptr = 0;
108
109
110 static void *malloc(int size);
111 static void free(void *where);
112 static void error(char *m);
113 static void gzip_mark(void **);
114 static void gzip_release(void **);
115
116 #ifndef STANDALONE_DEBUG
117 static void puts(const char *);
118
119 extern int end;
120 static long free_mem_ptr = (long)&end;
121 static long free_mem_end_ptr = 0x90000;
122
123 #define INPLACE_MOVE_ROUTINE 0x1000
124 #define LOW_BUFFER_START 0x2000
125 #define LOW_BUFFER_END 0x90000
126 #define LOW_BUFFER_SIZE ( LOW_BUFFER_END - LOW_BUFFER_START )
127 #define HEAP_SIZE 0x2000
128 static int high_loaded =0;
129 static uch *high_buffer_start ;
130
131 static char *vidmem = (char *)0xb8000;
132 static int vidport;
133 static int lines, cols;
134
135 #include "../../../../lib/inflate.c"
136
137 static void *malloc(int size)
138 {
139 void *p;
140
141 if (size <0) error("Malloc error\n");
142 if (free_mem_ptr <= 0) error("Memory error\n");
143
144 free_mem_ptr = (free_mem_ptr + 3) & ~3;
145
146 p = (void *)free_mem_ptr;
147 free_mem_ptr += size;
148
149 if (free_mem_ptr >= free_mem_end_ptr)
150 error("\nOut of memory\n");
151
152 return p;
153 }
154
155 static void free(void *where)
156 {
157 }
158
159 static void gzip_mark(void **ptr)
160 {
161 *ptr = (void *) free_mem_ptr;
162 }
163
164 static void gzip_release(void **ptr)
165 {
166 free_mem_ptr = (long) *ptr;
167 }
168
169 static void scroll()
170 {
171 int i;
172
173 memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
174 for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
175 vidmem[i] = ' ';
176 }
177
178 static void puts(const char *s)
179 {
180 int x,y,pos;
181 char c;
182
183 x = SCREEN_INFO.orig_x;
184 y = SCREEN_INFO.orig_y;
185
186 while ( ( c = *s++ ) != '\0' ) {
187 if ( c == '\n' ) {
188 x = 0;
189 if ( ++y >= lines ) {
190 scroll();
191 y--;
192 }
193 } else {
194 vidmem [ ( x + cols * y ) * 2 ] = c;
195 if ( ++x >= cols ) {
196 x = 0;
197 if ( ++y >= lines ) {
198 scroll();
199 y--;
200 }
201 }
202 }
203 }
204
205 SCREEN_INFO.orig_x = x;
206 SCREEN_INFO.orig_y = y;
207
208 pos = (x + cols * y) * 2;
209 outb_p(14, vidport);
210 outb_p(0xff & (pos >> 9), vidport+1);
211 outb_p(15, vidport);
212 outb_p(0xff & (pos >> 1), vidport+1);
213 }
214
215 __ptr_t memset(__ptr_t s, int c, size_t n)
216 {
217 int i;
218 char *ss = (char*)s;
219
220 for (i=0;i<n;i++) ss[i] = c;
221 }
222
223 __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
224 size_t __n)
225 {
226 int i;
227 char *d = (char *)__dest, *s = (char *)__src;
228
229 for (i=0;i<__n;i++) d[i] = s[i];
230 }
231 #endif
232
233
234
235
236
237 static int fill_inbuf()
238 {
239 if (insize != 0) {
240 error("ran out of input data\n");
241 }
242
243 inbuf = input_data;
244 insize = input_len;
245 inptr = 1;
246 return inbuf[0];
247 }
248
249
250
251
252
253 static void flush_window_low()
254 {
255 ulg c = crc;
256 unsigned n;
257 uch *in, *out, ch;
258
259 in = window;
260 out = &output_data[output_ptr];
261 for (n = 0; n < outcnt; n++) {
262 ch = *out++ = *in++;
263 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
264 }
265 crc = c;
266 bytes_out += (ulg)outcnt;
267 output_ptr += (ulg)outcnt;
268 outcnt = 0;
269 }
270
271 static void flush_window_high()
272 {
273 ulg c = crc;
274 unsigned n;
275 uch *in, ch;
276 in = window;
277 for (n = 0; n < outcnt; n++) {
278 ch = *output_data++ = *in++;
279 if ((ulg)output_data == LOW_BUFFER_END) output_data=high_buffer_start;
280 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
281 }
282 crc = c;
283 bytes_out += (ulg)outcnt;
284 outcnt = 0;
285 }
286
287 static void flush_window()
288 {
289 if (high_loaded) flush_window_high();
290 else flush_window_low();
291 }
292
293 static void error(char *x)
294 {
295 puts("\n\n");
296 puts(x);
297 puts("\n\n -- System halted");
298
299 while(1);
300 }
301
302 #define STACK_SIZE (4096)
303
304 long user_stack [STACK_SIZE];
305
306 struct {
307 long * a;
308 short b;
309 } stack_start = { & user_stack [STACK_SIZE] , KERNEL_DS };
310
311 #ifdef STANDALONE_DEBUG
312
313 static void gzip_mark(void **ptr)
314 {
315 }
316
317 static void gzip_release(void **ptr)
318 {
319 }
320
321 char output_buffer[1024 * 800];
322
323 int
324 main(argc, argv)
325 int argc;
326 char **argv;
327 {
328 output_data = output_buffer;
329
330 makecrc();
331 puts("Uncompressing Linux...");
332 gunzip();
333 puts("done.\n");
334 return 0;
335 }
336
337 #else
338
339 void setup_normal_output_buffer()
340 {
341 if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
342 output_data = (char *)0x100000;
343 }
344
345 struct moveparams {
346 uch *low_buffer_start; int lcount;
347 uch *high_buffer_start; int hcount;
348 };
349
350 void setup_output_buffer_if_we_run_high(struct moveparams *mv)
351 {
352 high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
353 if (EXT_MEM_K < (4*1024)) error("Less than 4MB of memory.\n");
354 mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
355 high_loaded = 1;
356 free_mem_end_ptr = (long)high_buffer_start;
357 if ( (0x100000 + LOW_BUFFER_SIZE) > ((ulg)high_buffer_start)) {
358 high_buffer_start = (uch *)(0x100000 + LOW_BUFFER_SIZE);
359 mv->hcount = 0;
360 }
361 else mv->hcount = -1;
362 mv->high_buffer_start = high_buffer_start;
363 }
364
365 void close_output_buffer_if_we_run_high(struct moveparams *mv)
366 {
367 mv->lcount = bytes_out;
368 if (bytes_out > LOW_BUFFER_SIZE) {
369 mv->lcount = LOW_BUFFER_SIZE;
370 if (mv->hcount) mv->hcount = bytes_out - LOW_BUFFER_SIZE;
371 }
372 else mv->hcount = 0;
373 }
374
375
376 int decompress_kernel(struct moveparams *mv)
377 {
378 if (SCREEN_INFO.orig_video_mode == 7) {
379 vidmem = (char *) 0xb0000;
380 vidport = 0x3b4;
381 } else {
382 vidmem = (char *) 0xb8000;
383 vidport = 0x3d4;
384 }
385
386 lines = SCREEN_INFO.orig_video_lines;
387 cols = SCREEN_INFO.orig_video_cols;
388
389 if (free_mem_ptr < 0x100000) setup_normal_output_buffer();
390 else setup_output_buffer_if_we_run_high(mv);
391
392 makecrc();
393 puts("Uncompressing Linux...");
394 gunzip();
395 puts("done.\nNow booting the kernel\n");
396 if (high_loaded) close_output_buffer_if_we_run_high(mv);
397 return high_loaded;
398 }
399 #endif
400
401
402
403