reorder sdk menuconfig entry, so that it does not force the toolchain selection into...
[openwrt.git] / target / linux / image / ar7 / src / loader.c
1 /* inflate.c -- Not copyrighted 1992 by Mark Adler
2    version c10p1, 10 January 1993 */
3
4 /*
5  * Adapted for booting Linux by Hannu Savolainen 1993
6  * based on gzip-1.0.3
7  *
8  * Nicolas Pitre <nico@visuaide.com>, 1999/04/14 :
9  *   Little mods for all variable to reside either into rodata or bss segments
10  *   by marking constant variables with 'const' and initializing all the others
11  *   at run-time only.  This allows for the kernel uncompressor to run
12  *   directly from Flash or ROM memory on embeded systems.
13  */
14
15 #include <linux/config.h>
16 #include "gzip.h"
17 #include "LzmaDecode.h"
18
19 /* Function prototypes */
20 unsigned char get_byte(void);
21 int tikernelunzip(int,char *[], char *[]);
22 static int tidecompress(uch *, uch *);
23
24 void kernel_entry(int, char *[], char *[]);
25 void (*ke)(int, char *[], char *[]); /* Gen reference to kernel function */
26 void (*prnt)(unsigned int, char *);             /* Gen reference to Yamon print function */
27 void printf(char *ptr);                 /* Generate our own printf */
28
29 int tikernelunzip(int argc, char *argv[], char *arge[])
30 {
31         extern unsigned int _ftext;
32         extern uch kernelimage[];
33         uch *in, *out;
34         int status;
35
36         printf("Launching kernel decompressor.\n");
37
38         out = (unsigned char *) LOADADDR;
39         in = &(kernelimage[0]);
40
41         status = tidecompress(in, out);
42
43         if (status == 0) {
44                 printf("Kernel decompressor was successful ... launching kernel.\n");
45
46                 ke = ( void(*)(int, char *[],char*[]))kernel_entry;
47                 (*ke)(argc,argv,arge);
48
49                 return (0);
50         } else {
51                 printf("Error in decompression.\n");
52                 return(1);
53         }
54 }
55
56 #if 0
57 char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
58 void print_i(int i)
59 {
60         int j;
61         char buf[11];
62
63         buf[0] = '0';
64         buf[1] = 'x';
65         buf[10] = 0;
66         
67         for (j = 0; j < 8; j++)
68         {
69                 buf[2 + 7 - j] = hex[i & 0xf];
70                 i = i >> 4;
71         }
72
73         printf(buf);
74 }
75 #endif
76
77 int tidecompress(uch *indata, uch *outdata)
78 {
79         extern unsigned int workspace;
80         extern unsigned char kernelimage[], kernelimage_end[];
81         unsigned int i;  /* temp value */
82         unsigned int lc; /* literal context bits */
83         unsigned int lp; /* literal pos state bits */
84         unsigned int pb; /* pos state bits */
85         unsigned int osize; /* uncompressed size */
86         unsigned int wsize; /* window size */
87         unsigned int insize = kernelimage_end - kernelimage;
88         int status;
89         
90         output_ptr = 0;
91         output_data = outdata;
92         input_data = indata;
93
94         /* lzma args */
95         i = get_byte();
96         lc = i % 9, i = i / 9;
97         lp = i % 5, pb = i / 5;
98
99         /* skip rest of the LZMA coder property */
100         for (i = 0; i < 4; i++)
101                 get_byte();
102         
103         /* read the lower half of uncompressed size in the header */
104         osize = ((unsigned int)get_byte()) +
105                 ((unsigned int)get_byte() << 8) +
106                 ((unsigned int)get_byte() << 16) +
107                 ((unsigned int)get_byte() << 24);
108
109         /* skip rest of the header (upper half of uncompressed size) */
110         for (i = 0; i < 4; i++)
111                 get_byte();
112         
113         i = 0;
114         wsize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb);
115
116         if ((status = LzmaDecode((unsigned char *) &workspace, wsize, lc, lp, pb,
117                 indata + 13, insize - 13, (unsigned char *) output_data, osize, &i)) == LZMA_RESULT_OK)
118                         return 0;
119
120         return status;
121 }
122
123
124 void printf(char *ptr)
125 {
126         unsigned int *tempptr = (unsigned int  *)0x90000534;
127         prnt = ( void (*)(unsigned int, char *)) *tempptr;
128         (*prnt)(0,ptr);
129 }
130
131 unsigned char get_byte()
132 {
133         unsigned char c;
134         
135         c = *input_data;
136         input_data++;
137
138         return c;
139 }
140