home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / zBoot / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  9.8 KB  |  438 lines

  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)
  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)
  101. {    /* Don't care */
  102. }
  103.  
  104. static void scroll()
  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)
  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)
  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,
  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)
  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()
  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()
  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()
  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)
  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)
  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()
  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)
  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. }
  438.