OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [i386/] [boot/] [compressed/] [misc.c] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * misc.c
3
 *
4
 * This is a collection of several routines from gzip-1.0.3
5
 * adapted for Linux.
6
 *
7
 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8
 * puts by Nick Holloway 1993, better puts by Martin Mares 1995
9
 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
10
 */
11
 
12
#include <asm/segment.h>
13
#include <asm/io.h>
14
#include <linux/types.h>
15
 
16
/*
17
 * gzip declarations
18
 */
19
 
20
#define OF(args)  args
21
#define STATIC static
22
 
23
void* memset(void* s, int c, size_t n);
24
void* memcpy(void* __dest, __const void* __src,
25
             size_t __n);
26
 
27
#define memzero(s, n)     memset ((s), 0, (n))
28
 
29
 
30
typedef unsigned char  uch;
31
typedef unsigned short ush;
32
typedef unsigned long  ulg;
33
 
34
#define WSIZE 0x8000            /* Window size must be at least 32k, */
35
                                /* and a power of two */
36
 
37
static uch *inbuf;           /* input buffer */
38
static uch window[WSIZE];    /* Sliding window buffer */
39
 
40
static unsigned insize = 0;  /* valid bytes in inbuf */
41
static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
42
static unsigned outcnt = 0;  /* bytes in output buffer */
43
 
44
/* gzip flag byte */
45
#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
46
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
47
#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
48
#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
49
#define COMMENT      0x10 /* bit 4 set: file comment present */
50
#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
51
#define RESERVED     0xC0 /* bit 6,7:   reserved */
52
 
53
#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
54
 
55
/* Diagnostic functions */
56
#ifdef DEBUG
57
#  define Assert(cond,msg) {if(!(cond)) error(msg);}
58
#  define Trace(x) fprintf x
59
#  define Tracev(x) {if (verbose) fprintf x ;}
60
#  define Tracevv(x) {if (verbose>1) fprintf x ;}
61
#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
62
#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
63
#else
64
#  define Assert(cond,msg)
65
#  define Trace(x)
66
#  define Tracev(x)
67
#  define Tracevv(x)
68
#  define Tracec(c,x)
69
#  define Tracecv(c,x)
70
#endif
71
 
72
static int  fill_inbuf(void);
73
static void flush_window(void);
74
static void error(char *m);
75
static void gzip_mark(void **);
76
static void gzip_release(void **);
77
 
78
/*
79
 * These are set up by the setup-routine at boot-time:
80
 */
81
 
82
struct screen_info {
83
        unsigned char  orig_x;
84
        unsigned char  orig_y;
85
        unsigned char  unused1[2];
86
        unsigned short orig_video_page;
87
        unsigned char  orig_video_mode;
88
        unsigned char  orig_video_cols;
89
        unsigned short unused2;
90
        unsigned short orig_video_ega_bx;
91
        unsigned short unused3;
92
        unsigned char  orig_video_lines;
93
        unsigned char  orig_video_isVGA;
94
};
95
 
96
/*
97
 * This is set up by the setup-routine at boot-time
98
 */
99
#define EXT_MEM_K (*(unsigned short *)0x90002)
100
#ifndef STANDARD_MEMORY_BIOS_CALL
101
#define ALT_MEM_K (*(unsigned long *) 0x901e0)
102
#endif
103
#define DRIVE_INFO (*(struct drive_info *)0x90080)
104
#define SCREEN_INFO (*(struct screen_info *)0x90000)
105
#define RAMDISK_SIZE (*(unsigned short *)0x901F8)
106
#define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
107
#define AUX_DEVICE_INFO (*(unsigned char *)0x901FF)
108
 
109
extern char input_data[];
110
extern int input_len;
111
 
112
static long bytes_out = 0;
113
static uch *output_data;
114
static unsigned long output_ptr = 0;
115
 
116
 
117
static void *malloc(int size);
118
static void free(void *where);
119
static void error(char *m);
120
static void gzip_mark(void **);
121
static void gzip_release(void **);
122
 
123
static void puts(const char *);
124
 
125
extern int end;
126
static long free_mem_ptr = (long)&end;
127
static long free_mem_end_ptr = 0x90000;
128
 
129
#define INPLACE_MOVE_ROUTINE  0x1000
130
#define LOW_BUFFER_START      0x2000
131
#define LOW_BUFFER_END       0x90000
132
#define LOW_BUFFER_SIZE      ( LOW_BUFFER_END - LOW_BUFFER_START )
133
#define HEAP_SIZE             0x2000
134
static int high_loaded =0;
135
static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/;
136
 
137
static char *vidmem = (char *)0xb8000;
138
static int vidport;
139
static int lines, cols;
140
 
141
#include "../../../../lib/inflate.c"
142
 
143
static void *malloc(int size)
144
{
145
        void *p;
146
 
147
        if (size <0) error("Malloc error\n");
148
        if (free_mem_ptr <= 0) error("Memory error\n");
149
 
150
        free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
151
 
152
        p = (void *)free_mem_ptr;
153
        free_mem_ptr += size;
154
 
155
        if (free_mem_ptr >= free_mem_end_ptr)
156
                error("\nOut of memory\n");
157
 
158
        return p;
159
}
160
 
161
static void free(void *where)
162
{       /* Don't care */
163
}
164
 
165
static void gzip_mark(void **ptr)
166
{
167
        *ptr = (void *) free_mem_ptr;
168
}
169
 
170
static void gzip_release(void **ptr)
171
{
172
        free_mem_ptr = (long) *ptr;
173
}
174
 
175
static void scroll()
176
{
177
        int i;
178
 
179
        memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
180
        for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
181
                vidmem[i] = ' ';
182
}
183
 
184
static void puts(const char *s)
185
{
186
        int x,y,pos;
187
        char c;
188
 
189
        x = SCREEN_INFO.orig_x;
190
        y = SCREEN_INFO.orig_y;
191
 
192
        while ( ( c = *s++ ) != '\0' ) {
193
                if ( c == '\n' ) {
194
                        x = 0;
195
                        if ( ++y >= lines ) {
196
                                scroll();
197
                                y--;
198
                        }
199
                } else {
200
                        vidmem [ ( x + cols * y ) * 2 ] = c;
201
                        if ( ++x >= cols ) {
202
                                x = 0;
203
                                if ( ++y >= lines ) {
204
                                        scroll();
205
                                        y--;
206
                                }
207
                        }
208
                }
209
        }
210
 
211
        SCREEN_INFO.orig_x = x;
212
        SCREEN_INFO.orig_y = y;
213
 
214
        pos = (x + cols * y) * 2;       /* Update cursor position */
215
        outb_p(14, vidport);
216
        outb_p(0xff & (pos >> 9), vidport+1);
217
        outb_p(15, vidport);
218
        outb_p(0xff & (pos >> 1), vidport+1);
219
}
220
 
221
void* memset(void* s, int c, size_t n)
222
{
223
        int i;
224
        char *ss = (char*)s;
225
 
226
        for (i=0;i<n;i++) ss[i] = c;
227
}
228
 
229
void* memcpy(void* __dest, __const void* __src,
230
                            size_t __n)
231
{
232
        int i;
233
        char *d = (char *)__dest, *s = (char *)__src;
234
 
235
        for (i=0;i<__n;i++) d[i] = s[i];
236
}
237
 
238
/* ===========================================================================
239
 * Fill the input buffer. This is called only when the buffer is empty
240
 * and at least one byte is really needed.
241
 */
242
static int fill_inbuf()
243
{
244
        if (insize != 0) {
245
                error("ran out of input data\n");
246
        }
247
 
248
        inbuf = input_data;
249
        insize = input_len;
250
        inptr = 1;
251
        return inbuf[0];
252
}
253
 
254
/* ===========================================================================
255
 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
256
 * (Used for the decompressed data only.)
257
 */
258
static void flush_window_low()
259
{
260
    ulg c = crc;         /* temporary variable */
261
    unsigned n;
262
    uch *in, *out, ch;
263
 
264
    in = window;
265
    out = &output_data[output_ptr];
266
    for (n = 0; n < outcnt; n++) {
267
            ch = *out++ = *in++;
268
            c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
269
    }
270
    crc = c;
271
    bytes_out += (ulg)outcnt;
272
    output_ptr += (ulg)outcnt;
273
    outcnt = 0;
274
}
275
 
276
static void flush_window_high()
277
{
278
    ulg c = crc;         /* temporary variable */
279
    unsigned n;
280
    uch *in,  ch;
281
    in = window;
282
    for (n = 0; n < outcnt; n++) {
283
        ch = *output_data++ = *in++;
284
        if ((ulg)output_data == LOW_BUFFER_END) output_data=high_buffer_start;
285
        c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
286
    }
287
    crc = c;
288
    bytes_out += (ulg)outcnt;
289
    outcnt = 0;
290
}
291
 
292
static void flush_window()
293
{
294
        if (high_loaded) flush_window_high();
295
        else flush_window_low();
296
}
297
 
298
static void error(char *x)
299
{
300
        puts("\n\n");
301
        puts(x);
302
        puts("\n\n -- System halted");
303
 
304
        while(1);       /* Halt */
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
 
317
void setup_normal_output_buffer()
318
{
319
#ifdef STANDARD_MEMORY_BIOS_CALL
320
        if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
321
#else
322
        if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
323
#endif
324
        output_data = (char *)0x100000; /* Points to 1M */
325
}
326
 
327
struct moveparams {
328
        uch *low_buffer_start;  int lcount;
329
        uch *high_buffer_start; int hcount;
330
};
331
 
332
void setup_output_buffer_if_we_run_high(struct moveparams *mv)
333
{
334
        high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
335
#ifdef STANDARD_MEMORY_BIOS_CALL
336
        if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
337
#else
338
        if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n");
339
#endif
340
        mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
341
        high_loaded = 1;
342
        free_mem_end_ptr = (long)high_buffer_start;
343
        if ( (0x100000 + LOW_BUFFER_SIZE) > ((ulg)high_buffer_start)) {
344
                high_buffer_start = (uch *)(0x100000 + LOW_BUFFER_SIZE);
345
                mv->hcount = 0; /* say: we need not to move high_buffer */
346
        }
347
        else mv->hcount = -1;
348
        mv->high_buffer_start = high_buffer_start;
349
}
350
 
351
void close_output_buffer_if_we_run_high(struct moveparams *mv)
352
{
353
        mv->lcount = bytes_out;
354
        if (bytes_out > LOW_BUFFER_SIZE) {
355
                mv->lcount = LOW_BUFFER_SIZE;
356
                if (mv->hcount) mv->hcount = bytes_out - LOW_BUFFER_SIZE;
357
        }
358
        else mv->hcount = 0;
359
}
360
 
361
 
362
int decompress_kernel(struct moveparams *mv)
363
{
364
        if (SCREEN_INFO.orig_video_mode == 7) {
365
                vidmem = (char *) 0xb0000;
366
                vidport = 0x3b4;
367
        } else {
368
                vidmem = (char *) 0xb8000;
369
                vidport = 0x3d4;
370
        }
371
 
372
        lines = SCREEN_INFO.orig_video_lines;
373
        cols = SCREEN_INFO.orig_video_cols;
374
 
375
        if (free_mem_ptr < 0x100000) setup_normal_output_buffer();
376
        else setup_output_buffer_if_we_run_high(mv);
377
 
378
        makecrc();
379
        puts("Uncompressing Linux...");
380
        gunzip();
381
        puts("done.\nNow booting the kernel\n");
382
        if (high_loaded) close_output_buffer_if_we_run_high(mv);
383
        return high_loaded;
384
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.