patch-pre2.0.8 linux/arch/ppc/boot/compressed/misc.c
Next file: linux/arch/ppc/boot/compressed/piggyback.c
Previous file: linux/arch/ppc/boot/compressed/lzw.h
Back to the patch index
Back to the overall index
- Lines: 431
- Date:
Mon May 27 12:00:57 1996
- Orig file:
pre2.0.7/linux/arch/ppc/boot/compressed/misc.c
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file pre2.0.7/linux/arch/ppc/boot/compressed/misc.c linux/arch/ppc/boot/compressed/misc.c
@@ -0,0 +1,430 @@
+/*
+ * misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ * puts by Nick Holloway 1993
+ */
+
+#include "gzip.h"
+#include "lzw.h"
+
+
+#define EOF -1
+
+DECLARE(uch, inbuf, INBUFSIZ);
+DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);
+DECLARE(uch, window, WSIZE);
+
+unsigned outcnt;
+unsigned insize;
+unsigned inptr;
+
+extern char input_data[];
+extern int input_len;
+
+int input_ptr;
+
+int method, exit_code, part_nb, last_member;
+int test = 0;
+int force = 0;
+int verbose = 1;
+long bytes_in, bytes_out;
+
+char *output_data;
+unsigned long output_ptr;
+
+extern int end;
+long free_mem_ptr = (long)&end;
+
+int to_stdout = 0;
+int hard_math = 0;
+
+void (*work)(int inf, int outf);
+void makecrc(void);
+
+local int get_method(int);
+
+char *vidmem = (char *)0xC00B8000;
+int lines, cols;
+int orig_x, orig_y;
+
+void puts(const char *);
+
+void *malloc(int size)
+{
+ void *p;
+
+ if (size <0) error("Malloc error\n");
+ if (free_mem_ptr <= 0) error("Memory error\n");
+
+ while(1) {
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+ p = (void *)free_mem_ptr;
+ free_mem_ptr += size;
+
+ /*
+ * The part of the compressed kernel which has already been expanded
+ * is no longer needed. Therefore we can reuse it for malloc.
+ * With bigger kernels, this is necessary.
+ */
+
+ if (free_mem_ptr < (long)&end) {
+ if (free_mem_ptr > (long)&input_data[input_ptr])
+ error("\nOut of memory\n");
+
+ return p;
+ }
+#if 0
+ if (free_mem_ptr < 0x90000)
+#endif
+ return p;
+ puts("large kernel, low 1M tight...");
+ free_mem_ptr = (long)input_data;
+ }
+}
+
+void free(void *where)
+{ /* Don't care */
+}
+
+static void scroll()
+{
+ int i;
+
+ memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
+ for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
+ vidmem[i] = ' ';
+}
+
+void puts(const char *s)
+{
+ int x,y;
+ char c;
+
+#if 0
+ x = SCREEN_INFO.orig_x;
+ y = SCREEN_INFO.orig_y;
+#else
+ x = orig_x;
+ y = orig_y;
+#endif
+
+ while ( ( c = *s++ ) != '\0' ) {
+ if ( c == '\n' ) {
+ x = 0;
+ if ( ++y >= lines ) {
+ scroll();
+ y--;
+ }
+ } else {
+ vidmem [ ( x + cols * y ) * 2 ] = c;
+ if ( ++x >= cols ) {
+ x = 0;
+ if ( ++y >= lines ) {
+ scroll();
+ y--;
+ }
+ }
+ }
+ }
+
+#if 0
+ SCREEN_INFO.orig_x = x;
+ SCREEN_INFO.orig_y = y;
+#else
+ orig_x = x;
+ orig_y = y;
+#endif
+}
+
+__ptr_t memset(__ptr_t s, int c, size_t n)
+{
+ int i;
+ char *ss = (char*)s;
+
+ for (i=0;i<n;i++) ss[i] = c;
+}
+
+__ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
+ size_t __n)
+{
+ int i;
+ char *d = (char *)__dest, *s = (char *)__src;
+
+ for (i=0;i<__n;i++) d[i] = s[i];
+}
+
+int memcmp(__ptr_t __dest, __const __ptr_t __src,
+ size_t __n)
+{
+ int i;
+ char *d = (char *)__dest, *s = (char *)__src;
+
+ for (i=0;i<__n;i++, d++, s++)
+ {
+ if (*d != *s)
+ {
+ return (*s - *d);
+ }
+ }
+ return (0);
+}
+
+extern ulg crc_32_tab[]; /* crc table, defined below */
+
+/* ===========================================================================
+ * Run a set of bytes through the crc shift register. If s is a NULL
+ * pointer, then initialize the crc shift register contents instead.
+ * Return the current crc in either case.
+ */
+ulg updcrc(s, n)
+ uch *s; /* pointer to bytes to pump through */
+ unsigned n; /* number of bytes in s[] */
+{
+ register ulg c; /* temporary variable */
+
+ static ulg crc = (ulg)0xffffffffL; /* shift register contents */
+
+ if (s == NULL) {
+ c = 0xffffffffL;
+ } else {
+ c = crc;
+ while (n--) {
+ c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
+ }
+ }
+ crc = c;
+ return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
+}
+
+/* ===========================================================================
+ * Clear input and output buffers
+ */
+void clear_bufs()
+{
+ outcnt = 0;
+ insize = inptr = 0;
+ bytes_in = bytes_out = 0L;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+int fill_inbuf()
+{
+ int len, i;
+
+ /* Read as much as possible */
+puts("*");
+ insize = 0;
+ do {
+ len = INBUFSIZ-insize;
+ if (len > (input_len-input_ptr+1)) len=input_len-input_ptr+1;
+ if (len == 0 || len == EOF) break;
+
+ for (i=0;i<len;i++) inbuf[insize+i] = input_data[input_ptr+i];
+ insize += len;
+ input_ptr += len;
+ } while (insize < INBUFSIZ);
+
+ if (insize == 0) {
+ error("unable to fill buffer\n");
+ }
+ bytes_in += (ulg)insize;
+ inptr = 1;
+ return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+void flush_window()
+{
+ if (outcnt == 0) return;
+ updcrc(window, outcnt);
+
+ memcpy(&output_data[output_ptr], (char *)window, outcnt);
+
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
+}
+
+/*
+ * Code to compute the CRC-32 table. Borrowed from
+ * gzip-1.0.3/makecrc.c.
+ */
+
+ulg crc_32_tab[256];
+
+void
+makecrc(void)
+{
+/* Not copyrighted 1990 Mark Adler */
+
+ unsigned long c; /* crc shift register */
+ unsigned long e; /* polynomial exclusive-or pattern */
+ int i; /* counter for all possible eight bit values */
+ int k; /* byte being shifted into crc apparatus */
+
+ /* terms of polynomial defining this crc (except x^32): */
+ static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* Make exclusive-or pattern from polynomial */
+ e = 0;
+ for (i = 0; i < sizeof(p)/sizeof(int); i++)
+ e |= 1L << (31 - p[i]);
+
+ crc_32_tab[0] = 0;
+
+ for (i = 1; i < 256; i++)
+ {
+ c = 0;
+ for (k = i | 256; k != 1; k >>= 1)
+ {
+ c = c & 1 ? (c >> 1) ^ e : c >> 1;
+ if (k & 1)
+ c ^= e;
+ }
+ crc_32_tab[i] = c;
+ }
+}
+
+void error(char *x)
+{
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+#if 0
+#define STACK_SIZE (4096)
+
+long user_stack [STACK_SIZE];
+
+struct {
+ long * a;
+ short b;
+ } stack_start = { & user_stack [STACK_SIZE] , KERNEL_DS };
+#endif
+
+void decompress_kernel()
+{
+#if 0
+ if (SCREEN_INFO.orig_video_mode == 7)
+ vidmem = (char *) 0xb0000;
+ else
+ vidmem = (char *) 0xb8000;
+
+ lines = SCREEN_INFO.orig_video_lines;
+ cols = SCREEN_INFO.orig_video_cols;
+
+ if (EXT_MEM_K < 1024) error("<2M of mem\n");
+ output_data = (char *)0x100000; /* Points to 1M */
+#else
+ output_data = (char *)0x0; /* Points to 0 */
+ lines = 25;
+ cols = 80;
+ orig_x = 0;
+ orig_y = 24;
+#endif
+
+ output_ptr = 0;
+
+ exit_code = 0;
+ test = 0;
+ input_ptr = 0;
+ part_nb = 0;
+
+ clear_bufs();
+ makecrc();
+
+ puts("Uncompressing Linux...");
+
+ method = get_method(0);
+
+ work(0, 0);
+
+ puts("done.\n");
+
+ puts("Now booting the kernel\n");
+}
+
+/* ========================================================================
+ * Check the magic number of the input file and update ofname if an
+ * original name was given and to_stdout is not set.
+ * Return the compression method, -1 for error, -2 for warning.
+ * Set inptr to the offset of the next byte to be processed.
+ * This function may be called repeatedly for an input file consisting
+ * of several contiguous gzip'ed members.
+ * IN assertions: there is at least one remaining compressed member.
+ * If the member is a zip file, it must be the only one.
+ */
+local int get_method(in)
+ int in; /* input file descriptor */
+{
+ uch flags;
+ char magic[2]; /* magic header */
+
+ magic[0] = (char)get_byte();
+ magic[1] = (char)get_byte();
+
+ method = -1; /* unknown yet */
+ part_nb++; /* number of parts in gzip file */
+ last_member = 0;
+ /* assume multiple members in gzip file except for record oriented I/O */
+
+ if (memcmp(magic, GZIP_MAGIC, 2) == 0
+ || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {
+
+ work = unzip;
+ method = (int)get_byte();
+ flags = (uch)get_byte();
+ if ((flags & ENCRYPTED) != 0)
+ error("Input is encrypted\n");
+ if ((flags & CONTINUATION) != 0)
+ error("Multi part input\n");
+ if ((flags & RESERVED) != 0) {
+ error("Input has invalid flags\n");
+ exit_code = ERROR;
+ if (force <= 1) return -1;
+ }
+ (ulg)get_byte(); /* Get timestamp */
+ ((ulg)get_byte()) << 8;
+ ((ulg)get_byte()) << 16;
+ ((ulg)get_byte()) << 24;
+
+ (void)get_byte(); /* Ignore extra flags for the moment */
+ (void)get_byte(); /* Ignore OS type for the moment */
+
+ if ((flags & EXTRA_FIELD) != 0) {
+ unsigned len = (unsigned)get_byte();
+ len |= ((unsigned)get_byte())<<8;
+ while (len--) (void)get_byte();
+ }
+
+ /* Get original file name if it was truncated */
+ if ((flags & ORIG_NAME) != 0) {
+ if (to_stdout || part_nb > 1) {
+ /* Discard the old name */
+ while (get_byte() != 0) /* null */ ;
+ } else {
+ } /* to_stdout */
+ } /* orig_name */
+
+ /* Discard file comment if any */
+ if ((flags & COMMENT) != 0) {
+ while (get_byte() != 0) /* null */ ;
+ }
+ } else
+ error("unknown compression method");
+ return method;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this