root/zBoot/misc.c

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

DEFINITIONS

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

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