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