ofcommon.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.ofcommon.c 1.2 01/11/02 10:46:07 trini
  3.  *
  4.  * Copyright (C) Paul Mackerras 1997.
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License
  8.  * as published by the Free Software Foundation; either version
  9.  * 2 of the License, or (at your option) any later version.
  10.  */
  11. #include "zlib.h"
  12. #include "nonstdio.h"
  13. #include <asm/bootinfo.h>
  14. #include <asm/page.h>
  15. /* Information from the linker */
  16. extern char __sysmap_begin, __sysmap_end;
  17. extern int strcmp(const char *s1, const char *s2);
  18. extern char *avail_ram, *avail_high;
  19. extern char *end_avail;
  20. extern void claim(unsigned int virt, unsigned int size, unsigned int align);
  21. extern void pause(void);
  22. unsigned int heap_use, heap_max;
  23. struct memchunk {
  24.     unsigned int size;
  25.     struct memchunk *next;
  26. };
  27. static struct memchunk *freechunks;
  28. static void *zalloc(void *x, unsigned items, unsigned size)
  29. {
  30.     void *p;
  31.     struct memchunk **mpp, *mp;
  32.     size *= items;
  33.     size = (size + 7) & -8;
  34.     heap_use += size;
  35.     if (heap_use > heap_max)
  36. heap_max = heap_use;
  37.     for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
  38. if (mp->size == size) {
  39.     *mpp = mp->next;
  40.     return mp;
  41. }
  42.     }
  43.     p = avail_ram;
  44.     avail_ram += size;
  45.     if (avail_ram > avail_high)
  46. avail_high = avail_ram;
  47.     if (avail_ram > end_avail) {
  48. printf("oops... out of memorynr");
  49. pause();
  50.     }
  51.     return p;
  52. }
  53. static void zfree(void *x, void *addr, unsigned nb)
  54. {
  55.     struct memchunk *mp = addr;
  56.     nb = (nb + 7) & -8;
  57.     heap_use -= nb;
  58.     if (avail_ram == addr + nb) {
  59. avail_ram = addr;
  60. return;
  61.     }
  62.     mp->size = nb;
  63.     mp->next = freechunks;
  64.     freechunks = mp;
  65. }
  66. #define HEAD_CRC 2
  67. #define EXTRA_FIELD 4
  68. #define ORIG_NAME 8
  69. #define COMMENT 0x10
  70. #define RESERVED 0xe0
  71. #define DEFLATED 8
  72. void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
  73. {
  74.     z_stream s;
  75.     int r, i, flags;
  76.     /* skip header */
  77.     i = 10;
  78.     flags = src[3];
  79.     if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
  80. printf("bad gzipped datanr");
  81. exit();
  82.     }
  83.     if ((flags & EXTRA_FIELD) != 0)
  84. i = 12 + src[10] + (src[11] << 8);
  85.     if ((flags & ORIG_NAME) != 0)
  86. while (src[i++] != 0)
  87.     ;
  88.     if ((flags & COMMENT) != 0)
  89. while (src[i++] != 0)
  90.     ;
  91.     if ((flags & HEAD_CRC) != 0)
  92. i += 2;
  93.     if (i >= *lenp) {
  94. printf("gunzip: ran out of data in headernr");
  95. exit();
  96.     }
  97.     s.zalloc = zalloc;
  98.     s.zfree = zfree;
  99.     r = inflateInit2(&s, -MAX_WBITS);
  100.     if (r != Z_OK) {
  101. printf("inflateInit2 returned %dnr", r);
  102. exit();
  103.     }
  104.     s.next_in = src + i;
  105.     s.avail_in = *lenp - i;
  106.     s.next_out = dst;
  107.     s.avail_out = dstlen;
  108.     r = inflate(&s, Z_FINISH);
  109.     if (r != Z_OK && r != Z_STREAM_END) {
  110. printf("inflate returned %d msg: %snr", r, s.msg);
  111. exit();
  112.     }
  113.     *lenp = s.next_out - (unsigned char *) dst;
  114.     inflateEnd(&s);
  115. }
  116. /* Make a bi_rec in OF.  We need to be passed a name for BI_BOOTLOADER_ID,
  117.  * a machine type for BI_MACHTYPE, and the location where the end of the
  118.  * bootloader is (PROG_START + PROG_SIZE)
  119.  */
  120. void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
  121. unsigned long progend)
  122. {
  123. unsigned long sysmap_size;
  124. struct bi_record *rec;
  125. /* FIgure out the size of a possible System.map we're going to
  126.  * pass along.
  127.  * */
  128. sysmap_size = (unsigned long)(&__sysmap_end) -
  129. (unsigned long)(&__sysmap_begin);
  130. /* leave a 1MB gap then align to the next 1MB boundary */
  131. addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
  132. /* oldworld machine seem very unhappy about this. -- Tom */
  133. if (addr >= progend)
  134. claim(addr, 0x1000, 0);
  135. rec = (struct bi_record *)addr;
  136. rec->tag = BI_FIRST;
  137. rec->size = sizeof(struct bi_record);
  138. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  139. rec->tag = BI_BOOTLOADER_ID;
  140. sprintf( (char *)rec->data, name);
  141. rec->size = sizeof(struct bi_record) + strlen(name) + 1;
  142. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  143. rec->tag = BI_MACHTYPE;
  144. rec->data[0] = mach;
  145. rec->data[1] = 1;
  146. rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
  147. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  148. if (sysmap_size) {
  149. rec->tag = BI_SYSMAP;
  150. rec->data[0] = (unsigned long)(&__sysmap_begin);
  151. rec->data[1] = sysmap_size;
  152. rec->size = sizeof(struct bi_record) + 2 *
  153. sizeof(unsigned long);
  154. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  155. }
  156. rec->tag = BI_LAST;
  157. rec->size = sizeof(struct bi_record);
  158. rec = (struct bi_record *)((unsigned long)rec + rec->size);
  159. }