^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This is a collection of several routines from gzip-1.0.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * adapted for Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Adapted for SH by Stuart Menefy, Aug 1999
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Based on arch/sh/boot/compressed/misc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * gzip declarations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define OF(args) args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define STATIC static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #undef memset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #undef memcpy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define memzero(s, n) memset((s), 0, (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) typedef unsigned char uch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) typedef unsigned short ush;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) typedef unsigned long ulg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define WSIZE 0x8000 /* Window size must be at least 32k, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* and a power of two */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static uch *inbuf; /* input buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static uch window[WSIZE]; /* Sliding window buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static unsigned insize; /* valid bytes in inbuf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static unsigned inptr; /* index of next byte to be processed in inbuf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static unsigned outcnt; /* bytes in output buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* gzip flag byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define COMMENT 0x10 /* bit 4 set: file comment present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define RESERVED 0xC0 /* bit 6,7: reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) # define Assert(cond, msg) {if (!(cond)) error(msg); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) # define Trace(x) fprintf x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) # define Tracev(x) {if (verbose) fprintf x ; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) # define Tracevv(x) {if (verbose > 1) fprintf x ; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) # define Tracec(c, x) {if (verbose && (c)) fprintf x ; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) # define Tracecv(c, x) {if (verbose > 1 && (c)) fprintf x ; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) # define Assert(cond, msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) # define Trace(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) # define Tracev(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) # define Tracevv(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) # define Tracec(c, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) # define Tracecv(c, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static int fill_inbuf(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void flush_window(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static void error(char *m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) extern char input_data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) extern int input_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static long bytes_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static uch *output_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static unsigned long output_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include "console.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static void error(char *m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int puts(const char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) extern int _end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static unsigned long free_mem_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static unsigned long free_mem_end_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define HEAP_SIZE 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #include "../../../../lib/inflate.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) void *memset(void *s, int c, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) char *ss = (char *)s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) for (i = 0; i < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ss[i] = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) void *memcpy(void *__dest, __const void *__src, size_t __n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) char *d = (char *)__dest, *s = (char *)__src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) for (i = 0; i < __n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) d[i] = s[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return __dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Fill the input buffer. This is called only when the buffer is empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * and at least one byte is really needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static int fill_inbuf(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (insize != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) error("ran out of input data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) inbuf = input_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) insize = input_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) inptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return inbuf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Write the output window window[0..outcnt-1] and update crc and bytes_out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * (Used for the decompressed data only.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void flush_window(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ulg c = crc; /* temporary variable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) uch *in, *out, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) in = window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) out = &output_data[output_ptr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) for (n = 0; n < outcnt; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ch = *out++ = *in++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) crc = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) bytes_out += (ulg)outcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) output_ptr += (ulg)outcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) outcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void error(char *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) puts("\nERROR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) puts(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) puts("\n\n -- System halted");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) while (1) /* Halt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) void decompress_kernel(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) output_data = (void *) (CONFIG_NIOS2_MEM_BASE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) CONFIG_NIOS2_KERNEL_REGION_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) output_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) free_mem_ptr = (unsigned long)&_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) console_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) makecrc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) puts("Uncompressing Linux... ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) gunzip();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) puts("Ok, booting the kernel.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }