linux-old/arch/arm/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 *
   9 * Modified for ARM Linux by Russell King
  10 *
  11 * Nicolas Pitre <nico@visuaide.com>  1999/04/14 :
  12 *  For this code to run directly from Flash, all constant variables must
  13 *  be marked with 'const' and all other variables initialized at run-time 
  14 *  only.  This way all non constant variables will end up in the bss segment,
  15 *  which should point to addresses in RAM and cleared to 0 on start.
  16 *  This allows for a much quicker boot time.
  17 */
  18
  19unsigned int __machine_arch_type;
  20
  21#include <linux/kernel.h>
  22
  23#include <asm/uaccess.h>
  24#include <asm/arch/uncompress.h>
  25
  26#ifdef STANDALONE_DEBUG
  27#define puts printf
  28#endif
  29
  30#define __ptr_t void *
  31
  32/*
  33 * Optimised C version of memzero for the ARM.
  34 */
  35void __memzero (__ptr_t s, size_t n)
  36{
  37        union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
  38        int i;
  39
  40        u.vp = s;
  41
  42        for (i = n >> 5; i > 0; i--) {
  43                *u.ulp++ = 0;
  44                *u.ulp++ = 0;
  45                *u.ulp++ = 0;
  46                *u.ulp++ = 0;
  47                *u.ulp++ = 0;
  48                *u.ulp++ = 0;
  49                *u.ulp++ = 0;
  50                *u.ulp++ = 0;
  51        }
  52
  53        if (n & 1 << 4) {
  54                *u.ulp++ = 0;
  55                *u.ulp++ = 0;
  56                *u.ulp++ = 0;
  57                *u.ulp++ = 0;
  58        }
  59
  60        if (n & 1 << 3) {
  61                *u.ulp++ = 0;
  62                *u.ulp++ = 0;
  63        }
  64
  65        if (n & 1 << 2)
  66                *u.ulp++ = 0;
  67
  68        if (n & 1 << 1) {
  69                *u.ucp++ = 0;
  70                *u.ucp++ = 0;
  71        }
  72
  73        if (n & 1)
  74                *u.ucp++ = 0;
  75}
  76
  77static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
  78                            size_t __n)
  79{
  80        int i = 0;
  81        unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
  82
  83        for (i = __n >> 3; i > 0; i--) {
  84                *d++ = *s++;
  85                *d++ = *s++;
  86                *d++ = *s++;
  87                *d++ = *s++;
  88                *d++ = *s++;
  89                *d++ = *s++;
  90                *d++ = *s++;
  91                *d++ = *s++;
  92        }
  93
  94        if (__n & 1 << 2) {
  95                *d++ = *s++;
  96                *d++ = *s++;
  97                *d++ = *s++;
  98                *d++ = *s++;
  99        }
 100
 101        if (__n & 1 << 1) {
 102                *d++ = *s++;
 103                *d++ = *s++;
 104        }
 105
 106        if (__n & 1)
 107                *d++ = *s++;
 108
 109        return __dest;
 110}
 111
 112/*
 113 * gzip delarations
 114 */
 115#define OF(args)  args
 116#define STATIC static
 117
 118typedef unsigned char  uch;
 119typedef unsigned short ush;
 120typedef unsigned long  ulg;
 121
 122#define WSIZE 0x8000            /* Window size must be at least 32k, */
 123                                /* and a power of two */
 124
 125static uch *inbuf;              /* input buffer */
 126static uch window[WSIZE];       /* Sliding window buffer */
 127
 128static unsigned insize;         /* valid bytes in inbuf */
 129static unsigned inptr;          /* index of next byte to be processed in inbuf */
 130static unsigned outcnt;         /* bytes in output buffer */
 131
 132/* gzip flag byte */
 133#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
 134#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
 135#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
 136#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
 137#define COMMENT      0x10 /* bit 4 set: file comment present */
 138#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
 139#define RESERVED     0xC0 /* bit 6,7:   reserved */
 140
 141#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
 142
 143/* Diagnostic functions */
 144#ifdef DEBUG
 145#  define Assert(cond,msg) {if(!(cond)) error(msg);}
 146#  define Trace(x) fprintf x
 147#  define Tracev(x) {if (verbose) fprintf x ;}
 148#  define Tracevv(x) {if (verbose>1) fprintf x ;}
 149#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
 150#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
 151#else
 152#  define Assert(cond,msg)
 153#  define Trace(x)
 154#  define Tracev(x)
 155#  define Tracevv(x)
 156#  define Tracec(c,x)
 157#  define Tracecv(c,x)
 158#endif
 159
 160static int  fill_inbuf(void);
 161static void flush_window(void);
 162static void error(char *m);
 163static void gzip_mark(void **);
 164static void gzip_release(void **);
 165
 166extern char input_data[];
 167extern char input_data_end[];
 168
 169static uch *output_data;
 170static ulg output_ptr;
 171static ulg bytes_out;
 172
 173static void *malloc(int size);
 174static void free(void *where);
 175static void error(char *m);
 176static void gzip_mark(void **);
 177static void gzip_release(void **);
 178
 179static void puts(const char *);
 180
 181extern int end;
 182static ulg free_mem_ptr;
 183static ulg free_mem_ptr_end;
 184
 185#define HEAP_SIZE 0x2000
 186
 187#include "../../../../lib/inflate.c"
 188
 189#ifndef STANDALONE_DEBUG
 190static void *malloc(int size)
 191{
 192        void *p;
 193
 194        if (size <0) error("Malloc error\n");
 195        if (free_mem_ptr <= 0) error("Memory error\n");
 196
 197        free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
 198
 199        p = (void *)free_mem_ptr;
 200        free_mem_ptr += size;
 201
 202        if (free_mem_ptr >= free_mem_ptr_end)
 203                error("Out of memory");
 204        return p;
 205}
 206
 207static void free(void *where)
 208{ /* gzip_mark & gzip_release do the free */
 209}
 210
 211static void gzip_mark(void **ptr)
 212{
 213        arch_decomp_wdog();
 214        *ptr = (void *) free_mem_ptr;
 215}
 216
 217static void gzip_release(void **ptr)
 218{
 219        arch_decomp_wdog();
 220        free_mem_ptr = (long) *ptr;
 221}
 222#else
 223static void gzip_mark(void **ptr)
 224{
 225}
 226
 227static void gzip_release(void **ptr)
 228{
 229}
 230#endif
 231
 232/* ===========================================================================
 233 * Fill the input buffer. This is called only when the buffer is empty
 234 * and at least one byte is really needed.
 235 */
 236int fill_inbuf(void)
 237{
 238        if (insize != 0)
 239                error("ran out of input data\n");
 240
 241        inbuf = input_data;
 242        insize = &input_data_end[0] - &input_data[0];
 243
 244        inptr = 1;
 245        return inbuf[0];
 246}
 247
 248/* ===========================================================================
 249 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 250 * (Used for the decompressed data only.)
 251 */
 252void flush_window(void)
 253{
 254        ulg c = crc;
 255        unsigned n;
 256        uch *in, *out, ch;
 257
 258        in = window;
 259        out = &output_data[output_ptr];
 260        for (n = 0; n < outcnt; n++) {
 261                ch = *out++ = *in++;
 262                c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
 263        }
 264        crc = c;
 265        bytes_out += (ulg)outcnt;
 266        output_ptr += (ulg)outcnt;
 267        outcnt = 0;
 268        puts(".");
 269}
 270
 271static void error(char *x)
 272{
 273        int ptr;
 274
 275        puts("\n\n");
 276        puts(x);
 277        puts("\n\n -- System halted");
 278
 279        while(1);       /* Halt */
 280}
 281
 282#ifndef STANDALONE_DEBUG
 283
 284ulg
 285decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
 286                  int arch_id)
 287{
 288        output_data             = (uch *)output_start;  /* Points to kernel start */
 289        free_mem_ptr            = free_mem_ptr_p;
 290        free_mem_ptr_end        = free_mem_ptr_end_p;
 291        __machine_arch_type     = arch_id;
 292
 293        arch_decomp_setup();
 294
 295        makecrc();
 296        puts("Uncompressing Linux...");
 297        gunzip();
 298        puts(" done, booting the kernel.\n");
 299        return output_ptr;
 300}
 301#else
 302
 303char output_buffer[1500*1024];
 304
 305int main()
 306{
 307        output_data = output_buffer;
 308
 309        makecrc();
 310        puts("Uncompressing Linux...");
 311        gunzip();
 312        puts("done.\n");
 313        return 0;
 314}
 315#endif
 316
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.