ia64/xen-unstable

view xen/arch/x86/bzimage.c @ 19107:696351cde9a4

Allow memflags to be specified to alloc_xenheap_pages().

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jan 28 16:58:41 2009 +0000 (2009-01-28)
parents 9b0289a165eb
children 1bd06ed9369d
line source
1 #include <xen/cache.h>
2 #include <xen/errno.h>
3 #include <xen/lib.h>
4 #include <xen/mm.h>
5 #include <xen/string.h>
6 #include <xen/types.h>
8 #define HEAPORDER 3
10 static unsigned char *window;
11 #define memptr long
12 static memptr free_mem_ptr;
13 static memptr free_mem_end_ptr;
15 #define WSIZE 0x80000000
17 static unsigned char *inbuf;
18 static unsigned insize;
20 /* Index of next byte to be processed in inbuf: */
21 static unsigned inptr;
23 /* Bytes in output buffer: */
24 static unsigned outcnt;
26 #define OF(args) args
27 #define STATIC static
29 #define memzero(s, n) memset((s), 0, (n))
31 typedef unsigned char uch;
32 typedef unsigned short ush;
33 typedef unsigned long ulg;
35 #define INIT __init
37 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
39 /* Diagnostic functions */
40 #ifdef DEBUG
41 # define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0)
42 # define Trace(x) do { fprintf x; } while (0)
43 # define Tracev(x) do { if (verbose) fprintf x ; } while (0)
44 # define Tracevv(x) do { if (verbose > 1) fprintf x ; } while (0)
45 # define Tracec(c, x) do { if (verbose && (c)) fprintf x ; } while (0)
46 # define Tracecv(c, x) do { if (verbose > 1 && (c)) fprintf x ; } while (0)
47 #else
48 # define Assert(cond, msg)
49 # define Trace(x)
50 # define Tracev(x)
51 # define Tracevv(x)
52 # define Tracec(c, x)
53 # define Tracecv(c, x)
54 #endif
56 static long bytes_out;
57 static void flush_window(void);
59 static __init void error(char *x)
60 {
61 printk("%s\n", x);
62 BUG();
63 }
65 static __init int fill_inbuf(void)
66 {
67 error("ran out of input data");
68 return 0;
69 }
72 #include "../../common/inflate.c"
74 static __init void flush_window(void)
75 {
76 /*
77 * The window is equal to the output buffer therefore only need to
78 * compute the crc.
79 */
80 unsigned long c = crc;
81 unsigned n;
82 unsigned char *in, ch;
84 in = window;
85 for ( n = 0; n < outcnt; n++ )
86 {
87 ch = *in++;
88 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
89 }
90 crc = c;
92 bytes_out += (unsigned long)outcnt;
93 outcnt = 0;
94 }
96 static __init int gzip_length(char *image, unsigned long image_len)
97 {
98 return *(uint32_t *)&image[image_len - 4];
99 }
101 static __init int perform_gunzip(char *output, char **_image_start, unsigned long *image_len)
102 {
103 char *image = *_image_start;
104 int rc;
105 unsigned char magic0 = (unsigned char)image[0];
106 unsigned char magic1 = (unsigned char)image[1];
108 if ( magic0 != 0x1f || ( (magic1 != 0x8b) && (magic1 != 0x9e) ) )
109 return 0;
111 window = (unsigned char *)output;
113 free_mem_ptr = (unsigned long)alloc_xenheap_pages(HEAPORDER, 0);
114 free_mem_end_ptr = free_mem_ptr + (PAGE_SIZE << HEAPORDER);
116 inbuf = (unsigned char *)image;
117 insize = *image_len;
118 inptr = 0;
120 makecrc();
122 if ( gunzip() < 0 )
123 {
124 rc = -EINVAL;
125 }
126 else
127 {
128 *_image_start = (char *)window;
129 *image_len = gzip_length(image, *image_len);
130 rc = 0;
131 }
133 free_xenheap_pages((void *)free_mem_ptr, HEAPORDER);
135 return rc;
136 }
138 struct setup_header {
139 uint8_t _pad0[0x1f1]; /* skip uninteresting stuff */
140 uint8_t setup_sects;
141 uint16_t root_flags;
142 uint32_t syssize;
143 uint16_t ram_size;
144 uint16_t vid_mode;
145 uint16_t root_dev;
146 uint16_t boot_flag;
147 uint16_t jump;
148 uint32_t header;
149 #define HDR_MAGIC "HdrS"
150 #define HDR_MAGIC_SZ 4
151 uint16_t version;
152 #define VERSION(h,l) (((h)<<8) | (l))
153 uint32_t realmode_swtch;
154 uint16_t start_sys;
155 uint16_t kernel_version;
156 uint8_t type_of_loader;
157 uint8_t loadflags;
158 uint16_t setup_move_size;
159 uint32_t code32_start;
160 uint32_t ramdisk_image;
161 uint32_t ramdisk_size;
162 uint32_t bootsect_kludge;
163 uint16_t heap_end_ptr;
164 uint16_t _pad1;
165 uint32_t cmd_line_ptr;
166 uint32_t initrd_addr_max;
167 uint32_t kernel_alignment;
168 uint8_t relocatable_kernel;
169 uint8_t _pad2[3];
170 uint32_t cmdline_size;
171 uint32_t hardware_subarch;
172 uint64_t hardware_subarch_data;
173 uint32_t payload_offset;
174 uint32_t payload_length;
175 } __attribute__((packed));
177 static __init int bzimage_check(struct setup_header *hdr, unsigned long len)
178 {
179 if ( len < sizeof(struct setup_header) )
180 return 0;
182 if ( memcmp(&hdr->header, HDR_MAGIC, HDR_MAGIC_SZ) != 0 )
183 return 0;
185 if ( hdr->version < VERSION(2,8) ) {
186 printk("Cannot load bzImage v%d.%02d at least v2.08 is required\n",
187 hdr->version >> 8, hdr->version & 0xff);
188 return -EINVAL;
189 }
190 return 1;
191 }
193 int __init bzimage_headroom(char *image_start, unsigned long image_length)
194 {
195 struct setup_header *hdr = (struct setup_header *)image_start;
196 char *img;
197 int err, headroom;
199 err = bzimage_check(hdr, image_length);
200 if (err < 1)
201 return err;
203 img = image_start + (hdr->setup_sects+1) * 512;
204 img += hdr->payload_offset;
206 headroom = gzip_length(img, hdr->payload_length);
207 headroom += headroom >> 12; /* Add 8 bytes for every 32K input block */
208 headroom += (32768 + 18); /* Add 32K + 18 bytes of extra headroom */
209 headroom = (headroom + 4095) & ~4095;
211 return headroom;
212 }
214 int __init bzimage_parse(char *image_base, char **image_start, unsigned long *image_len)
215 {
216 struct setup_header *hdr = (struct setup_header *)(*image_start);
217 int err = bzimage_check(hdr, *image_len);
219 if (err < 1)
220 return err;
222 BUG_ON(!(image_base < *image_start));
224 *image_start += (hdr->setup_sects+1) * 512;
225 *image_start += hdr->payload_offset;
226 *image_len = hdr->payload_length;
228 if ( (err = perform_gunzip(image_base, image_start, image_len)) < 0 )
229 return err;
231 return 0;
232 }
234 /*
235 * Local variables:
236 * mode: C
237 * c-set-style: "BSD"
238 * c-basic-offset: 4
239 * tab-width: 4
240 * indent-tabs-mode: nil
241 * End:
242 */