root/zBoot/misc.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. malloc
  2. free
  3. scroll
  4. puts
  5. memset
  6. memcpy
  7. updcrc
  8. clear_bufs
  9. fill_inbuf
  10. flush_window
  11. makecrc
  12. error
  13. decompress_kernel
  14. get_method

   1 /*
   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
   8  * puts by Nick Holloway 1993
   9  */
  10 
  11 #include "gzip.h"
  12 #include "lzw.h"
  13 
  14 #include <linux/segment.h>
  15 
  16 /*
  17  * These are set up by the setup-routine at boot-time:
  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  * This is set up by the setup-routine at boot-time
  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 void *malloc(int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  82 {
  83         void *p;
  84 
  85         if (size <0) error("Malloc error\n");
  86         if (free_mem_ptr <= 0) error("Memory error\n");
  87 
  88         free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
  89 
  90         p = (void *)free_mem_ptr;
  91 
  92         free_mem_ptr += size;
  93 
  94         if (free_mem_ptr > 0x90000) error("\nOut of memory\n");
  95 
  96         if (p == NULL) error("malloc = NULL\n");
  97         return p;
  98 }
  99 
 100 void free(void *where)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {       /* Don't care */
 102 }
 103 
 104 static void scroll()
     /* [previous][next][first][last][top][bottom][index][help] */
 105 {
 106         int i;
 107 
 108         memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
 109         for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
 110                 vidmem[i] = ' ';
 111 }
 112 
 113 static void puts(char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
 114 {
 115         int x,y;
 116         char c;
 117 
 118         x = SCREEN_INFO.orig_x;
 119         y = SCREEN_INFO.orig_y;
 120 
 121         while ( ( c = *s++ ) != '\0' ) {
 122                 if ( c == '\n' ) {
 123                         x = 0;
 124                         if ( ++y >= lines ) {
 125                                 scroll();
 126                                 y--;
 127                         }
 128                 } else {
 129                         vidmem [ ( x + cols * y ) * 2 ] = c; 
 130                         if ( ++x >= cols ) {
 131                                 x = 0;
 132                                 if ( ++y >= lines ) {
 133                                         scroll();
 134                                         y--;
 135                                 }
 136                         }
 137                 }
 138         }
 139 
 140         SCREEN_INFO.orig_x = x;
 141         SCREEN_INFO.orig_y = y;
 142 }
 143 
 144 __ptr_t memset(__ptr_t s, int c, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146         int i;
 147         char *ss = (char*)s;
 148 
 149         for (i=0;i<n;i++) ss[i] = c;
 150 }
 151 
 152 __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
     /* [previous][next][first][last][top][bottom][index][help] */
 153                             size_t __n)
 154 {
 155         int i;
 156         char *d = (char *)__dest, *s = (char *)__src;
 157 
 158         for (i=0;i<__n;i++) d[i] = s[i];
 159 }
 160 
 161 extern ulg crc_32_tab[];   /* crc table, defined below */
 162 
 163 /* ===========================================================================
 164  * Run a set of bytes through the crc shift register.  If s is a NULL
 165  * pointer, then initialize the crc shift register contents instead.
 166  * Return the current crc in either case.
 167  */
 168 ulg updcrc(s, n)
     /* [previous][next][first][last][top][bottom][index][help] */
 169     uch *s;                 /* pointer to bytes to pump through */
 170     unsigned n;             /* number of bytes in s[] */
 171 {
 172     register ulg c;         /* temporary variable */
 173 
 174     static ulg crc = (ulg)0xffffffffL; /* shift register contents */
 175 
 176     if (s == NULL) {
 177         c = 0xffffffffL;
 178     } else {
 179         c = crc;
 180         while (n--) {
 181             c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
 182         }
 183     }
 184     crc = c;
 185     return c ^ 0xffffffffL;       /* (instead of ~c for 64-bit machines) */
 186 }
 187 
 188 /* ===========================================================================
 189  * Clear input and output buffers
 190  */
 191 void clear_bufs()
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193     outcnt = 0;
 194     insize = inptr = 0;
 195     bytes_in = bytes_out = 0L;
 196 }
 197 
 198 /* ===========================================================================
 199  * Fill the input buffer. This is called only when the buffer is empty
 200  * and at least one byte is really needed.
 201  */
 202 int fill_inbuf()
     /* [previous][next][first][last][top][bottom][index][help] */
 203 {
 204     int len, i;
 205 
 206     /* Read as much as possible */
 207     insize = 0;
 208     do {
 209         len = INBUFSIZ-insize;
 210         if (len > (input_len-input_ptr+1)) len=input_len-input_ptr+1;
 211         if (len == 0 || len == EOF) break;
 212 
 213         for (i=0;i<len;i++) inbuf[insize+i] = input_data[input_ptr+i];
 214         insize += len;
 215         input_ptr += len;
 216     } while (insize < INBUFSIZ);
 217 
 218     if (insize == 0) {
 219         error("unable to fill buffer\n");
 220     }
 221     bytes_in += (ulg)insize;
 222     inptr = 1;
 223     return inbuf[0];
 224 }
 225 
 226 /* ===========================================================================
 227  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 228  * (Used for the decompressed data only.)
 229  */
 230 void flush_window()
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232     if (outcnt == 0) return;
 233     updcrc(window, outcnt);
 234 
 235     memcpy(&output_data[output_ptr], (char *)window, outcnt);
 236 
 237     bytes_out += (ulg)outcnt;
 238     output_ptr += (ulg)outcnt;
 239     outcnt = 0;
 240 }
 241 
 242 /*
 243  * Code to compute the CRC-32 table. Borrowed from 
 244  * gzip-1.0.3/makecrc.c.
 245  */
 246 
 247 ulg crc_32_tab[256];
 248 
 249 void
 250 makecrc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 251 {
 252 /* Not copyrighted 1990 Mark Adler      */
 253 
 254   unsigned long c;      /* crc shift register */
 255   unsigned long e;      /* polynomial exclusive-or pattern */
 256   int i;                /* counter for all possible eight bit values */
 257   int k;                /* byte being shifted into crc apparatus */
 258 
 259   /* terms of polynomial defining this crc (except x^32): */
 260   static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
 261 
 262   /* Make exclusive-or pattern from polynomial */
 263   e = 0;
 264   for (i = 0; i < sizeof(p)/sizeof(int); i++)
 265     e |= 1L << (31 - p[i]);
 266 
 267   crc_32_tab[0] = 0;
 268 
 269   for (i = 1; i < 256; i++)
 270   {
 271     c = 0;
 272     for (k = i | 256; k != 1; k >>= 1)
 273     {
 274       c = c & 1 ? (c >> 1) ^ e : c >> 1;
 275       if (k & 1)
 276         c ^= e;
 277     }
 278     crc_32_tab[i] = c;
 279   }
 280 }
 281 
 282 void error(char *x)
     /* [previous][next][first][last][top][bottom][index][help] */
 283 {
 284         puts("\n\n");
 285         puts(x);
 286         puts("\n\n -- System halted");
 287 
 288         while(1);       /* Halt */
 289 }
 290 
 291 #define STACK_SIZE (4096)
 292 
 293 long user_stack [STACK_SIZE];
 294 
 295 struct {
 296         long * a;
 297         short b;
 298         } stack_start = { & user_stack [STACK_SIZE] , KERNEL_DS };
 299 
 300 void decompress_kernel()
     /* [previous][next][first][last][top][bottom][index][help] */
 301 {
 302         if (SCREEN_INFO.orig_video_mode == 7)
 303                 vidmem = (char *) 0xb0000;
 304         else
 305                 vidmem = (char *) 0xb8000;
 306 
 307         lines = SCREEN_INFO.orig_video_lines;
 308         cols = SCREEN_INFO.orig_video_cols;
 309 
 310         if (EXT_MEM_K < 1024) error("<2M of mem\n");
 311 
 312         output_data = (char *)1048576;  /* Points to 1M */
 313         output_ptr = 0;
 314 
 315         exit_code = 0;
 316         test = 0;
 317         input_ptr = 0;
 318         part_nb = 0;
 319 
 320         clear_bufs();
 321         makecrc();
 322 
 323         puts("Uncompressing Linux...");
 324 
 325         method = get_method(0);
 326 
 327         work(0, 0);
 328 
 329         puts("done.\n");
 330 
 331         puts("Now booting the kernel\n");
 332 }
 333 
 334 /* ========================================================================
 335  * Check the magic number of the input file and update ofname if an
 336  * original name was given and to_stdout is not set.
 337  * Return the compression method, -1 for error, -2 for warning.
 338  * Set inptr to the offset of the next byte to be processed.
 339  * This function may be called repeatedly for an input file consisting
 340  * of several contiguous gzip'ed members.
 341  * IN assertions: there is at least one remaining compressed member.
 342  *   If the member is a zip file, it must be the only one.
 343  */
 344 local int get_method(in)
     /* [previous][next][first][last][top][bottom][index][help] */
 345     int in;        /* input file descriptor */
 346 {
 347     uch flags;
 348     char magic[2]; /* magic header */
 349 
 350     magic[0] = (char)get_byte();
 351     magic[1] = (char)get_byte();
 352 
 353     method = -1;                 /* unknown yet */
 354     part_nb++;                   /* number of parts in gzip file */
 355     last_member = 0;
 356     /* assume multiple members in gzip file except for record oriented I/O */
 357 
 358     if (memcmp(magic, GZIP_MAGIC, 2) == 0
 359         || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
 360 
 361         work = unzip;
 362         method = (int)get_byte();
 363         flags  = (uch)get_byte();
 364         if ((flags & ENCRYPTED) != 0) {
 365             error("Input is encrypted\n");
 366             exit_code = ERROR;
 367             return -1;
 368         }
 369         if ((flags & CONTINUATION) != 0) {
 370                error("Multi part input\n");
 371             exit_code = ERROR;
 372             if (force <= 1) return -1;
 373         }
 374         if ((flags & RESERVED) != 0) {
 375             error("Input has invalid flags\n");
 376             exit_code = ERROR;
 377             if (force <= 1) return -1;
 378         }
 379         (ulg)get_byte();        /* Get timestamp */
 380         ((ulg)get_byte()) << 8;
 381         ((ulg)get_byte()) << 16;
 382         ((ulg)get_byte()) << 24;
 383 
 384         (void)get_byte();  /* Ignore extra flags for the moment */
 385         (void)get_byte();  /* Ignore OS type for the moment */
 386 
 387         if ((flags & CONTINUATION) != 0) {
 388             unsigned part = (unsigned)get_byte();
 389             part |= ((unsigned)get_byte())<<8;
 390             if (verbose) {
 391                 error("Input is not part number 1\n");
 392             }
 393         }
 394         if ((flags & EXTRA_FIELD) != 0) {
 395             unsigned len = (unsigned)get_byte();
 396             len |= ((unsigned)get_byte())<<8;
 397             while (len--) (void)get_byte();
 398         }
 399 
 400         /* Get original file name if it was truncated */
 401         if ((flags & ORIG_NAME) != 0) {
 402             if (to_stdout || part_nb > 1) {
 403                 /* Discard the old name */
 404                 while (get_byte() != 0) /* null */ ;
 405             } else {
 406             } /* to_stdout */
 407         } /* orig_name */
 408 
 409         /* Discard file comment if any */
 410         if ((flags & COMMENT) != 0) {
 411             while (get_byte() != 0) /* null */ ;
 412         }
 413 
 414     } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2
 415             && memcmp(inbuf, PKZIP_MAGIC, 4) == 0) {
 416         /* To simplify the code, we support a zip file when alone only.
 417          * We are thus guaranteed that the entire local header fits in inbuf.
 418          */
 419         inptr = 0;
 420         work = unzip;
 421         if (check_zipfile(in) == -1) return -1;
 422         /* check_zipfile may get ofname from the local header */
 423         last_member = 1;
 424 
 425     } else if (memcmp(magic, PACK_MAGIC, 2) == 0) {
 426         error("packed input");
 427     } else if (memcmp(magic, LZW_MAGIC, 2) == 0) {
 428         error("compressed input");
 429         last_member = 1;
 430     }
 431     if (method == -1) {
 432         error("Corrupted input\n");
 433         if (exit_code != ERROR) exit_code = part_nb == 1 ? ERROR : WARNING;
 434         return part_nb == 1 ? -1 : -2;
 435     }
 436     return method;
 437 }

/* [previous][next][first][last][top][bottom][index][help] */