misc.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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