Indentation fix, cleanup.
[AROS.git] / arch / all-pc / boot / grub2-aros / util / mkimage.c
blobbccd70388afa3122d6879278629321b22cf69f86
1 /* grub-mkimage.c - make a bootable image */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
21 #include <grub/types.h>
22 #include <grub/elf.h>
23 #include <grub/aout.h>
24 #include <grub/i18n.h>
25 #include <grub/kernel.h>
26 #include <grub/disk.h>
27 #include <grub/emu/misc.h>
28 #include <grub/util/misc.h>
29 #include <grub/util/resolve.h>
30 #include <grub/misc.h>
31 #include <grub/offsets.h>
32 #include <grub/crypto.h>
33 #include <grub/dl.h>
34 #include <time.h>
35 #include <multiboot.h>
37 #include <stdio.h>
38 #include <unistd.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <assert.h>
42 #include <grub/efi/pe32.h>
43 #include <grub/uboot/image.h>
44 #include <grub/arm/reloc.h>
45 #include <grub/arm64/reloc.h>
46 #include <grub/ia64/reloc.h>
47 #include <grub/osdep/hostfile.h>
48 #include <grub/util/install.h>
50 #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
52 #ifdef USE_LIBLZMA
53 #include <lzma.h>
54 #endif
56 #define TARGET_NO_FIELD 0xffffffff
58 struct grub_install_image_target_desc
60 const char *dirname;
61 const char *names[6];
62 grub_size_t voidp_sizeof;
63 int bigendian;
64 enum {
65 IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT,
66 IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_SPARC64_CDCORE,
67 IMAGE_I386_IEEE1275,
68 IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH,
69 IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC,
70 IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO
71 } id;
72 enum
74 PLATFORM_FLAGS_NONE = 0,
75 PLATFORM_FLAGS_DECOMPRESSORS = 2,
76 PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4,
77 } flags;
78 unsigned total_module_size;
79 unsigned decompressor_compressed_size;
80 unsigned decompressor_uncompressed_size;
81 unsigned decompressor_uncompressed_addr;
82 unsigned link_align;
83 grub_uint16_t elf_target;
84 unsigned section_align;
85 signed vaddr_offset;
86 grub_uint64_t link_addr;
87 unsigned mod_gap, mod_align;
88 grub_compression_t default_compression;
89 grub_uint16_t pe_target;
92 #define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
93 + GRUB_PE32_SIGNATURE_SIZE \
94 + sizeof (struct grub_pe32_coff_header) \
95 + sizeof (struct grub_pe32_optional_header) \
96 + 4 * sizeof (struct grub_pe32_section_table), \
97 GRUB_PE32_SECTION_ALIGNMENT)
99 #define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
100 + GRUB_PE32_SIGNATURE_SIZE \
101 + sizeof (struct grub_pe32_coff_header) \
102 + sizeof (struct grub_pe64_optional_header) \
103 + 4 * sizeof (struct grub_pe32_section_table), \
104 GRUB_PE32_SECTION_ALIGNMENT)
106 static const struct grub_install_image_target_desc image_targets[] =
109 .dirname = "i386-coreboot",
110 .names = { "i386-coreboot", NULL },
111 .voidp_sizeof = 4,
112 .bigendian = 0,
113 .id = IMAGE_COREBOOT,
114 .flags = PLATFORM_FLAGS_NONE,
115 .total_module_size = TARGET_NO_FIELD,
116 .decompressor_compressed_size = TARGET_NO_FIELD,
117 .decompressor_uncompressed_size = TARGET_NO_FIELD,
118 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
119 .section_align = 1,
120 .vaddr_offset = 0,
121 .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR,
122 .elf_target = EM_386,
123 .link_align = 4,
124 .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP,
125 .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
128 .dirname = "i386-multiboot",
129 .names = { "i386-multiboot", NULL},
130 .voidp_sizeof = 4,
131 .bigendian = 0,
132 .id = IMAGE_COREBOOT,
133 .flags = PLATFORM_FLAGS_NONE,
134 .total_module_size = TARGET_NO_FIELD,
135 .decompressor_compressed_size = TARGET_NO_FIELD,
136 .decompressor_uncompressed_size = TARGET_NO_FIELD,
137 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
138 .section_align = 1,
139 .vaddr_offset = 0,
140 .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR,
141 .elf_target = EM_386,
142 .link_align = 4,
143 .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP,
144 .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
147 .dirname = "i386-pc",
148 .names = { "i386-pc", NULL },
149 .voidp_sizeof = 4,
150 .bigendian = 0,
151 .id = IMAGE_I386_PC,
152 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
153 .total_module_size = TARGET_NO_FIELD,
154 .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
155 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
156 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
157 .section_align = 1,
158 .vaddr_offset = 0,
159 .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
160 .default_compression = GRUB_COMPRESSION_LZMA
163 .dirname = "i386-pc",
164 .names = { "i386-pc-pxe", NULL },
165 .voidp_sizeof = 4,
166 .bigendian = 0,
167 .id = IMAGE_I386_PC_PXE,
168 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
169 .total_module_size = TARGET_NO_FIELD,
170 .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
171 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
172 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
173 .section_align = 1,
174 .vaddr_offset = 0,
175 .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
176 .default_compression = GRUB_COMPRESSION_LZMA
179 .dirname = "i386-pc",
180 .names = { "i386-pc-eltorito", NULL },
181 .voidp_sizeof = 4,
182 .bigendian = 0,
183 .id = IMAGE_I386_PC_ELTORITO,
184 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
185 .total_module_size = TARGET_NO_FIELD,
186 .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
187 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
188 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
189 .section_align = 1,
190 .vaddr_offset = 0,
191 .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
192 .default_compression = GRUB_COMPRESSION_LZMA
195 .dirname = "i386-efi",
196 .names = { "i386-efi", NULL },
197 .voidp_sizeof = 4,
198 .bigendian = 0,
199 .id = IMAGE_EFI,
200 .flags = PLATFORM_FLAGS_NONE,
201 .total_module_size = TARGET_NO_FIELD,
202 .decompressor_compressed_size = TARGET_NO_FIELD,
203 .decompressor_uncompressed_size = TARGET_NO_FIELD,
204 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
205 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
206 .vaddr_offset = EFI32_HEADER_SIZE,
207 .pe_target = GRUB_PE32_MACHINE_I386,
208 .elf_target = EM_386,
211 .dirname = "i386-ieee1275",
212 .names = { "i386-ieee1275", NULL },
213 .voidp_sizeof = 4,
214 .bigendian = 0,
215 .id = IMAGE_I386_IEEE1275,
216 .flags = PLATFORM_FLAGS_NONE,
217 .total_module_size = TARGET_NO_FIELD,
218 .decompressor_compressed_size = TARGET_NO_FIELD,
219 .decompressor_uncompressed_size = TARGET_NO_FIELD,
220 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
221 .section_align = 1,
222 .vaddr_offset = 0,
223 .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR,
224 .elf_target = EM_386,
225 .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP,
226 .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN,
227 .link_align = 4,
230 .dirname = "i386-qemu",
231 .names = { "i386-qemu", NULL },
232 .voidp_sizeof = 4,
233 .bigendian = 0,
234 .id = IMAGE_QEMU,
235 .flags = PLATFORM_FLAGS_NONE,
236 .total_module_size = TARGET_NO_FIELD,
237 .decompressor_compressed_size = TARGET_NO_FIELD,
238 .decompressor_uncompressed_size = TARGET_NO_FIELD,
239 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
240 .section_align = 1,
241 .vaddr_offset = 0,
242 .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR
245 .dirname = "x86_64-efi",
246 .names = { "x86_64-efi", NULL },
247 .voidp_sizeof = 8,
248 .bigendian = 0,
249 .id = IMAGE_EFI,
250 .flags = PLATFORM_FLAGS_NONE,
251 .total_module_size = TARGET_NO_FIELD,
252 .decompressor_compressed_size = TARGET_NO_FIELD,
253 .decompressor_uncompressed_size = TARGET_NO_FIELD,
254 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
255 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
256 .vaddr_offset = EFI64_HEADER_SIZE,
257 .pe_target = GRUB_PE32_MACHINE_X86_64,
258 .elf_target = EM_X86_64,
261 .dirname = "i386-xen",
262 .names = { "i386-xen", NULL },
263 .voidp_sizeof = 4,
264 .bigendian = 0,
265 .id = IMAGE_XEN,
266 .flags = PLATFORM_FLAGS_NONE,
267 .total_module_size = TARGET_NO_FIELD,
268 .decompressor_compressed_size = TARGET_NO_FIELD,
269 .decompressor_uncompressed_size = TARGET_NO_FIELD,
270 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
271 .section_align = 1,
272 .vaddr_offset = 0,
273 .link_addr = 0,
274 .elf_target = EM_386,
275 .mod_gap = GRUB_KERNEL_I386_XEN_MOD_GAP,
276 .mod_align = GRUB_KERNEL_I386_XEN_MOD_ALIGN,
277 .link_align = 4
280 .dirname = "x86_64-xen",
281 .names = { "x86_64-xen", NULL },
282 .voidp_sizeof = 8,
283 .bigendian = 0,
284 .id = IMAGE_XEN,
285 .flags = PLATFORM_FLAGS_NONE,
286 .total_module_size = TARGET_NO_FIELD,
287 .decompressor_compressed_size = TARGET_NO_FIELD,
288 .decompressor_uncompressed_size = TARGET_NO_FIELD,
289 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
290 .section_align = 1,
291 .vaddr_offset = 0,
292 .link_addr = 0,
293 .elf_target = EM_X86_64,
294 .mod_gap = GRUB_KERNEL_X86_64_XEN_MOD_GAP,
295 .mod_align = GRUB_KERNEL_X86_64_XEN_MOD_ALIGN,
296 .link_align = 8
299 .dirname = "mipsel-loongson",
300 .names = { "mipsel-yeeloong-flash", NULL },
301 .voidp_sizeof = 4,
302 .bigendian = 0,
303 .id = IMAGE_YEELOONG_FLASH,
304 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
305 .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
306 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
307 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
308 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
309 .section_align = 1,
310 .vaddr_offset = 0,
311 .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
312 .elf_target = EM_MIPS,
313 .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
314 .default_compression = GRUB_COMPRESSION_NONE
317 .dirname = "mipsel-loongson",
318 .names = { "mipsel-fuloong2f-flash", NULL },
319 .voidp_sizeof = 4,
320 .bigendian = 0,
321 .id = IMAGE_FULOONG2F_FLASH,
322 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
323 .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
324 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
325 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
326 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
327 .section_align = 1,
328 .vaddr_offset = 0,
329 .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
330 .elf_target = EM_MIPS,
331 .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
332 .default_compression = GRUB_COMPRESSION_NONE
335 .dirname = "mipsel-loongson",
336 .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf",
337 "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf",
338 "mipsel-fuloong-elf", NULL },
339 .voidp_sizeof = 4,
340 .bigendian = 0,
341 .id = IMAGE_LOONGSON_ELF,
342 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
343 .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
344 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
345 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
346 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
347 .section_align = 1,
348 .vaddr_offset = 0,
349 .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
350 .elf_target = EM_MIPS,
351 .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
352 .default_compression = GRUB_COMPRESSION_NONE
355 .dirname = "powerpc-ieee1275",
356 .names = { "powerpc-ieee1275", NULL },
357 .voidp_sizeof = 4,
358 .bigendian = 1,
359 .id = IMAGE_PPC,
360 .flags = PLATFORM_FLAGS_NONE,
361 .total_module_size = TARGET_NO_FIELD,
362 .decompressor_compressed_size = TARGET_NO_FIELD,
363 .decompressor_uncompressed_size = TARGET_NO_FIELD,
364 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
365 .section_align = 1,
366 .vaddr_offset = 0,
367 .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR,
368 .elf_target = EM_PPC,
369 .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP,
370 .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN,
371 .link_align = 4
374 .dirname = "sparc64-ieee1275",
375 .names = { "sparc64-ieee1275-raw", NULL },
376 .voidp_sizeof = 8,
377 .bigendian = 1,
378 .id = IMAGE_SPARC64_RAW,
379 .flags = PLATFORM_FLAGS_NONE,
380 .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
381 .decompressor_compressed_size = TARGET_NO_FIELD,
382 .decompressor_uncompressed_size = TARGET_NO_FIELD,
383 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
384 .section_align = 1,
385 .vaddr_offset = 0,
386 .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
387 .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
390 .dirname = "sparc64-ieee1275",
391 .names = { "sparc64-ieee1275-cdcore", NULL },
392 .voidp_sizeof = 8,
393 .bigendian = 1,
394 .id = IMAGE_SPARC64_CDCORE,
395 .flags = PLATFORM_FLAGS_NONE,
396 .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
397 .decompressor_compressed_size = TARGET_NO_FIELD,
398 .decompressor_uncompressed_size = TARGET_NO_FIELD,
399 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
400 .section_align = 1,
401 .vaddr_offset = 0,
402 .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
403 .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
406 .dirname = "sparc64-ieee1275",
407 .names = { "sparc64-ieee1275-aout", NULL },
408 .voidp_sizeof = 8,
409 .bigendian = 1,
410 .id = IMAGE_SPARC64_AOUT,
411 .flags = PLATFORM_FLAGS_NONE,
412 .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
413 .decompressor_compressed_size = TARGET_NO_FIELD,
414 .decompressor_uncompressed_size = TARGET_NO_FIELD,
415 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
416 .section_align = 1,
417 .vaddr_offset = 0,
418 .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
419 .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
422 .dirname = "ia64-efi",
423 .names = {"ia64-efi", NULL},
424 .voidp_sizeof = 8,
425 .bigendian = 0,
426 .id = IMAGE_EFI,
427 .flags = PLATFORM_FLAGS_NONE,
428 .total_module_size = TARGET_NO_FIELD,
429 .decompressor_compressed_size = TARGET_NO_FIELD,
430 .decompressor_uncompressed_size = TARGET_NO_FIELD,
431 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
432 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
433 .vaddr_offset = EFI64_HEADER_SIZE,
434 .pe_target = GRUB_PE32_MACHINE_IA64,
435 .elf_target = EM_IA_64,
438 .dirname = "mips-arc",
439 .names = {"mips-arc", NULL},
440 .voidp_sizeof = 4,
441 .bigendian = 1,
442 .id = IMAGE_MIPS_ARC,
443 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
444 .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE,
445 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
446 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
447 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
448 .section_align = 1,
449 .vaddr_offset = 0,
450 .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR,
451 .elf_target = EM_MIPS,
452 .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN,
453 .default_compression = GRUB_COMPRESSION_NONE
456 .dirname = "mipsel-arc",
457 .names = {"mipsel-arc", NULL},
458 .voidp_sizeof = 4,
459 .bigendian = 0,
460 .id = IMAGE_MIPS_ARC,
461 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
462 .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE,
463 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
464 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
465 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
466 .section_align = 1,
467 .vaddr_offset = 0,
468 .link_addr = GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR,
469 .elf_target = EM_MIPS,
470 .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN,
471 .default_compression = GRUB_COMPRESSION_NONE
474 .dirname = "mipsel-qemu_mips",
475 .names = { "mipsel-qemu_mips-elf", NULL },
476 .voidp_sizeof = 4,
477 .bigendian = 0,
478 .id = IMAGE_LOONGSON_ELF,
479 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
480 .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
481 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
482 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
483 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
484 .section_align = 1,
485 .vaddr_offset = 0,
486 .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
487 .elf_target = EM_MIPS,
488 .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
489 .default_compression = GRUB_COMPRESSION_NONE
492 .dirname = "mips-qemu_mips",
493 .names = { "mips-qemu_mips-flash", NULL },
494 .voidp_sizeof = 4,
495 .bigendian = 1,
496 .id = IMAGE_QEMU_MIPS_FLASH,
497 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
498 .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
499 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
500 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
501 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
502 .section_align = 1,
503 .vaddr_offset = 0,
504 .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
505 .elf_target = EM_MIPS,
506 .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
507 .default_compression = GRUB_COMPRESSION_NONE
510 .dirname = "mipsel-qemu_mips",
511 .names = { "mipsel-qemu_mips-flash", NULL },
512 .voidp_sizeof = 4,
513 .bigendian = 0,
514 .id = IMAGE_QEMU_MIPS_FLASH,
515 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
516 .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
517 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
518 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
519 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
520 .section_align = 1,
521 .vaddr_offset = 0,
522 .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
523 .elf_target = EM_MIPS,
524 .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
525 .default_compression = GRUB_COMPRESSION_NONE
528 .dirname = "mips-qemu_mips",
529 .names = { "mips-qemu_mips-elf", NULL },
530 .voidp_sizeof = 4,
531 .bigendian = 1,
532 .id = IMAGE_LOONGSON_ELF,
533 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
534 .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
535 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
536 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
537 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
538 .section_align = 1,
539 .vaddr_offset = 0,
540 .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
541 .elf_target = EM_MIPS,
542 .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
543 .default_compression = GRUB_COMPRESSION_NONE
546 .dirname = "arm-uboot",
547 .names = { "arm-uboot", NULL },
548 .voidp_sizeof = 4,
549 .bigendian = 0,
550 .id = IMAGE_UBOOT,
551 .flags = PLATFORM_FLAGS_NONE,
552 .total_module_size = GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE,
553 .decompressor_compressed_size = TARGET_NO_FIELD,
554 .decompressor_uncompressed_size = TARGET_NO_FIELD,
555 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
556 .section_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
557 .vaddr_offset = 0,
558 .link_addr = GRUB_KERNEL_ARM_UBOOT_LINK_ADDR,
559 .elf_target = EM_ARM,
560 .mod_gap = GRUB_KERNEL_ARM_UBOOT_MOD_GAP,
561 .mod_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
562 .link_align = 4
565 .dirname = "arm-efi",
566 .names = { "arm-efi", NULL },
567 .voidp_sizeof = 4,
568 .bigendian = 0,
569 .id = IMAGE_EFI,
570 .flags = PLATFORM_FLAGS_NONE,
571 .total_module_size = TARGET_NO_FIELD,
572 .decompressor_compressed_size = TARGET_NO_FIELD,
573 .decompressor_uncompressed_size = TARGET_NO_FIELD,
574 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
575 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
576 .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE
577 + GRUB_PE32_SIGNATURE_SIZE
578 + sizeof (struct grub_pe32_coff_header)
579 + sizeof (struct grub_pe32_optional_header)
580 + 4 * sizeof (struct grub_pe32_section_table),
581 GRUB_PE32_SECTION_ALIGNMENT),
582 .pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED,
583 .elf_target = EM_ARM,
586 .dirname = "arm64-efi",
587 .names = { "arm64-efi", NULL },
588 .voidp_sizeof = 8,
589 .bigendian = 0,
590 .id = IMAGE_EFI,
591 .flags = PLATFORM_FLAGS_NONE,
592 .total_module_size = TARGET_NO_FIELD,
593 .decompressor_compressed_size = TARGET_NO_FIELD,
594 .decompressor_uncompressed_size = TARGET_NO_FIELD,
595 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
596 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
597 .vaddr_offset = EFI64_HEADER_SIZE,
598 .pe_target = GRUB_PE32_MACHINE_ARM64,
599 .elf_target = EM_AARCH64,
603 #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x)))
604 #define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x)))
605 #define grub_target_to_host64(x) (grub_target_to_host64_real (image_target, (x)))
606 #define grub_host_to_target64(x) (grub_host_to_target64_real (image_target, (x)))
607 #define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (image_target, (x)))
608 #define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x)))
609 #define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x)))
611 static inline grub_uint32_t
612 grub_target_to_host32_real (const struct grub_install_image_target_desc *image_target,
613 grub_uint32_t in)
615 if (image_target->bigendian)
616 return grub_be_to_cpu32 (in);
617 else
618 return grub_le_to_cpu32 (in);
621 static inline grub_uint64_t
622 grub_target_to_host64_real (const struct grub_install_image_target_desc *image_target,
623 grub_uint64_t in)
625 if (image_target->bigendian)
626 return grub_be_to_cpu64 (in);
627 else
628 return grub_le_to_cpu64 (in);
631 static inline grub_uint64_t
632 grub_host_to_target64_real (const struct grub_install_image_target_desc *image_target,
633 grub_uint64_t in)
635 if (image_target->bigendian)
636 return grub_cpu_to_be64 (in);
637 else
638 return grub_cpu_to_le64 (in);
641 static inline grub_uint32_t
642 grub_host_to_target32_real (const struct grub_install_image_target_desc *image_target,
643 grub_uint32_t in)
645 if (image_target->bigendian)
646 return grub_cpu_to_be32 (in);
647 else
648 return grub_cpu_to_le32 (in);
651 static inline grub_uint16_t
652 grub_target_to_host16_real (const struct grub_install_image_target_desc *image_target,
653 grub_uint16_t in)
655 if (image_target->bigendian)
656 return grub_be_to_cpu16 (in);
657 else
658 return grub_le_to_cpu16 (in);
661 static inline grub_uint16_t
662 grub_host_to_target16_real (const struct grub_install_image_target_desc *image_target,
663 grub_uint16_t in)
665 if (image_target->bigendian)
666 return grub_cpu_to_be16 (in);
667 else
668 return grub_cpu_to_le16 (in);
671 static inline grub_uint64_t
672 grub_host_to_target_addr_real (const struct grub_install_image_target_desc *image_target, grub_uint64_t in)
674 if (image_target->voidp_sizeof == 8)
675 return grub_host_to_target64_real (image_target, in);
676 else
677 return grub_host_to_target32_real (image_target, in);
680 static inline grub_uint64_t
681 grub_target_to_host_real (const struct grub_install_image_target_desc *image_target, grub_uint64_t in)
683 if (image_target->voidp_sizeof == 8)
684 return grub_target_to_host64_real (image_target, in);
685 else
686 return grub_target_to_host32_real (image_target, in);
689 #define GRUB_IEEE1275_NOTE_NAME "PowerPC"
690 #define GRUB_IEEE1275_NOTE_TYPE 0x1275
692 /* These structures are defined according to the CHRP binding to IEEE1275,
693 "Client Program Format" section. */
695 struct grub_ieee1275_note_desc
697 grub_uint32_t real_mode;
698 grub_uint32_t real_base;
699 grub_uint32_t real_size;
700 grub_uint32_t virt_base;
701 grub_uint32_t virt_size;
702 grub_uint32_t load_base;
705 struct grub_ieee1275_note
707 Elf32_Nhdr header;
708 char name[ALIGN_UP(sizeof (GRUB_IEEE1275_NOTE_NAME), 4)];
709 struct grub_ieee1275_note_desc descriptor;
712 #define GRUB_XEN_NOTE_NAME "Xen"
714 #define grub_target_to_host(val) grub_target_to_host_real(image_target, (val))
716 #include <grub/lib/LzmaEnc.h>
718 static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return xmalloc(size); }
719 static void SzFree(void *p __attribute__ ((unused)), void *address) { free(address); }
720 static ISzAlloc g_Alloc = { SzAlloc, SzFree };
722 static void
723 compress_kernel_lzma (char *kernel_img, size_t kernel_size,
724 char **core_img, size_t *core_size)
726 CLzmaEncProps props;
727 unsigned char out_props[5];
728 size_t out_props_size = 5;
730 LzmaEncProps_Init(&props);
731 props.dictSize = 1 << 16;
732 props.lc = 3;
733 props.lp = 0;
734 props.pb = 2;
735 props.numThreads = 1;
737 *core_img = xmalloc (kernel_size);
739 *core_size = kernel_size;
740 if (LzmaEncode ((unsigned char *) *core_img, core_size,
741 (unsigned char *) kernel_img,
742 kernel_size,
743 &props, out_props, &out_props_size,
744 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK)
745 grub_util_error ("%s", _("cannot compress the kernel image"));
748 #ifdef USE_LIBLZMA
749 static void
750 compress_kernel_xz (char *kernel_img, size_t kernel_size,
751 char **core_img, size_t *core_size)
753 lzma_stream strm = LZMA_STREAM_INIT;
754 lzma_ret xzret;
755 lzma_options_lzma lzopts = {
756 .dict_size = 1 << 16,
757 .preset_dict = NULL,
758 .preset_dict_size = 0,
759 .lc = 3,
760 .lp = 0,
761 .pb = 2,
762 .mode = LZMA_MODE_NORMAL,
763 .nice_len = 64,
764 .mf = LZMA_MF_BT4,
765 .depth = 0,
767 lzma_filter fltrs[] = {
768 { .id = LZMA_FILTER_LZMA2, .options = &lzopts},
769 { .id = LZMA_VLI_UNKNOWN, .options = NULL}
772 xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE);
773 if (xzret != LZMA_OK)
774 grub_util_error ("%s", _("cannot compress the kernel image"));
776 *core_img = xmalloc (kernel_size);
778 *core_size = kernel_size;
779 strm.next_in = (unsigned char *) kernel_img;
780 strm.avail_in = kernel_size;
781 strm.next_out = (unsigned char *) *core_img;
782 strm.avail_out = *core_size;
784 while (1)
786 xzret = lzma_code (&strm, LZMA_FINISH);
787 if (xzret == LZMA_OK)
788 continue;
789 if (xzret == LZMA_STREAM_END)
790 break;
791 grub_util_error ("%s", _("cannot compress the kernel image"));
794 *core_size -= strm.avail_out;
796 #endif
798 static void
799 compress_kernel (const struct grub_install_image_target_desc *image_target, char *kernel_img,
800 size_t kernel_size, char **core_img, size_t *core_size,
801 grub_compression_t comp)
803 if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
804 && (comp == GRUB_COMPRESSION_LZMA))
806 compress_kernel_lzma (kernel_img, kernel_size, core_img,
807 core_size);
808 return;
811 #ifdef USE_LIBLZMA
812 if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
813 && (comp == GRUB_COMPRESSION_XZ))
815 compress_kernel_xz (kernel_img, kernel_size, core_img,
816 core_size);
817 return;
819 #endif
821 if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
822 && (comp != GRUB_COMPRESSION_NONE))
823 grub_util_error (_("unknown compression %d\n"), comp);
825 *core_img = xmalloc (kernel_size);
826 memcpy (*core_img, kernel_img, kernel_size);
827 *core_size = kernel_size;
830 struct fixup_block_list
832 struct fixup_block_list *next;
833 int state;
834 struct grub_pe32_fixup_block b;
838 * R_ARM_THM_CALL/THM_JUMP24
840 * Relocate Thumb (T32) instruction set relative branches:
841 * B.W, BL and BLX
843 static grub_err_t
844 grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
846 grub_int32_t offset;
848 offset = grub_arm_thm_call_get_offset (target);
850 grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr);
852 offset += sym_addr;
854 grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n",
855 target, sym_addr, offset);
857 /* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel
858 is bigger than 2M (currently under 150K) then we probably have a problem
859 somewhere else. */
860 if (offset < -0x200000 || offset >= 0x200000)
861 return grub_error (GRUB_ERR_BAD_MODULE,
862 "THM_CALL Relocation out of range.");
864 grub_dprintf ("dl", " relative destination = %p",
865 (char *) target + offset);
867 return grub_arm_thm_call_set_offset (target, offset);
871 * R_ARM_THM_JUMP19
873 * Relocate conditional Thumb (T32) B<c>.W
875 static grub_err_t
876 grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr)
878 grub_int32_t offset;
880 if (!(sym_addr & 1))
881 return grub_error (GRUB_ERR_BAD_MODULE,
882 "Relocation targeting wrong execution state");
884 offset = grub_arm_thm_jump19_get_offset (target);
886 /* Adjust and re-truncate offset */
887 offset += sym_addr;
889 if (!grub_arm_thm_jump19_check_offset (offset))
890 return grub_error (GRUB_ERR_BAD_MODULE,
891 "THM_JUMP19 Relocation out of range.");
893 grub_arm_thm_jump19_set_offset (target, offset);
895 return GRUB_ERR_NONE;
899 * R_ARM_JUMP24
901 * Relocate ARM (A32) B
903 static grub_err_t
904 grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
906 grub_int32_t offset;
908 if (sym_addr & 1)
909 return grub_error (GRUB_ERR_BAD_MODULE,
910 "Relocation targeting wrong execution state");
912 offset = grub_arm_jump24_get_offset (target);
913 offset += sym_addr;
915 if (!grub_arm_jump24_check_offset (offset))
916 return grub_error (GRUB_ERR_BAD_MODULE,
917 "JUMP24 Relocation out of range.");
920 grub_arm_jump24_set_offset (target, offset);
922 return GRUB_ERR_NONE;
925 #pragma GCC diagnostic ignored "-Wcast-align"
927 #define MKIMAGE_ELF32 1
928 #include "grub-mkimagexx.c"
929 #undef MKIMAGE_ELF32
931 #define MKIMAGE_ELF64 1
932 #include "grub-mkimagexx.c"
933 #undef MKIMAGE_ELF64
935 const struct grub_install_image_target_desc *
936 grub_install_get_image_target (const char *arg)
938 unsigned i, j;
939 for (i = 0; i < ARRAY_SIZE (image_targets); i++)
940 for (j = 0; image_targets[i].names[j]
941 && j < ARRAY_SIZE (image_targets[i].names); j++)
942 if (strcmp (arg, image_targets[i].names[j]) == 0)
943 return &image_targets[i];
944 return NULL;
947 const char *
948 grub_util_get_target_dirname (const struct grub_install_image_target_desc *t)
950 return t->dirname;
953 const char *
954 grub_util_get_target_name (const struct grub_install_image_target_desc *t)
956 return t->names[0];
959 char *
960 grub_install_get_image_targets_string (void)
962 int format_len = 0;
963 char *formats;
964 char *ptr;
965 unsigned i;
966 for (i = 0; i < ARRAY_SIZE (image_targets); i++)
967 format_len += strlen (image_targets[i].names[0]) + 2;
968 ptr = formats = xmalloc (format_len);
969 for (i = 0; i < ARRAY_SIZE (image_targets); i++)
971 strcpy (ptr, image_targets[i].names[0]);
972 ptr += strlen (image_targets[i].names[0]);
973 *ptr++ = ',';
974 *ptr++ = ' ';
976 ptr[-2] = 0;
978 return formats;
981 void
982 grub_install_generate_image (const char *dir, const char *prefix,
983 FILE *out, const char *outname, char *mods[],
984 char *memdisk_path, char **pubkey_paths,
985 size_t npubkeys, char *config_path,
986 const struct grub_install_image_target_desc *image_target,
987 int note,
988 grub_compression_t comp)
990 char *kernel_img, *core_img;
991 size_t kernel_size, total_module_size, core_size, exec_size;
992 size_t memdisk_size = 0, config_size = 0, config_size_pure = 0;
993 size_t prefix_size = 0;
994 char *kernel_path;
995 size_t offset;
996 struct grub_util_path_list *path_list, *p, *next;
997 size_t bss_size;
998 grub_uint64_t start_address;
999 void *rel_section = 0;
1000 size_t reloc_size = 0, align;
1001 size_t decompress_size = 0;
1003 if (comp == GRUB_COMPRESSION_AUTO)
1004 comp = image_target->default_compression;
1006 if (image_target->id == IMAGE_I386_PC
1007 || image_target->id == IMAGE_I386_PC_PXE
1008 || image_target->id == IMAGE_I386_PC_ELTORITO)
1009 comp = GRUB_COMPRESSION_LZMA;
1011 path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
1013 kernel_path = grub_util_get_path (dir, "kernel.img");
1015 if (image_target->voidp_sizeof == 8)
1016 total_module_size = sizeof (struct grub_module_info64);
1017 else
1018 total_module_size = sizeof (struct grub_module_info32);
1021 size_t i;
1022 for (i = 0; i < npubkeys; i++)
1024 size_t curs;
1025 curs = ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i]));
1026 grub_util_info ("the size of public key %u is 0x%"
1027 GRUB_HOST_PRIxLONG_LONG,
1028 (unsigned) i, (unsigned long long) curs);
1029 total_module_size += curs + sizeof (struct grub_module_header);
1033 if (memdisk_path)
1035 memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
1036 grub_util_info ("the size of memory disk is 0x%" GRUB_HOST_PRIxLONG_LONG,
1037 (unsigned long long) memdisk_size);
1038 total_module_size += memdisk_size + sizeof (struct grub_module_header);
1041 if (config_path)
1043 config_size_pure = grub_util_get_image_size (config_path) + 1;
1044 config_size = ALIGN_ADDR (config_size_pure);
1045 grub_util_info ("the size of config file is 0x%" GRUB_HOST_PRIxLONG_LONG,
1046 (unsigned long long) config_size);
1047 total_module_size += config_size + sizeof (struct grub_module_header);
1050 if (prefix)
1052 prefix_size = ALIGN_ADDR (strlen (prefix) + 1);
1053 total_module_size += prefix_size + sizeof (struct grub_module_header);
1056 for (p = path_list; p; p = p->next)
1057 total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name))
1058 + sizeof (struct grub_module_header));
1060 grub_util_info ("the total module size is 0x%" GRUB_HOST_PRIxLONG_LONG,
1061 (unsigned long long) total_module_size);
1063 if (image_target->voidp_sizeof == 4)
1064 kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size,
1065 total_module_size, &start_address, &rel_section,
1066 &reloc_size, &align, image_target);
1067 else
1068 kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size,
1069 total_module_size, &start_address, &rel_section,
1070 &reloc_size, &align, image_target);
1071 if (image_target->id == IMAGE_XEN && align < 4096)
1072 align = 4096;
1074 if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
1075 && (image_target->total_module_size != TARGET_NO_FIELD))
1076 *((grub_uint32_t *) (kernel_img + image_target->total_module_size))
1077 = grub_host_to_target32 (total_module_size);
1079 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
1080 memmove (kernel_img + total_module_size, kernel_img, kernel_size);
1082 if (image_target->voidp_sizeof == 8)
1084 /* Fill in the grub_module_info structure. */
1085 struct grub_module_info64 *modinfo;
1086 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
1087 modinfo = (struct grub_module_info64 *) kernel_img;
1088 else
1089 modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size);
1090 memset (modinfo, 0, sizeof (struct grub_module_info64));
1091 modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
1092 modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64));
1093 modinfo->size = grub_host_to_target_addr (total_module_size);
1094 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
1095 offset = sizeof (struct grub_module_info64);
1096 else
1097 offset = kernel_size + sizeof (struct grub_module_info64);
1099 else
1101 /* Fill in the grub_module_info structure. */
1102 struct grub_module_info32 *modinfo;
1103 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
1104 modinfo = (struct grub_module_info32 *) kernel_img;
1105 else
1106 modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size);
1107 memset (modinfo, 0, sizeof (struct grub_module_info32));
1108 modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
1109 modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32));
1110 modinfo->size = grub_host_to_target_addr (total_module_size);
1111 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
1112 offset = sizeof (struct grub_module_info32);
1113 else
1114 offset = kernel_size + sizeof (struct grub_module_info32);
1117 for (p = path_list; p; p = p->next)
1119 struct grub_module_header *header;
1120 size_t mod_size, orig_size;
1122 orig_size = grub_util_get_image_size (p->name);
1123 mod_size = ALIGN_ADDR (orig_size);
1125 header = (struct grub_module_header *) (kernel_img + offset);
1126 memset (header, 0, sizeof (struct grub_module_header));
1127 header->type = grub_host_to_target32 (OBJ_TYPE_ELF);
1128 header->size = grub_host_to_target32 (mod_size + sizeof (*header));
1129 offset += sizeof (*header);
1130 memset (kernel_img + offset + orig_size, 0, mod_size - orig_size);
1132 grub_util_load_image (p->name, kernel_img + offset);
1133 offset += mod_size;
1137 size_t i;
1138 for (i = 0; i < npubkeys; i++)
1140 size_t curs;
1141 struct grub_module_header *header;
1143 curs = grub_util_get_image_size (pubkey_paths[i]);
1145 header = (struct grub_module_header *) (kernel_img + offset);
1146 memset (header, 0, sizeof (struct grub_module_header));
1147 header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY);
1148 header->size = grub_host_to_target32 (curs + sizeof (*header));
1149 offset += sizeof (*header);
1151 grub_util_load_image (pubkey_paths[i], kernel_img + offset);
1152 offset += ALIGN_ADDR (curs);
1156 if (memdisk_path)
1158 struct grub_module_header *header;
1160 header = (struct grub_module_header *) (kernel_img + offset);
1161 memset (header, 0, sizeof (struct grub_module_header));
1162 header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK);
1163 header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
1164 offset += sizeof (*header);
1166 grub_util_load_image (memdisk_path, kernel_img + offset);
1167 offset += memdisk_size;
1170 if (config_path)
1172 struct grub_module_header *header;
1174 header = (struct grub_module_header *) (kernel_img + offset);
1175 memset (header, 0, sizeof (struct grub_module_header));
1176 header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG);
1177 header->size = grub_host_to_target32 (config_size + sizeof (*header));
1178 offset += sizeof (*header);
1180 grub_util_load_image (config_path, kernel_img + offset);
1181 *(kernel_img + offset + config_size_pure - 1) = 0;
1182 offset += config_size;
1185 if (prefix)
1187 struct grub_module_header *header;
1189 header = (struct grub_module_header *) (kernel_img + offset);
1190 memset (header, 0, sizeof (struct grub_module_header));
1191 header->type = grub_host_to_target32 (OBJ_TYPE_PREFIX);
1192 header->size = grub_host_to_target32 (prefix_size + sizeof (*header));
1193 offset += sizeof (*header);
1195 grub_memset (kernel_img + offset, 0, prefix_size);
1196 grub_strcpy (kernel_img + offset, prefix);
1197 offset += prefix_size;
1200 grub_util_info ("kernel_img=%p, kernel_size=0x%" GRUB_HOST_PRIxLONG_LONG,
1201 kernel_img,
1202 (unsigned long long) kernel_size);
1203 compress_kernel (image_target, kernel_img, kernel_size + total_module_size,
1204 &core_img, &core_size, comp);
1205 free (kernel_img);
1207 grub_util_info ("the core size is 0x%" GRUB_HOST_PRIxLONG_LONG,
1208 (unsigned long long) core_size);
1210 if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
1211 && image_target->total_module_size != TARGET_NO_FIELD)
1212 *((grub_uint32_t *) (core_img + image_target->total_module_size))
1213 = grub_host_to_target32 (total_module_size);
1215 if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
1217 char *full_img;
1218 size_t full_size;
1219 char *decompress_path, *decompress_img;
1220 const char *name;
1222 switch (comp)
1224 case GRUB_COMPRESSION_XZ:
1225 name = "xz_decompress.img";
1226 break;
1227 case GRUB_COMPRESSION_LZMA:
1228 name = "lzma_decompress.img";
1229 break;
1230 case GRUB_COMPRESSION_NONE:
1231 name = "none_decompress.img";
1232 break;
1233 default:
1234 grub_util_error (_("unknown compression %d\n"), comp);
1237 decompress_path = grub_util_get_path (dir, name);
1238 decompress_size = grub_util_get_image_size (decompress_path);
1239 decompress_img = grub_util_read_image (decompress_path);
1241 if ((image_target->id == IMAGE_I386_PC
1242 || image_target->id == IMAGE_I386_PC_PXE
1243 || image_target->id == IMAGE_I386_PC_ELTORITO)
1244 && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200)
1245 grub_util_error ("%s", _("Decompressor is too big"));
1247 if (image_target->decompressor_compressed_size != TARGET_NO_FIELD)
1248 *((grub_uint32_t *) (decompress_img
1249 + image_target->decompressor_compressed_size))
1250 = grub_host_to_target32 (core_size);
1252 if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD)
1253 *((grub_uint32_t *) (decompress_img
1254 + image_target->decompressor_uncompressed_size))
1255 = grub_host_to_target32 (kernel_size + total_module_size);
1257 if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD)
1259 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
1260 *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr))
1261 = grub_host_to_target_addr (image_target->link_addr - total_module_size);
1262 else
1263 *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr))
1264 = grub_host_to_target_addr (image_target->link_addr);
1266 full_size = core_size + decompress_size;
1268 full_img = xmalloc (full_size);
1269 memset (full_img, 0, full_size);
1271 memcpy (full_img, decompress_img, decompress_size);
1273 memcpy (full_img + decompress_size, core_img, core_size);
1275 memset (full_img + decompress_size + core_size, 0,
1276 full_size - (decompress_size + core_size));
1278 free (core_img);
1279 core_img = full_img;
1280 core_size = full_size;
1281 free (decompress_img);
1282 free (decompress_path);
1285 switch (image_target->id)
1287 case IMAGE_I386_PC:
1288 case IMAGE_I386_PC_PXE:
1289 case IMAGE_I386_PC_ELTORITO:
1290 if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000
1291 || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS))
1292 || (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000))
1293 grub_util_error (_("core image is too big (0x%x > 0x%x)"),
1294 GRUB_KERNEL_I386_PC_LINK_ADDR + (unsigned) core_size,
1295 0x78000);
1296 /* fallthrough */
1297 case IMAGE_COREBOOT:
1298 case IMAGE_QEMU:
1299 if (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)
1300 grub_util_error (_("kernel image is too big (0x%x > 0x%x)"),
1301 (unsigned) kernel_size + (unsigned) bss_size
1302 + GRUB_KERNEL_I386_PC_LINK_ADDR,
1303 0x68000);
1304 break;
1305 case IMAGE_LOONGSON_ELF:
1306 case IMAGE_YEELOONG_FLASH:
1307 case IMAGE_FULOONG2F_FLASH:
1308 case IMAGE_EFI:
1309 case IMAGE_MIPS_ARC:
1310 case IMAGE_QEMU_MIPS_FLASH:
1311 case IMAGE_XEN:
1312 break;
1313 case IMAGE_SPARC64_AOUT:
1314 case IMAGE_SPARC64_RAW:
1315 case IMAGE_SPARC64_CDCORE:
1316 case IMAGE_I386_IEEE1275:
1317 case IMAGE_PPC:
1318 case IMAGE_UBOOT:
1319 break;
1322 switch (image_target->id)
1324 case IMAGE_I386_PC:
1325 case IMAGE_I386_PC_PXE:
1326 case IMAGE_I386_PC_ELTORITO:
1328 unsigned num;
1329 char *boot_path, *boot_img;
1330 size_t boot_size;
1332 num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
1333 if (image_target->id == IMAGE_I386_PC_PXE)
1335 char *pxeboot_path, *pxeboot_img;
1336 size_t pxeboot_size;
1337 grub_uint32_t *ptr;
1339 pxeboot_path = grub_util_get_path (dir, "pxeboot.img");
1340 pxeboot_size = grub_util_get_image_size (pxeboot_path);
1341 pxeboot_img = grub_util_read_image (pxeboot_path);
1343 grub_util_write_image (pxeboot_img, pxeboot_size, out,
1344 outname);
1345 free (pxeboot_img);
1346 free (pxeboot_path);
1348 /* Remove Multiboot header to avoid confusing ipxe. */
1349 for (ptr = (grub_uint32_t *) core_img;
1350 ptr < (grub_uint32_t *) (core_img + MULTIBOOT_SEARCH); ptr++)
1351 if (*ptr == grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC)
1352 && grub_target_to_host32 (ptr[0])
1353 + grub_target_to_host32 (ptr[1])
1354 + grub_target_to_host32 (ptr[2]) == 0)
1356 *ptr = 0;
1357 break;
1361 if (image_target->id == IMAGE_I386_PC_ELTORITO)
1363 char *eltorito_path, *eltorito_img;
1364 size_t eltorito_size;
1366 eltorito_path = grub_util_get_path (dir, "cdboot.img");
1367 eltorito_size = grub_util_get_image_size (eltorito_path);
1368 eltorito_img = grub_util_read_image (eltorito_path);
1370 grub_util_write_image (eltorito_img, eltorito_size, out,
1371 outname);
1372 free (eltorito_img);
1373 free (eltorito_path);
1376 boot_path = grub_util_get_path (dir, "diskboot.img");
1377 boot_size = grub_util_get_image_size (boot_path);
1378 if (boot_size != GRUB_DISK_SECTOR_SIZE)
1379 grub_util_error (_("diskboot.img size must be %u bytes"),
1380 GRUB_DISK_SECTOR_SIZE);
1382 boot_img = grub_util_read_image (boot_path);
1385 struct grub_pc_bios_boot_blocklist *block;
1386 block = (struct grub_pc_bios_boot_blocklist *) (boot_img
1387 + GRUB_DISK_SECTOR_SIZE
1388 - sizeof (*block));
1389 block->len = grub_host_to_target16 (num);
1391 /* This is filled elsewhere. Verify it just in case. */
1392 assert (block->segment
1393 == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG
1394 + (GRUB_DISK_SECTOR_SIZE >> 4)));
1397 grub_util_write_image (boot_img, boot_size, out, outname);
1398 free (boot_img);
1399 free (boot_path);
1401 break;
1402 case IMAGE_EFI:
1404 void *pe_img;
1405 grub_uint8_t *header;
1406 void *sections;
1407 size_t pe_size;
1408 struct grub_pe32_coff_header *c;
1409 struct grub_pe32_section_table *text_section, *data_section;
1410 struct grub_pe32_section_table *mods_section, *reloc_section;
1411 static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
1412 int header_size;
1413 int reloc_addr;
1415 if (image_target->voidp_sizeof == 4)
1416 header_size = EFI32_HEADER_SIZE;
1417 else
1418 header_size = EFI64_HEADER_SIZE;
1420 reloc_addr = ALIGN_UP (header_size + core_size,
1421 image_target->section_align);
1423 pe_size = ALIGN_UP (reloc_addr + reloc_size,
1424 image_target->section_align);
1425 pe_img = xmalloc (reloc_addr + reloc_size);
1426 memset (pe_img, 0, header_size);
1427 memcpy ((char *) pe_img + header_size, core_img, core_size);
1428 memcpy ((char *) pe_img + reloc_addr, rel_section, reloc_size);
1429 header = pe_img;
1431 /* The magic. */
1432 memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE);
1433 memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0",
1434 GRUB_PE32_SIGNATURE_SIZE);
1436 /* The COFF file header. */
1437 c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE
1438 + GRUB_PE32_SIGNATURE_SIZE);
1439 c->machine = grub_host_to_target16 (image_target->pe_target);
1441 c->num_sections = grub_host_to_target16 (4);
1442 c->time = grub_host_to_target32 (time (0));
1443 c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE
1444 | GRUB_PE32_LINE_NUMS_STRIPPED
1445 | ((image_target->voidp_sizeof == 4)
1446 ? GRUB_PE32_32BIT_MACHINE
1447 : 0)
1448 | GRUB_PE32_LOCAL_SYMS_STRIPPED
1449 | GRUB_PE32_DEBUG_STRIPPED);
1451 /* The PE Optional header. */
1452 if (image_target->voidp_sizeof == 4)
1454 struct grub_pe32_optional_header *o;
1456 c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header));
1458 o = (struct grub_pe32_optional_header *)
1459 (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
1460 + sizeof (struct grub_pe32_coff_header));
1461 o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
1462 o->code_size = grub_host_to_target32 (exec_size);
1463 o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size
1464 - header_size);
1465 o->bss_size = grub_cpu_to_le32 (bss_size);
1466 o->entry_addr = grub_cpu_to_le32 (start_address);
1467 o->code_base = grub_cpu_to_le32 (header_size);
1469 o->data_base = grub_host_to_target32 (header_size + exec_size);
1471 o->image_base = 0;
1472 o->section_alignment = grub_host_to_target32 (image_target->section_align);
1473 o->file_alignment = grub_host_to_target32 (image_target->section_align);
1474 o->image_size = grub_host_to_target32 (pe_size);
1475 o->header_size = grub_host_to_target32 (header_size);
1476 o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
1478 /* Do these really matter? */
1479 o->stack_reserve_size = grub_host_to_target32 (0x10000);
1480 o->stack_commit_size = grub_host_to_target32 (0x10000);
1481 o->heap_reserve_size = grub_host_to_target32 (0x10000);
1482 o->heap_commit_size = grub_host_to_target32 (0x10000);
1484 o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
1486 o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
1487 o->base_relocation_table.size = grub_host_to_target32 (reloc_size);
1488 sections = o + 1;
1490 else
1492 struct grub_pe64_optional_header *o;
1494 c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header));
1496 o = (struct grub_pe64_optional_header *)
1497 (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
1498 + sizeof (struct grub_pe32_coff_header));
1499 o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
1500 o->code_size = grub_host_to_target32 (exec_size);
1501 o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size
1502 - header_size);
1503 o->bss_size = grub_cpu_to_le32 (bss_size);
1504 o->entry_addr = grub_cpu_to_le32 (start_address);
1505 o->code_base = grub_cpu_to_le32 (header_size);
1506 o->image_base = 0;
1507 o->section_alignment = grub_host_to_target32 (image_target->section_align);
1508 o->file_alignment = grub_host_to_target32 (image_target->section_align);
1509 o->image_size = grub_host_to_target32 (pe_size);
1510 o->header_size = grub_host_to_target32 (header_size);
1511 o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
1513 /* Do these really matter? */
1514 o->stack_reserve_size = grub_host_to_target64 (0x10000);
1515 o->stack_commit_size = grub_host_to_target64 (0x10000);
1516 o->heap_reserve_size = grub_host_to_target64 (0x10000);
1517 o->heap_commit_size = grub_host_to_target64 (0x10000);
1519 o->num_data_directories
1520 = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
1522 o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
1523 o->base_relocation_table.size = grub_host_to_target32 (reloc_size);
1524 sections = o + 1;
1526 /* The sections. */
1527 text_section = sections;
1528 strcpy (text_section->name, ".text");
1529 text_section->virtual_size = grub_cpu_to_le32 (exec_size);
1530 text_section->virtual_address = grub_cpu_to_le32 (header_size);
1531 text_section->raw_data_size = grub_cpu_to_le32 (exec_size);
1532 text_section->raw_data_offset = grub_cpu_to_le32 (header_size);
1533 text_section->characteristics = grub_cpu_to_le32_compile_time (
1534 GRUB_PE32_SCN_CNT_CODE
1535 | GRUB_PE32_SCN_MEM_EXECUTE
1536 | GRUB_PE32_SCN_MEM_READ);
1538 data_section = text_section + 1;
1539 strcpy (data_section->name, ".data");
1540 data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size);
1541 data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size);
1542 data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size);
1543 data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size);
1544 data_section->characteristics
1545 = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1546 | GRUB_PE32_SCN_MEM_READ
1547 | GRUB_PE32_SCN_MEM_WRITE);
1549 #if 0
1550 bss_section = data_section + 1;
1551 strcpy (bss_section->name, ".bss");
1552 bss_section->virtual_size = grub_cpu_to_le32 (bss_size);
1553 bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size);
1554 bss_section->raw_data_size = 0;
1555 bss_section->raw_data_offset = 0;
1556 bss_section->characteristics
1557 = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ
1558 | GRUB_PE32_SCN_MEM_WRITE
1559 | GRUB_PE32_SCN_ALIGN_64BYTES
1560 | GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1561 | 0x80);
1562 #endif
1564 mods_section = data_section + 1;
1565 strcpy (mods_section->name, "mods");
1566 mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size);
1567 mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size);
1568 mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size);
1569 mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size);
1570 mods_section->characteristics
1571 = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1572 | GRUB_PE32_SCN_MEM_READ
1573 | GRUB_PE32_SCN_MEM_WRITE);
1575 reloc_section = mods_section + 1;
1576 strcpy (reloc_section->name, ".reloc");
1577 reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size);
1578 reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size);
1579 reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size);
1580 reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr);
1581 reloc_section->characteristics
1582 = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1583 | GRUB_PE32_SCN_MEM_DISCARDABLE
1584 | GRUB_PE32_SCN_MEM_READ);
1585 free (core_img);
1586 core_img = pe_img;
1587 core_size = pe_size;
1589 break;
1590 case IMAGE_QEMU:
1592 char *rom_img;
1593 size_t rom_size;
1594 char *boot_path, *boot_img;
1595 size_t boot_size;
1597 boot_path = grub_util_get_path (dir, "boot.img");
1598 boot_size = grub_util_get_image_size (boot_path);
1599 boot_img = grub_util_read_image (boot_path);
1601 /* Rom sizes must be 64k-aligned. */
1602 rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024);
1604 rom_img = xmalloc (rom_size);
1605 memset (rom_img, 0, rom_size);
1607 *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR))
1608 = grub_host_to_target32 ((grub_uint32_t) -rom_size);
1610 memcpy (rom_img, core_img, core_size);
1612 *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR))
1613 = grub_host_to_target32 ((grub_uint32_t) -rom_size);
1615 memcpy (rom_img + rom_size - boot_size, boot_img, boot_size);
1617 free (core_img);
1618 core_img = rom_img;
1619 core_size = rom_size;
1621 free (boot_img);
1622 free (boot_path);
1624 break;
1625 case IMAGE_SPARC64_AOUT:
1627 void *aout_img;
1628 size_t aout_size;
1629 struct grub_aout32_header *aout_head;
1631 aout_size = core_size + sizeof (*aout_head);
1632 aout_img = xmalloc (aout_size);
1633 aout_head = aout_img;
1634 grub_memset (aout_head, 0, sizeof (*aout_head));
1635 aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16)
1636 | AOUT32_OMAGIC);
1637 aout_head->a_text = grub_host_to_target32 (core_size);
1638 aout_head->a_entry
1639 = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS);
1640 memcpy ((char *) aout_img + sizeof (*aout_head), core_img, core_size);
1642 free (core_img);
1643 core_img = aout_img;
1644 core_size = aout_size;
1646 break;
1647 case IMAGE_SPARC64_RAW:
1649 unsigned int num;
1650 char *boot_path, *boot_img;
1651 size_t boot_size;
1653 num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
1654 num <<= GRUB_DISK_SECTOR_BITS;
1656 boot_path = grub_util_get_path (dir, "diskboot.img");
1657 boot_size = grub_util_get_image_size (boot_path);
1658 if (boot_size != GRUB_DISK_SECTOR_SIZE)
1659 grub_util_error (_("diskboot.img size must be %u bytes"),
1660 GRUB_DISK_SECTOR_SIZE);
1662 boot_img = grub_util_read_image (boot_path);
1664 *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE
1665 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8))
1666 = grub_host_to_target32 (num);
1668 grub_util_write_image (boot_img, boot_size, out, outname);
1669 free (boot_img);
1670 free (boot_path);
1672 break;
1673 case IMAGE_SPARC64_CDCORE:
1674 break;
1675 case IMAGE_YEELOONG_FLASH:
1676 case IMAGE_FULOONG2F_FLASH:
1678 char *rom_img;
1679 size_t rom_size;
1680 char *boot_path, *boot_img;
1681 size_t boot_size;
1682 /* fwstart.img is the only part which can't be tested by using *-elf
1683 target. Check it against the checksum. */
1684 const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] =
1686 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a,
1687 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5,
1688 0x75, 0x64, 0x6b, 0xbb, 0x24, 0xcd, 0xb4, 0xbc,
1689 0xf2, 0x3e, 0x23, 0xf9, 0xc2, 0x6a, 0x8c, 0xde,
1690 0x3b, 0x94, 0x9c, 0xcc, 0xa5, 0xa7, 0x58, 0xb1,
1691 0xbe, 0x8b, 0x3d, 0x73, 0x98, 0x18, 0x7e, 0x68,
1692 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7,
1693 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25
1695 const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] =
1697 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62,
1698 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c,
1699 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d,
1700 0x02, 0x84, 0xa0, 0x85, 0xf2, 0xd1, 0xb9, 0x53,
1701 0xa2, 0xbc, 0xf2, 0xe1, 0x39, 0x1e, 0x51, 0xb5,
1702 0xaf, 0xec, 0x9e, 0xf2, 0xf1, 0xf3, 0x0a, 0x2f,
1703 0xe6, 0xf1, 0x08, 0x89, 0xbe, 0xbc, 0x73, 0xab,
1704 0x46, 0x50, 0xd6, 0x21, 0xce, 0x8e, 0x24, 0xa7
1706 const grub_uint8_t *fwstart_good_hash;
1707 grub_uint8_t fwstart_hash[512 / 8];
1709 if (image_target->id == IMAGE_FULOONG2F_FLASH)
1711 fwstart_good_hash = fuloong2f_fwstart_good_hash;
1712 boot_path = grub_util_get_path (dir, "fwstart_fuloong2f.img");
1714 else
1716 fwstart_good_hash = yeeloong_fwstart_good_hash;
1717 boot_path = grub_util_get_path (dir, "fwstart.img");
1720 boot_size = grub_util_get_image_size (boot_path);
1721 boot_img = grub_util_read_image (boot_path);
1723 grub_crypto_hash (GRUB_MD_SHA512, fwstart_hash, boot_img, boot_size);
1725 if (grub_memcmp (fwstart_hash, fwstart_good_hash,
1726 GRUB_MD_SHA512->mdlen) != 0)
1727 /* TRANSLATORS: fwstart.img may still be good, just it wasn't checked. */
1728 grub_util_warn ("%s",
1729 _("fwstart.img doesn't match the known good version. "
1730 "proceed at your own risk"));
1732 if (core_size + boot_size > 512 * 1024)
1733 grub_util_error ("%s", _("firmware image is too big"));
1734 rom_size = 512 * 1024;
1736 rom_img = xmalloc (rom_size);
1737 memset (rom_img, 0, rom_size);
1739 memcpy (rom_img, boot_img, boot_size);
1741 memcpy (rom_img + boot_size, core_img, core_size);
1743 memset (rom_img + boot_size + core_size, 0,
1744 rom_size - (boot_size + core_size));
1746 free (core_img);
1747 core_img = rom_img;
1748 core_size = rom_size;
1749 free (boot_img);
1750 free (boot_path);
1752 break;
1753 case IMAGE_QEMU_MIPS_FLASH:
1755 char *rom_img;
1756 size_t rom_size;
1758 if (core_size > 512 * 1024)
1759 grub_util_error ("%s", _("firmware image is too big"));
1760 rom_size = 512 * 1024;
1762 rom_img = xmalloc (rom_size);
1763 memset (rom_img, 0, rom_size);
1765 memcpy (rom_img, core_img, core_size);
1767 memset (rom_img + core_size, 0,
1768 rom_size - core_size);
1770 free (core_img);
1771 core_img = rom_img;
1772 core_size = rom_size;
1774 break;
1776 case IMAGE_UBOOT:
1778 struct grub_uboot_image_header *hdr;
1780 hdr = xmalloc (core_size + sizeof (struct grub_uboot_image_header));
1781 memcpy (hdr + 1, core_img, core_size);
1783 memset (hdr, 0, sizeof (*hdr));
1784 hdr->ih_magic = grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC);
1785 hdr->ih_time = grub_cpu_to_be32 (time (0));
1786 hdr->ih_size = grub_cpu_to_be32 (core_size);
1787 hdr->ih_load = grub_cpu_to_be32 (image_target->link_addr);
1788 hdr->ih_ep = grub_cpu_to_be32 (image_target->link_addr);
1789 hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL;
1790 hdr->ih_os = GRUB_UBOOT_IH_OS_LINUX;
1791 hdr->ih_arch = GRUB_UBOOT_IH_ARCH_ARM;
1792 hdr->ih_comp = GRUB_UBOOT_IH_COMP_NONE;
1794 grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_dcrc, hdr + 1, core_size);
1795 grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_hcrc, hdr, sizeof (*hdr));
1797 free (core_img);
1798 core_img = (char *) hdr;
1799 core_size += sizeof (struct grub_uboot_image_header);
1801 break;
1803 case IMAGE_MIPS_ARC:
1805 char *ecoff_img;
1806 struct ecoff_header {
1807 grub_uint16_t magic;
1808 grub_uint16_t nsec;
1809 grub_uint32_t time;
1810 grub_uint32_t syms;
1811 grub_uint32_t nsyms;
1812 grub_uint16_t opt;
1813 grub_uint16_t flags;
1814 grub_uint16_t magic2;
1815 grub_uint16_t version;
1816 grub_uint32_t textsize;
1817 grub_uint32_t datasize;
1818 grub_uint32_t bsssize;
1819 grub_uint32_t entry;
1820 grub_uint32_t text_start;
1821 grub_uint32_t data_start;
1822 grub_uint32_t bss_start;
1823 grub_uint32_t gprmask;
1824 grub_uint32_t cprmask[4];
1825 grub_uint32_t gp_value;
1827 struct ecoff_section
1829 char name[8];
1830 grub_uint32_t paddr;
1831 grub_uint32_t vaddr;
1832 grub_uint32_t size;
1833 grub_uint32_t file_offset;
1834 grub_uint32_t reloc;
1835 grub_uint32_t gp;
1836 grub_uint16_t nreloc;
1837 grub_uint16_t ngp;
1838 grub_uint32_t flags;
1840 struct ecoff_header *head;
1841 struct ecoff_section *section;
1842 grub_uint32_t target_addr;
1843 size_t program_size;
1845 program_size = ALIGN_ADDR (core_size);
1846 if (comp == GRUB_COMPRESSION_NONE)
1847 target_addr = (image_target->link_addr - decompress_size);
1848 else
1849 target_addr = ALIGN_UP (image_target->link_addr
1850 + kernel_size + total_module_size, 32);
1852 ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section));
1853 grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section));
1854 head = (void *) ecoff_img;
1855 section = (void *) (head + 1);
1856 head->magic = image_target->bigendian ? grub_host_to_target16 (0x160)
1857 : grub_host_to_target16 (0x166);
1858 head->nsec = grub_host_to_target16 (1);
1859 head->time = grub_host_to_target32 (0);
1860 head->opt = grub_host_to_target16 (0x38);
1861 head->flags = image_target->bigendian
1862 ? grub_host_to_target16 (0x207)
1863 : grub_host_to_target16 (0x103);
1864 head->magic2 = grub_host_to_target16 (0x107);
1865 head->textsize = grub_host_to_target32 (program_size);
1866 head->entry = grub_host_to_target32 (target_addr);
1867 head->text_start = grub_host_to_target32 (target_addr);
1868 head->data_start = grub_host_to_target32 (target_addr + program_size);
1869 grub_memcpy (section->name, ".text", sizeof (".text") - 1);
1870 section->vaddr = grub_host_to_target32 (target_addr);
1871 section->size = grub_host_to_target32 (program_size);
1872 section->file_offset = grub_host_to_target32 (sizeof (*head) + sizeof (*section));
1873 if (!image_target->bigendian)
1875 section->paddr = grub_host_to_target32 (0xaa60);
1876 section->flags = grub_host_to_target32 (0x20);
1878 memcpy (section + 1, core_img, core_size);
1879 free (core_img);
1880 core_img = ecoff_img;
1881 core_size = program_size + sizeof (*head) + sizeof (*section);
1883 break;
1884 case IMAGE_LOONGSON_ELF:
1885 case IMAGE_PPC:
1886 case IMAGE_XEN:
1887 case IMAGE_COREBOOT:
1888 case IMAGE_I386_IEEE1275:
1890 grub_uint64_t target_addr;
1891 if (image_target->id == IMAGE_LOONGSON_ELF)
1893 if (comp == GRUB_COMPRESSION_NONE)
1894 target_addr = (image_target->link_addr - decompress_size);
1895 else
1896 target_addr = ALIGN_UP (image_target->link_addr
1897 + kernel_size + total_module_size, 32);
1899 else
1900 target_addr = image_target->link_addr;
1901 if (image_target->voidp_sizeof == 4)
1902 generate_elf32 (image_target, note, &core_img, &core_size,
1903 target_addr, align, kernel_size, bss_size);
1904 else
1905 generate_elf64 (image_target, note, &core_img, &core_size,
1906 target_addr, align, kernel_size, bss_size);
1908 break;
1911 grub_util_write_image (core_img, core_size, out, outname);
1912 free (core_img);
1913 free (kernel_path);
1914 free (rel_section);
1916 while (path_list)
1918 next = path_list->next;
1919 free ((void *) path_list->name);
1920 free (path_list);
1921 path_list = next;