root/zBoot/misc.c

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

DEFINITIONS

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

   1 #include "gzip.h"
   2 #include "lzw.h"
   3 
   4 /*
   5  * These are set up by the setup-routine at boot-time:
   6  */
   7 
   8 struct screen_info {
   9         unsigned char  orig_x;
  10         unsigned char  orig_y;
  11         unsigned char  unused1[2];
  12         unsigned short orig_video_page;
  13         unsigned char  orig_video_mode;
  14         unsigned char  orig_video_cols;
  15         unsigned short orig_video_ega_ax;
  16         unsigned short orig_video_ega_bx;
  17         unsigned short orig_video_ega_cx;
  18         unsigned char  orig_video_lines;
  19 };
  20 
  21 /*
  22  * This is set up by the setup-routine at boot-time
  23  */
  24 #define EXT_MEM_K (*(unsigned short *)0x90002)
  25 #define DRIVE_INFO (*(struct drive_info *)0x90080)
  26 #define SCREEN_INFO (*(struct screen_info *)0x90000)
  27 #define RAMDISK_SIZE (*(unsigned short *)0x901F8)
  28 #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
  29 #define AUX_DEVICE_INFO (*(unsigned char *)0x901FF)
  30 
  31 #define EOF -1
  32 
  33 DECLARE(uch, inbuf, INBUFSIZ);
  34 DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);
  35 DECLARE(uch, window, WSIZE);
  36 
  37 unsigned outcnt;
  38 unsigned insize;
  39 unsigned inptr;
  40 
  41 extern char input_data[];
  42 extern int input_len;
  43 
  44 int input_ptr;
  45 
  46 int method, exit_code, part_nb, last_member;
  47 int test = 0;
  48 int force = 0;
  49 int verbose = 1;
  50 long bytes_in, bytes_out;
  51 
  52 char *output_data;
  53 unsigned long output_ptr;
  54 
  55 extern int end;
  56 long free_mem_ptr = (long)&end;
  57 
  58 int to_stdout = 0;
  59 int hard_math = 0;
  60 
  61 void (*work)(int inf, int outf);
  62 
  63 char *vidmem = (char *)0xb8000;
  64 int vidp = 0;
  65 int lines, cols;
  66 
  67 void *malloc(int size)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69         void *p;
  70 
  71         if (size <0) error("Malloc error\n");
  72         if (free_mem_ptr <= 0) error("Memory error\n");
  73 
  74         free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
  75 
  76         p = (void *)free_mem_ptr;
  77 
  78         free_mem_ptr += size;
  79 
  80         if (free_mem_ptr >= (640*1024)) error("\nOut of memory\n");
  81 
  82         if (p == NULL) error("malloc = NULL\n");
  83         return p;
  84 }
  85 
  86 void free(void *where)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {       /* Don't care */
  88 }
  89 
  90 int printk(char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92         int i,n;
  93         n = strlen(s);
  94         if (!n) n = 10;
  95 
  96         for (i=0;i<n;i++)
  97         if (s[i] == '\n')
  98         {
  99                  vidp = ((vidp / (cols*2)) + 1) * cols * 2;
 100         } else {
 101                 vidmem[vidp] = s[i]; 
 102                 vidp = vidp + 2;
 103         }
 104 
 105         return 1;
 106 }
 107 
 108 __ptr_t memset(__ptr_t s, int c, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 109 {
 110         int i;
 111         char *ss = (char*)s;
 112 
 113         for (i=0;i<n;i++) ss[i] = c;
 114 }
 115 
 116 __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
     /* [previous][next][first][last][top][bottom][index][help] */
 117                             size_t __n)
 118 {
 119         int i;
 120         char *d = (char *)__dest, *s = (char *)__src;
 121 
 122         for (i=0;i<__n;i++) d[i] = s[i];
 123 }
 124 
 125 extern ulg crc_32_tab[];   /* crc table, defined below */
 126 
 127 /* ===========================================================================
 128  * Run a set of bytes through the crc shift register.  If s is a NULL
 129  * pointer, then initialize the crc shift register contents instead.
 130  * Return the current crc in either case.
 131  */
 132 ulg updcrc(s, n)
     /* [previous][next][first][last][top][bottom][index][help] */
 133     uch *s;                 /* pointer to bytes to pump through */
 134     unsigned n;             /* number of bytes in s[] */
 135 {
 136     register ulg c;         /* temporary variable */
 137 
 138     static ulg crc = (ulg)0xffffffffL; /* shift register contents */
 139 
 140     if (s == NULL) {
 141         c = 0xffffffffL;
 142     } else {
 143         c = crc;
 144         while (n--) {
 145             c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
 146         }
 147     }
 148     crc = c;
 149     return c ^ 0xffffffffL;       /* (instead of ~c for 64-bit machines) */
 150 }
 151 
 152 /* ===========================================================================
 153  * Clear input and output buffers
 154  */
 155 void clear_bufs()
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157     outcnt = 0;
 158     insize = inptr = 0;
 159     bytes_in = bytes_out = 0L;
 160 }
 161 
 162 /* ===========================================================================
 163  * Fill the input buffer. This is called only when the buffer is empty
 164  * and at least one byte is really needed.
 165  */
 166 int fill_inbuf()
     /* [previous][next][first][last][top][bottom][index][help] */
 167 {
 168     int len, i;
 169 
 170     /* Read as much as possible */
 171     insize = 0;
 172     do {
 173         len = INBUFSIZ-insize;
 174         if (len > (input_len-input_ptr+1)) len=input_len-input_ptr+1;
 175         if (len == 0 || len == EOF) break;
 176 
 177         for (i=0;i<len;i++) inbuf[insize+i] = input_data[input_ptr+i];
 178         insize += len;
 179         input_ptr += len;
 180     } while (insize < INBUFSIZ);
 181 
 182     if (insize == 0) {
 183         error("unable to fill buffer\n");
 184     }
 185     bytes_in += (ulg)insize;
 186     inptr = 1;
 187     return inbuf[0];
 188 }
 189 
 190 /* ===========================================================================
 191  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 192  * (Used for the decompressed data only.)
 193  */
 194 void flush_window()
     /* [previous][next][first][last][top][bottom][index][help] */
 195 {
 196     if (outcnt == 0) return;
 197     updcrc(window, outcnt);
 198 
 199     memcpy(&output_data[output_ptr], (char *)window, outcnt);
 200 
 201     bytes_out += (ulg)outcnt;
 202     output_ptr += (ulg)outcnt;
 203     outcnt = 0;
 204 }
 205 
 206 /* ========================================================================
 207  * Table of CRC-32's of all single-byte values (made by makecrc.c)
 208  */
 209 ulg crc_32_tab[] = {
 210   0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
 211   0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
 212   0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
 213   0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
 214   0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
 215   0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
 216   0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
 217   0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
 218   0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
 219   0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
 220   0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
 221   0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
 222   0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
 223   0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
 224   0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
 225   0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
 226   0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
 227   0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
 228   0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
 229   0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
 230   0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
 231   0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
 232   0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
 233   0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
 234   0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
 235   0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
 236   0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
 237   0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
 238   0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
 239   0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
 240   0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
 241   0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
 242   0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
 243   0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
 244   0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
 245   0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
 246   0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
 247   0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
 248   0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
 249   0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
 250   0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
 251   0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
 252   0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
 253   0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
 254   0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
 255   0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
 256   0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
 257   0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
 258   0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
 259   0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
 260   0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
 261   0x2d02ef8dL
 262 };
 263 
 264 void error(char *x)
     /* [previous][next][first][last][top][bottom][index][help] */
 265 {
 266         printk(x);
 267         printk(" -- System halted");
 268 
 269         while(1);       /* Halt */
 270 }
 271 
 272 #define STACK_SIZE (4096)
 273 
 274 long user_stack [STACK_SIZE];
 275 
 276 struct {
 277         long * a;
 278         short b;
 279         } stack_start = { & user_stack [STACK_SIZE] , 0x10 };
 280 
 281 void decompress_kernel()
     /* [previous][next][first][last][top][bottom][index][help] */
 282 {
 283         vidp = 0;
 284         vidmem[0] = '0';
 285 
 286         lines = SCREEN_INFO.orig_video_lines;
 287         cols = SCREEN_INFO.orig_video_cols;
 288 
 289         if (EXT_MEM_K < 2048) error("At least 2M of memory required by Turbo Ignition\n");
 290 
 291         output_data = (char *)1048576;  /* Points to 1M */
 292         output_ptr = 0;
 293 
 294         exit_code = 0;
 295         test = 0;
 296         input_ptr = 0;
 297         part_nb = 0;
 298 
 299         clear_bufs();
 300 
 301         printk("Uncompressing Linux: check - ");
 302 
 303         method = get_method(0);
 304 
 305         printk("work - ");
 306 
 307         work(0, 0);
 308 
 309         printk("done.\n\n");
 310 
 311         printk("Now booting the kernel\n");
 312 }
 313 
 314 /* ========================================================================
 315  * Check the magic number of the input file and update ofname if an
 316  * original name was given and to_stdout is not set.
 317  * Return the compression method, -1 for error, -2 for warning.
 318  * Set inptr to the offset of the next byte to be processed.
 319  * This function may be called repeatedly for an input file consisting
 320  * of several contiguous gzip'ed members.
 321  * IN assertions: there is at least one remaining compressed member.
 322  *   If the member is a zip file, it must be the only one.
 323  */
 324 local int get_method(in)
     /* [previous][next][first][last][top][bottom][index][help] */
 325     int in;        /* input file descriptor */
 326 {
 327     uch flags;
 328     char magic[2]; /* magic header */
 329 
 330     magic[0] = (char)get_byte();
 331     magic[1] = (char)get_byte();
 332 
 333     method = -1;                 /* unknown yet */
 334     part_nb++;                   /* number of parts in gzip file */
 335     last_member = 0;
 336     /* assume multiple members in gzip file except for record oriented I/O */
 337 
 338     if (memcmp(magic, GZIP_MAGIC, 2) == 0
 339         || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
 340 
 341         work = unzip;
 342         method = (int)get_byte();
 343         flags  = (uch)get_byte();
 344         if ((flags & ENCRYPTED) != 0) {
 345             error("Input is encrypted -- too secret\n");
 346             exit_code = ERROR;
 347             return -1;
 348         }
 349         if ((flags & CONTINUATION) != 0) {
 350                error("Input is a a multi-part gzip file\n");
 351             exit_code = ERROR;
 352             if (force <= 1) return -1;
 353         }
 354         if ((flags & RESERVED) != 0) {
 355             error("Input has invalid flags\n");
 356             exit_code = ERROR;
 357             if (force <= 1) return -1;
 358         }
 359         (ulg)get_byte();        /* Get timestamp */
 360         ((ulg)get_byte()) << 8;
 361         ((ulg)get_byte()) << 16;
 362         ((ulg)get_byte()) << 24;
 363 
 364         (void)get_byte();  /* Ignore extra flags for the moment */
 365         (void)get_byte();  /* Ignore OS type for the moment */
 366 
 367         if ((flags & CONTINUATION) != 0) {
 368             unsigned part = (unsigned)get_byte();
 369             part |= ((unsigned)get_byte())<<8;
 370             if (verbose) {
 371                 error("Input is not part number 1\n");
 372             }
 373         }
 374         if ((flags & EXTRA_FIELD) != 0) {
 375             unsigned len = (unsigned)get_byte();
 376             len |= ((unsigned)get_byte())<<8;
 377             while (len--) (void)get_byte();
 378         }
 379 
 380         /* Get original file name if it was truncated */
 381         if ((flags & ORIG_NAME) != 0) {
 382             if (to_stdout || part_nb > 1) {
 383                 /* Discard the old name */
 384                 while (get_byte() != 0) /* null */ ;
 385             } else {
 386             } /* to_stdout */
 387         } /* orig_name */
 388 
 389         /* Discard file comment if any */
 390         if ((flags & COMMENT) != 0) {
 391             while (get_byte() != 0) /* null */ ;
 392         }
 393 
 394     } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2
 395             && memcmp(inbuf, PKZIP_MAGIC, 4) == 0) {
 396         /* To simplify the code, we support a zip file when alone only.
 397          * We are thus guaranteed that the entire local header fits in inbuf.
 398          */
 399         inptr = 0;
 400         work = unzip;
 401         if (check_zipfile(in) == -1) return -1;
 402         /* check_zipfile may get ofname from the local header */
 403         last_member = 1;
 404 
 405     } else if (memcmp(magic, PACK_MAGIC, 2) == 0) {
 406         error("packed input");
 407     } else if (memcmp(magic, LZW_MAGIC, 2) == 0) {
 408         error("compressed input");
 409         last_member = 1;
 410     }
 411     if (method == -1) {
 412         error("Corrupted input\n");
 413         if (exit_code != ERROR) exit_code = part_nb == 1 ? ERROR : WARNING;
 414         return part_nb == 1 ? -1 : -2;
 415     }
 416     return method;
 417 }

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