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

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