linux/arch/sh/boot/compressed/misc_32.c
<<
>>
Prefs
   1/*
   2 * arch/sh/boot/compressed/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 *
   9 * Adapted for SH by Stuart Menefy, Aug 1999
  10 *
  11 * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
  12 */
  13
  14#include <asm/uaccess.h>
  15#include <asm/addrspace.h>
  16#include <asm/page.h>
  17#ifdef CONFIG_SH_STANDARD_BIOS
  18#include <asm/sh_bios.h>
  19#endif
  20
  21/*
  22 * gzip declarations
  23 */
  24
  25#define OF(args)  args
  26#define STATIC static
  27
  28#undef memset
  29#undef memcpy
  30#define memzero(s, n)     memset ((s), 0, (n))
  31
  32typedef unsigned char  uch;
  33typedef unsigned short ush;
  34typedef unsigned long  ulg;
  35
  36#define WSIZE 0x8000            /* Window size must be at least 32k, */
  37                                /* and a power of two */
  38
  39static uch *inbuf;           /* input buffer */
  40static uch window[WSIZE];    /* Sliding window buffer */
  41
  42static unsigned insize = 0;  /* valid bytes in inbuf */
  43static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
  44static unsigned outcnt = 0;  /* bytes in output buffer */
  45
  46/* gzip flag byte */
  47#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
  48#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
  49#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
  50#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
  51#define COMMENT      0x10 /* bit 4 set: file comment present */
  52#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
  53#define RESERVED     0xC0 /* bit 6,7:   reserved */
  54
  55#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
  56
  57/* Diagnostic functions */
  58#ifdef DEBUG
  59#  define Assert(cond,msg) {if(!(cond)) error(msg);}
  60#  define Trace(x) fprintf x
  61#  define Tracev(x) {if (verbose) fprintf x ;}
  62#  define Tracevv(x) {if (verbose>1) fprintf x ;}
  63#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
  64#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
  65#else
  66#  define Assert(cond,msg)
  67#  define Trace(x)
  68#  define Tracev(x)
  69#  define Tracevv(x)
  70#  define Tracec(c,x)
  71#  define Tracecv(c,x)
  72#endif
  73
  74static int  fill_inbuf(void);
  75static void flush_window(void);
  76static void error(char *m);
  77
  78extern char input_data[];
  79extern int input_len;
  80
  81static long bytes_out = 0;
  82static uch *output_data;
  83static unsigned long output_ptr = 0;
  84
  85static void error(char *m);
  86
  87int puts(const char *);
  88
  89extern int _text;               /* Defined in vmlinux.lds.S */
  90extern int _end;
  91static unsigned long free_mem_ptr;
  92static unsigned long free_mem_end_ptr;
  93
  94#define HEAP_SIZE             0x10000
  95
  96#include "../../../../lib/inflate.c"
  97
  98#ifdef CONFIG_SH_STANDARD_BIOS
  99size_t strlen(const char *s)
 100{
 101        int i = 0;
 102
 103        while (*s++)
 104                i++;
 105        return i;
 106}
 107
 108int puts(const char *s)
 109{
 110        int len = strlen(s);
 111        sh_bios_console_write(s, len);
 112        return len;
 113}
 114#else
 115int puts(const char *s)
 116{
 117        /* This should be updated to use the sh-sci routines */
 118        return 0;
 119}
 120#endif
 121
 122void* memset(void* s, int c, size_t n)
 123{
 124        int i;
 125        char *ss = (char*)s;
 126
 127        for (i=0;i<n;i++) ss[i] = c;
 128        return s;
 129}
 130
 131void* memcpy(void* __dest, __const void* __src,
 132                            size_t __n)
 133{
 134        int i;
 135        char *d = (char *)__dest, *s = (char *)__src;
 136
 137        for (i=0;i<__n;i++) d[i] = s[i];
 138        return __dest;
 139}
 140
 141/* ===========================================================================
 142 * Fill the input buffer. This is called only when the buffer is empty
 143 * and at least one byte is really needed.
 144 */
 145static int fill_inbuf(void)
 146{
 147        if (insize != 0) {
 148                error("ran out of input data");
 149        }
 150
 151        inbuf = input_data;
 152        insize = input_len;
 153        inptr = 1;
 154        return inbuf[0];
 155}
 156
 157/* ===========================================================================
 158 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 159 * (Used for the decompressed data only.)
 160 */
 161static void flush_window(void)
 162{
 163    ulg c = crc;         /* temporary variable */
 164    unsigned n;
 165    uch *in, *out, ch;
 166
 167    in = window;
 168    out = &output_data[output_ptr];
 169    for (n = 0; n < outcnt; n++) {
 170            ch = *out++ = *in++;
 171            c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
 172    }
 173    crc = c;
 174    bytes_out += (ulg)outcnt;
 175    output_ptr += (ulg)outcnt;
 176    outcnt = 0;
 177}
 178
 179static void error(char *x)
 180{
 181        puts("\n\n");
 182        puts(x);
 183        puts("\n\n -- System halted");
 184
 185        while(1);       /* Halt */
 186}
 187
 188#define STACK_SIZE (4096)
 189long user_stack [STACK_SIZE];
 190long* stack_start = &user_stack[STACK_SIZE];
 191
 192void decompress_kernel(void)
 193{
 194        output_data = NULL;
 195        output_ptr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
 196#ifdef CONFIG_29BIT
 197        output_ptr |= P2SEG;
 198#endif
 199        free_mem_ptr = (unsigned long)&_end;
 200        free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
 201
 202        makecrc();
 203        puts("Uncompressing Linux... ");
 204        gunzip();
 205        puts("Ok, booting the kernel.\n");
 206}
 207
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.