linux/arch/cris/arch-v10/boot/compressed/misc.c
<<
>>
Prefs
   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 and Matthias Urlichs 1994
   8 * puts by Nick Holloway 1993, better puts by Martin Mares 1995
   9 * adaptation for Linux/CRIS Axis Communications AB, 1999
  10 *
  11 */
  12
  13/* where the piggybacked kernel image expects itself to live.
  14 * it is the same address we use when we network load an uncompressed
  15 * image into DRAM, and it is the address the kernel is linked to live
  16 * at by vmlinux.lds.S
  17 */
  18
  19#define KERNEL_LOAD_ADR 0x40004000
  20
  21
  22#include <linux/types.h>
  23#include <arch/svinto.h>
  24
  25/*
  26 * gzip declarations
  27 */
  28
  29#define OF(args)  args
  30#define STATIC static
  31
  32void *memset(void *s, int c, size_t n);
  33void *memcpy(void *__dest, __const void *__src, size_t __n);
  34
  35#define memzero(s, n)     memset((s), 0, (n))
  36
  37typedef unsigned char  uch;
  38typedef unsigned short ush;
  39typedef unsigned long  ulg;
  40
  41#define WSIZE 0x8000            /* Window size must be at least 32k, */
  42                                /* and a power of two */
  43
  44static uch *inbuf;           /* input buffer */
  45static uch window[WSIZE];    /* Sliding window buffer */
  46
  47unsigned inptr = 0;     /* index of next byte to be processed in inbuf
  48                         * After decompression it will contain the
  49                         * compressed size, and head.S will read it.
  50                         */
  51
  52static unsigned outcnt = 0;  /* bytes in output buffer */
  53
  54/* gzip flag byte */
  55#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
  56#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
  57#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
  58#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
  59#define COMMENT      0x10 /* bit 4 set: file comment present */
  60#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
  61#define RESERVED     0xC0 /* bit 6,7:   reserved */
  62
  63#define get_byte() (inbuf[inptr++])
  64
  65/* Diagnostic functions */
  66#ifdef DEBUG
  67#  define Assert(cond, msg) do { \
  68                if (!(cond)) \
  69                        error(msg); \
  70        } while (0)
  71#  define Trace(x) fprintf x
  72#  define Tracev(x) do { \
  73                if (verbose) \
  74                        fprintf x; \
  75        } while (0)
  76#  define Tracevv(x) do { \
  77                if (verbose > 1) \
  78                        fprintf x; \
  79        } while (0)
  80#  define Tracec(c, x) do { \
  81                if (verbose && (c)) \
  82                        fprintf x; \
  83        } while (0)
  84#  define Tracecv(c, x) do { \
  85                if (verbose > 1 && (c)) \
  86                        fprintf x; \
  87        } while (0)
  88#else
  89#  define Assert(cond, msg)
  90#  define Trace(x)
  91#  define Tracev(x)
  92#  define Tracevv(x)
  93#  define Tracec(c, x)
  94#  define Tracecv(c, x)
  95#endif
  96
  97static void flush_window(void);
  98static void error(char *m);
  99
 100extern char *input_data;  /* lives in head.S */
 101
 102static long bytes_out = 0;
 103static uch *output_data;
 104static unsigned long output_ptr = 0;
 105static void puts(const char *);
 106
 107/* the "heap" is put directly after the BSS ends, at end */
 108
 109extern int _end;
 110static long free_mem_ptr = (long)&_end;
 111static long free_mem_end_ptr;
 112
 113#include "../../../../../lib/inflate.c"
 114
 115/* decompressor info and error messages to serial console */
 116
 117static void
 118puts(const char *s)
 119{
 120#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
 121        while (*s) {
 122#ifdef CONFIG_ETRAX_DEBUG_PORT0
 123                while (!(*R_SERIAL0_STATUS & (1 << 5))) ;
 124                *R_SERIAL0_TR_DATA = *s++;
 125#endif
 126#ifdef CONFIG_ETRAX_DEBUG_PORT1
 127                while (!(*R_SERIAL1_STATUS & (1 << 5))) ;
 128                *R_SERIAL1_TR_DATA = *s++;
 129#endif
 130#ifdef CONFIG_ETRAX_DEBUG_PORT2
 131                while (!(*R_SERIAL2_STATUS & (1 << 5))) ;
 132                *R_SERIAL2_TR_DATA = *s++;
 133#endif
 134#ifdef CONFIG_ETRAX_DEBUG_PORT3
 135                while (!(*R_SERIAL3_STATUS & (1 << 5))) ;
 136                *R_SERIAL3_TR_DATA = *s++;
 137#endif
 138        }
 139#endif
 140}
 141
 142void *memset(void *s, int c, size_t n)
 143{
 144        int i;
 145        char *ss = (char *)s;
 146
 147        for (i = 0; i < n; i++)
 148                ss[i] = c;
 149
 150        return s;
 151}
 152
 153void *memcpy(void *__dest, __const void *__src, size_t __n)
 154{
 155        int i;
 156        char *d = (char *)__dest, *s = (char *)__src;
 157
 158        for (i = 0; i < __n; i++)
 159                d[i] = s[i];
 160
 161        return __dest;
 162}
 163
 164/* ===========================================================================
 165 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 166 * (Used for the decompressed data only.)
 167 */
 168
 169static void flush_window(void)
 170{
 171        ulg c = crc;         /* temporary variable */
 172        unsigned n;
 173        uch *in, *out, ch;
 174
 175        in = window;
 176        out = &output_data[output_ptr];
 177        for (n = 0; n < outcnt; n++) {
 178                ch = *out = *in;
 179                out++;
 180                in++;
 181                c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
 182        }
 183        crc = c;
 184        bytes_out += (ulg)outcnt;
 185        output_ptr += (ulg)outcnt;
 186        outcnt = 0;
 187}
 188
 189static void error(char *x)
 190{
 191        puts("\n\n");
 192        puts(x);
 193        puts("\n\n -- System halted\n");
 194
 195        while (1);      /* Halt */
 196}
 197
 198void setup_normal_output_buffer(void)
 199{
 200        output_data = (char *)KERNEL_LOAD_ADR;
 201}
 202
 203void decompress_kernel(void)
 204{
 205        char revision;
 206
 207        /* input_data is set in head.S */
 208        inbuf = input_data;
 209
 210#ifdef CONFIG_ETRAX_DEBUG_PORT0
 211        *R_SERIAL0_XOFF = 0;
 212        *R_SERIAL0_BAUD = 0x99;
 213        *R_SERIAL0_TR_CTRL = 0x40;
 214#endif
 215#ifdef CONFIG_ETRAX_DEBUG_PORT1
 216        *R_SERIAL1_XOFF = 0;
 217        *R_SERIAL1_BAUD = 0x99;
 218        *R_SERIAL1_TR_CTRL = 0x40;
 219#endif
 220#ifdef CONFIG_ETRAX_DEBUG_PORT2
 221        *R_GEN_CONFIG = 0x08;
 222        *R_SERIAL2_XOFF = 0;
 223        *R_SERIAL2_BAUD = 0x99;
 224        *R_SERIAL2_TR_CTRL = 0x40;
 225#endif
 226#ifdef CONFIG_ETRAX_DEBUG_PORT3
 227        *R_GEN_CONFIG = 0x100;
 228        *R_SERIAL3_XOFF = 0;
 229        *R_SERIAL3_BAUD = 0x99;
 230        *R_SERIAL3_TR_CTRL = 0x40;
 231#endif
 232
 233        setup_normal_output_buffer();
 234
 235        makecrc();
 236
 237        __asm__ volatile ("move $vr,%0" : "=rm" (revision));
 238        if (revision < 10) {
 239                puts("You need an ETRAX 100LX to run linux 2.6\n");
 240                while (1);
 241        }
 242
 243        puts("Uncompressing Linux...\n");
 244        gunzip();
 245        puts("Done. Now booting the kernel.\n");
 246}
 247
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.