1 /* grub-mkimage.c - make a bootable image */
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/>.
21 #include <grub/types.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>
35 #include <multiboot.h>
42 #include <grub/efi/pe32.h>
43 #include <grub/uboot/image.h>
44 #include <grub/arm/reloc.h>
45 #include <grub/ia64/reloc.h>
52 #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
58 #define TARGET_NO_FIELD 0xffffffff
61 COMPRESSION_AUTO
, COMPRESSION_NONE
, COMPRESSION_XZ
, COMPRESSION_LZMA
64 struct image_target_desc
68 grub_size_t voidp_sizeof
;
71 IMAGE_I386_PC
, IMAGE_EFI
, IMAGE_COREBOOT
,
72 IMAGE_SPARC64_AOUT
, IMAGE_SPARC64_RAW
, IMAGE_SPARC64_CDCORE
,
74 IMAGE_LOONGSON_ELF
, IMAGE_QEMU
, IMAGE_PPC
, IMAGE_YEELOONG_FLASH
,
75 IMAGE_FULOONG2F_FLASH
, IMAGE_I386_PC_PXE
, IMAGE_MIPS_ARC
,
76 IMAGE_QEMU_MIPS_FLASH
, IMAGE_UBOOT
80 PLATFORM_FLAGS_NONE
= 0,
81 PLATFORM_FLAGS_DECOMPRESSORS
= 2,
82 PLATFORM_FLAGS_MODULES_BEFORE_KERNEL
= 4,
84 unsigned total_module_size
;
85 unsigned decompressor_compressed_size
;
86 unsigned decompressor_uncompressed_size
;
87 unsigned decompressor_uncompressed_addr
;
89 grub_uint16_t elf_target
;
90 unsigned section_align
;
92 grub_uint64_t link_addr
;
93 unsigned mod_gap
, mod_align
;
94 grub_compression_t default_compression
;
95 grub_uint16_t pe_target
;
98 #define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
99 + GRUB_PE32_SIGNATURE_SIZE \
100 + sizeof (struct grub_pe32_coff_header) \
101 + sizeof (struct grub_pe32_optional_header) \
102 + 4 * sizeof (struct grub_pe32_section_table), \
103 GRUB_PE32_SECTION_ALIGNMENT)
105 #define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
106 + GRUB_PE32_SIGNATURE_SIZE \
107 + sizeof (struct grub_pe32_coff_header) \
108 + sizeof (struct grub_pe64_optional_header) \
109 + 4 * sizeof (struct grub_pe32_section_table), \
110 GRUB_PE32_SECTION_ALIGNMENT)
112 struct image_target_desc image_targets
[] =
115 .dirname
= "i386-coreboot",
116 .names
= { "i386-coreboot", NULL
},
119 .id
= IMAGE_COREBOOT
,
120 .flags
= PLATFORM_FLAGS_NONE
,
121 .total_module_size
= TARGET_NO_FIELD
,
122 .decompressor_compressed_size
= TARGET_NO_FIELD
,
123 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
124 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
127 .link_addr
= GRUB_KERNEL_I386_COREBOOT_LINK_ADDR
,
128 .elf_target
= EM_386
,
130 .mod_gap
= GRUB_KERNEL_I386_COREBOOT_MOD_GAP
,
131 .mod_align
= GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
134 .dirname
= "i386-multiboot",
135 .names
= { "i386-multiboot", NULL
},
138 .id
= IMAGE_COREBOOT
,
139 .flags
= PLATFORM_FLAGS_NONE
,
140 .total_module_size
= TARGET_NO_FIELD
,
141 .decompressor_compressed_size
= TARGET_NO_FIELD
,
142 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
143 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
146 .link_addr
= GRUB_KERNEL_I386_COREBOOT_LINK_ADDR
,
147 .elf_target
= EM_386
,
149 .mod_gap
= GRUB_KERNEL_I386_COREBOOT_MOD_GAP
,
150 .mod_align
= GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
153 .dirname
= "i386-pc",
154 .names
= { "i386-pc", NULL
},
158 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
159 .total_module_size
= TARGET_NO_FIELD
,
160 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE
,
161 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE
,
162 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
165 .link_addr
= GRUB_KERNEL_I386_PC_LINK_ADDR
,
166 .default_compression
= COMPRESSION_LZMA
169 .dirname
= "i386-pc",
170 .names
= { "i386-pc-pxe", NULL
},
173 .id
= IMAGE_I386_PC_PXE
,
174 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
175 .total_module_size
= TARGET_NO_FIELD
,
176 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE
,
177 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE
,
178 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
181 .link_addr
= GRUB_KERNEL_I386_PC_LINK_ADDR
,
182 .default_compression
= COMPRESSION_LZMA
185 .dirname
= "i386-efi",
186 .names
= { "i386-efi", NULL
},
190 .flags
= PLATFORM_FLAGS_NONE
,
191 .total_module_size
= TARGET_NO_FIELD
,
192 .decompressor_compressed_size
= TARGET_NO_FIELD
,
193 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
194 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
195 .section_align
= GRUB_PE32_SECTION_ALIGNMENT
,
196 .vaddr_offset
= EFI32_HEADER_SIZE
,
197 .pe_target
= GRUB_PE32_MACHINE_I386
,
198 .elf_target
= EM_386
,
201 .dirname
= "i386-ieee1275",
202 .names
= { "i386-ieee1275", NULL
},
205 .id
= IMAGE_I386_IEEE1275
,
206 .flags
= PLATFORM_FLAGS_NONE
,
207 .total_module_size
= TARGET_NO_FIELD
,
208 .decompressor_compressed_size
= TARGET_NO_FIELD
,
209 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
210 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
213 .link_addr
= GRUB_KERNEL_I386_IEEE1275_LINK_ADDR
,
214 .elf_target
= EM_386
,
215 .mod_gap
= GRUB_KERNEL_I386_IEEE1275_MOD_GAP
,
216 .mod_align
= GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN
,
220 .dirname
= "i386-qemu",
221 .names
= { "i386-qemu", NULL
},
225 .flags
= PLATFORM_FLAGS_NONE
,
226 .total_module_size
= TARGET_NO_FIELD
,
227 .decompressor_compressed_size
= TARGET_NO_FIELD
,
228 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
229 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
232 .link_addr
= GRUB_KERNEL_I386_QEMU_LINK_ADDR
235 .dirname
= "x86_64-efi",
236 .names
= { "x86_64-efi", NULL
},
240 .flags
= PLATFORM_FLAGS_NONE
,
241 .total_module_size
= TARGET_NO_FIELD
,
242 .decompressor_compressed_size
= TARGET_NO_FIELD
,
243 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
244 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
245 .section_align
= GRUB_PE32_SECTION_ALIGNMENT
,
246 .vaddr_offset
= EFI64_HEADER_SIZE
,
247 .pe_target
= GRUB_PE32_MACHINE_X86_64
,
248 .elf_target
= EM_X86_64
,
251 .dirname
= "mipsel-loongson",
252 .names
= { "mipsel-yeeloong-flash", NULL
},
255 .id
= IMAGE_YEELOONG_FLASH
,
256 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
257 .total_module_size
= GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE
,
258 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
259 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
260 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
263 .link_addr
= GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR
,
264 .elf_target
= EM_MIPS
,
265 .link_align
= GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN
,
266 .default_compression
= COMPRESSION_NONE
269 .dirname
= "mipsel-loongson",
270 .names
= { "mipsel-fuloong2f-flash", NULL
},
273 .id
= IMAGE_FULOONG2F_FLASH
,
274 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
275 .total_module_size
= GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE
,
276 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
277 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
278 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
281 .link_addr
= GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR
,
282 .elf_target
= EM_MIPS
,
283 .link_align
= GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN
,
284 .default_compression
= COMPRESSION_NONE
287 .dirname
= "mipsel-loongson",
288 .names
= { "mipsel-loongson-elf", "mipsel-yeeloong-elf",
289 "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf",
290 "mipsel-fuloong-elf", NULL
},
293 .id
= IMAGE_LOONGSON_ELF
,
294 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
295 .total_module_size
= GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE
,
296 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
297 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
298 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
301 .link_addr
= GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR
,
302 .elf_target
= EM_MIPS
,
303 .link_align
= GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN
,
304 .default_compression
= COMPRESSION_NONE
307 .dirname
= "powerpc-ieee1275",
308 .names
= { "powerpc-ieee1275", NULL
},
312 .flags
= PLATFORM_FLAGS_NONE
,
313 .total_module_size
= TARGET_NO_FIELD
,
314 .decompressor_compressed_size
= TARGET_NO_FIELD
,
315 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
316 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
319 .link_addr
= GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR
,
320 .elf_target
= EM_PPC
,
321 .mod_gap
= GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP
,
322 .mod_align
= GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN
,
326 .dirname
= "sparc64-ieee1275",
327 .names
= { "sparc64-ieee1275-raw", NULL
},
330 .id
= IMAGE_SPARC64_RAW
,
331 .flags
= PLATFORM_FLAGS_NONE
,
332 .total_module_size
= GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE
,
333 .decompressor_compressed_size
= TARGET_NO_FIELD
,
334 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
335 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
338 .link_addr
= GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR
341 .dirname
= "sparc64-ieee1275",
342 .names
= { "sparc64-ieee1275-cdcore", NULL
},
345 .id
= IMAGE_SPARC64_CDCORE
,
346 .flags
= PLATFORM_FLAGS_NONE
,
347 .total_module_size
= GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE
,
348 .decompressor_compressed_size
= TARGET_NO_FIELD
,
349 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
350 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
353 .link_addr
= GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR
356 .dirname
= "sparc64-ieee1275",
357 .names
= { "sparc64-ieee1275-aout", NULL
},
360 .id
= IMAGE_SPARC64_AOUT
,
361 .flags
= PLATFORM_FLAGS_NONE
,
362 .total_module_size
= GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE
,
363 .decompressor_compressed_size
= TARGET_NO_FIELD
,
364 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
365 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
368 .link_addr
= GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR
371 .dirname
= "ia64-efi",
372 .names
= {"ia64-efi", NULL
},
376 .flags
= PLATFORM_FLAGS_NONE
,
377 .total_module_size
= TARGET_NO_FIELD
,
378 .decompressor_compressed_size
= TARGET_NO_FIELD
,
379 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
380 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
381 .section_align
= GRUB_PE32_SECTION_ALIGNMENT
,
382 .vaddr_offset
= EFI64_HEADER_SIZE
,
383 .pe_target
= GRUB_PE32_MACHINE_IA64
,
384 .elf_target
= EM_IA_64
,
387 .dirname
= "mips-arc",
388 .names
= {"mips-arc", NULL
},
391 .id
= IMAGE_MIPS_ARC
,
392 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
393 .total_module_size
= GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE
,
394 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
395 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
396 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
399 .link_addr
= GRUB_KERNEL_MIPS_ARC_LINK_ADDR
,
400 .elf_target
= EM_MIPS
,
401 .link_align
= GRUB_KERNEL_MIPS_ARC_LINK_ALIGN
,
402 .default_compression
= COMPRESSION_NONE
405 .dirname
= "mipsel-arc",
406 .names
= {"mipsel-arc", NULL
},
409 .id
= IMAGE_MIPS_ARC
,
410 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
411 .total_module_size
= GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE
,
412 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
413 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
414 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
417 .link_addr
= GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR
,
418 .elf_target
= EM_MIPS
,
419 .link_align
= GRUB_KERNEL_MIPS_ARC_LINK_ALIGN
,
420 .default_compression
= COMPRESSION_NONE
423 .dirname
= "mipsel-qemu_mips",
424 .names
= { "mipsel-qemu_mips-elf", NULL
},
427 .id
= IMAGE_LOONGSON_ELF
,
428 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
429 .total_module_size
= GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE
,
430 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
431 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
432 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
435 .link_addr
= GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR
,
436 .elf_target
= EM_MIPS
,
437 .link_align
= GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN
,
438 .default_compression
= COMPRESSION_NONE
441 .dirname
= "mips-qemu_mips",
442 .names
= { "mips-qemu_mips-flash", NULL
},
445 .id
= IMAGE_QEMU_MIPS_FLASH
,
446 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
447 .total_module_size
= GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE
,
448 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
449 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
450 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
453 .link_addr
= GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR
,
454 .elf_target
= EM_MIPS
,
455 .link_align
= GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN
,
456 .default_compression
= COMPRESSION_NONE
459 .dirname
= "mipsel-qemu_mips",
460 .names
= { "mipsel-qemu_mips-flash", NULL
},
463 .id
= IMAGE_QEMU_MIPS_FLASH
,
464 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
465 .total_module_size
= GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE
,
466 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
467 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
468 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
471 .link_addr
= GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR
,
472 .elf_target
= EM_MIPS
,
473 .link_align
= GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN
,
474 .default_compression
= COMPRESSION_NONE
477 .dirname
= "mips-qemu_mips",
478 .names
= { "mips-qemu_mips-elf", NULL
},
481 .id
= IMAGE_LOONGSON_ELF
,
482 .flags
= PLATFORM_FLAGS_DECOMPRESSORS
,
483 .total_module_size
= GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE
,
484 .decompressor_compressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE
,
485 .decompressor_uncompressed_size
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE
,
486 .decompressor_uncompressed_addr
= GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR
,
489 .link_addr
= GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR
,
490 .elf_target
= EM_MIPS
,
491 .link_align
= GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN
,
492 .default_compression
= COMPRESSION_NONE
495 .dirname
= "arm-uboot",
496 .names
= { "arm-uboot", NULL
},
500 .flags
= PLATFORM_FLAGS_NONE
,
501 .total_module_size
= GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE
,
502 .decompressor_compressed_size
= TARGET_NO_FIELD
,
503 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
504 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
505 .section_align
= GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN
,
507 .link_addr
= GRUB_KERNEL_ARM_UBOOT_LINK_ADDR
,
508 .elf_target
= EM_ARM
,
509 .mod_gap
= GRUB_KERNEL_ARM_UBOOT_MOD_GAP
,
510 .mod_align
= GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN
,
514 .dirname
= "arm-efi",
515 .names
= { "arm-efi", NULL
},
519 .flags
= PLATFORM_FLAGS_NONE
,
520 .total_module_size
= TARGET_NO_FIELD
,
521 .decompressor_compressed_size
= TARGET_NO_FIELD
,
522 .decompressor_uncompressed_size
= TARGET_NO_FIELD
,
523 .decompressor_uncompressed_addr
= TARGET_NO_FIELD
,
524 .section_align
= GRUB_PE32_SECTION_ALIGNMENT
,
525 .vaddr_offset
= ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE
526 + GRUB_PE32_SIGNATURE_SIZE
527 + sizeof (struct grub_pe32_coff_header
)
528 + sizeof (struct grub_pe32_optional_header
)
529 + 4 * sizeof (struct grub_pe32_section_table
),
530 GRUB_PE32_SECTION_ALIGNMENT
),
531 .pe_target
= GRUB_PE32_MACHINE_ARMTHUMB_MIXED
,
532 .elf_target
= EM_ARM
,
536 #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x)))
537 #define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x)))
538 #define grub_target_to_host64(x) (grub_target_to_host64_real (image_target, (x)))
539 #define grub_host_to_target64(x) (grub_host_to_target64_real (image_target, (x)))
540 #define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (image_target, (x)))
541 #define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x)))
542 #define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x)))
544 static inline grub_uint32_t
545 grub_target_to_host32_real (struct image_target_desc
*image_target
, grub_uint32_t in
)
547 if (image_target
->bigendian
)
548 return grub_be_to_cpu32 (in
);
550 return grub_le_to_cpu32 (in
);
553 static inline grub_uint64_t
554 grub_target_to_host64_real (struct image_target_desc
*image_target
, grub_uint64_t in
)
556 if (image_target
->bigendian
)
557 return grub_be_to_cpu64 (in
);
559 return grub_le_to_cpu64 (in
);
562 static inline grub_uint64_t
563 grub_host_to_target64_real (struct image_target_desc
*image_target
, grub_uint64_t in
)
565 if (image_target
->bigendian
)
566 return grub_cpu_to_be64 (in
);
568 return grub_cpu_to_le64 (in
);
571 static inline grub_uint32_t
572 grub_host_to_target32_real (struct image_target_desc
*image_target
, grub_uint32_t in
)
574 if (image_target
->bigendian
)
575 return grub_cpu_to_be32 (in
);
577 return grub_cpu_to_le32 (in
);
580 static inline grub_uint16_t
581 grub_target_to_host16_real (struct image_target_desc
*image_target
, grub_uint16_t in
)
583 if (image_target
->bigendian
)
584 return grub_be_to_cpu16 (in
);
586 return grub_le_to_cpu16 (in
);
589 static inline grub_uint16_t
590 grub_host_to_target16_real (struct image_target_desc
*image_target
, grub_uint16_t in
)
592 if (image_target
->bigendian
)
593 return grub_cpu_to_be16 (in
);
595 return grub_cpu_to_le16 (in
);
598 static inline grub_uint64_t
599 grub_host_to_target_addr_real (struct image_target_desc
*image_target
, grub_uint64_t in
)
601 if (image_target
->voidp_sizeof
== 8)
602 return grub_host_to_target64_real (image_target
, in
);
604 return grub_host_to_target32_real (image_target
, in
);
607 static inline grub_uint64_t
608 grub_target_to_host_real (struct image_target_desc
*image_target
, grub_uint64_t in
)
610 if (image_target
->voidp_sizeof
== 8)
611 return grub_target_to_host64_real (image_target
, in
);
613 return grub_target_to_host32_real (image_target
, in
);
616 #define GRUB_IEEE1275_NOTE_NAME "PowerPC"
617 #define GRUB_IEEE1275_NOTE_TYPE 0x1275
619 /* These structures are defined according to the CHRP binding to IEEE1275,
620 "Client Program Format" section. */
622 struct grub_ieee1275_note_hdr
624 grub_uint32_t namesz
;
625 grub_uint32_t descsz
;
627 char name
[sizeof (GRUB_IEEE1275_NOTE_NAME
)];
630 struct grub_ieee1275_note_desc
632 grub_uint32_t real_mode
;
633 grub_uint32_t real_base
;
634 grub_uint32_t real_size
;
635 grub_uint32_t virt_base
;
636 grub_uint32_t virt_size
;
637 grub_uint32_t load_base
;
640 struct grub_ieee1275_note
642 struct grub_ieee1275_note_hdr header
;
643 struct grub_ieee1275_note_desc descriptor
;
646 #define grub_target_to_host(val) grub_target_to_host_real(image_target, (val))
648 #include <grub/lib/LzmaEnc.h>
650 static void *SzAlloc(void *p
, size_t size
) { p
= p
; return xmalloc(size
); }
651 static void SzFree(void *p
, void *address
) { p
= p
; free(address
); }
652 static ISzAlloc g_Alloc
= { SzAlloc
, SzFree
};
655 compress_kernel_lzma (char *kernel_img
, size_t kernel_size
,
656 char **core_img
, size_t *core_size
)
659 unsigned char out_props
[5];
660 size_t out_props_size
= 5;
662 LzmaEncProps_Init(&props
);
663 props
.dictSize
= 1 << 16;
667 props
.numThreads
= 1;
669 *core_img
= xmalloc (kernel_size
);
671 *core_size
= kernel_size
;
672 if (LzmaEncode ((unsigned char *) *core_img
, core_size
,
673 (unsigned char *) kernel_img
,
675 &props
, out_props
, &out_props_size
,
676 0, NULL
, &g_Alloc
, &g_Alloc
) != SZ_OK
)
677 grub_util_error ("%s", _("cannot compress the kernel image"));
682 compress_kernel_xz (char *kernel_img
, size_t kernel_size
,
683 char **core_img
, size_t *core_size
)
685 lzma_stream strm
= LZMA_STREAM_INIT
;
687 lzma_options_lzma lzopts
= {
688 .dict_size
= 1 << 16,
690 .preset_dict_size
= 0,
694 .mode
= LZMA_MODE_NORMAL
,
699 lzma_filter fltrs
[] = {
700 { .id
= LZMA_FILTER_LZMA2
, .options
= &lzopts
},
701 { .id
= LZMA_VLI_UNKNOWN
, .options
= NULL
}
704 xzret
= lzma_stream_encoder (&strm
, fltrs
, LZMA_CHECK_NONE
);
705 if (xzret
!= LZMA_OK
)
706 grub_util_error ("%s", _("cannot compress the kernel image"));
708 *core_img
= xmalloc (kernel_size
);
710 *core_size
= kernel_size
;
711 strm
.next_in
= (unsigned char *) kernel_img
;
712 strm
.avail_in
= kernel_size
;
713 strm
.next_out
= (unsigned char *) *core_img
;
714 strm
.avail_out
= *core_size
;
718 xzret
= lzma_code (&strm
, LZMA_FINISH
);
719 if (xzret
== LZMA_OK
)
721 if (xzret
== LZMA_STREAM_END
)
723 grub_util_error ("%s", _("cannot compress the kernel image"));
726 *core_size
-= strm
.avail_out
;
731 compress_kernel (struct image_target_desc
*image_target
, char *kernel_img
,
732 size_t kernel_size
, char **core_img
, size_t *core_size
,
733 grub_compression_t comp
)
735 if (image_target
->flags
& PLATFORM_FLAGS_DECOMPRESSORS
736 && (comp
== COMPRESSION_LZMA
))
738 compress_kernel_lzma (kernel_img
, kernel_size
, core_img
,
744 if (image_target
->flags
& PLATFORM_FLAGS_DECOMPRESSORS
745 && (comp
== COMPRESSION_XZ
))
747 compress_kernel_xz (kernel_img
, kernel_size
, core_img
,
753 if (image_target
->flags
& PLATFORM_FLAGS_DECOMPRESSORS
754 && (comp
!= COMPRESSION_NONE
))
755 grub_util_error (_("unknown compression %d\n"), comp
);
757 *core_img
= xmalloc (kernel_size
);
758 memcpy (*core_img
, kernel_img
, kernel_size
);
759 *core_size
= kernel_size
;
762 struct fixup_block_list
764 struct fixup_block_list
*next
;
766 struct grub_pe32_fixup_block b
;
769 #pragma GCC diagnostic ignored "-Wcast-align"
771 #define MKIMAGE_ELF32 1
772 #include "grub-mkimagexx.c"
775 #define MKIMAGE_ELF64 1
776 #include "grub-mkimagexx.c"
780 generate_image (const char *dir
, const char *prefix
,
781 FILE *out
, const char *outname
, char *mods
[],
782 char *memdisk_path
, char **pubkey_paths
, size_t npubkeys
,
783 char *config_path
, struct image_target_desc
*image_target
, int note
,
784 grub_compression_t comp
)
786 char *kernel_img
, *core_img
;
787 size_t kernel_size
, total_module_size
, core_size
, exec_size
;
788 size_t memdisk_size
= 0, config_size
= 0, config_size_pure
= 0;
789 size_t prefix_size
= 0;
792 struct grub_util_path_list
*path_list
, *p
, *next
;
793 grub_size_t bss_size
;
794 grub_uint64_t start_address
;
795 void *rel_section
= 0;
796 grub_size_t reloc_size
= 0, align
;
797 size_t decompress_size
= 0;
799 if (comp
== COMPRESSION_AUTO
)
800 comp
= image_target
->default_compression
;
802 if (image_target
->id
== IMAGE_I386_PC
803 || image_target
->id
== IMAGE_I386_PC_PXE
)
804 comp
= COMPRESSION_LZMA
;
806 path_list
= grub_util_resolve_dependencies (dir
, "moddep.lst", mods
);
808 kernel_path
= grub_util_get_path (dir
, "kernel.img");
810 if (image_target
->voidp_sizeof
== 8)
811 total_module_size
= sizeof (struct grub_module_info64
);
813 total_module_size
= sizeof (struct grub_module_info32
);
817 for (i
= 0; i
< npubkeys
; i
++)
820 curs
= ALIGN_ADDR (grub_util_get_image_size (pubkey_paths
[i
]));
821 grub_util_info ("the size of public key %zd is 0x%llx",
822 i
, (unsigned long long) curs
);
823 total_module_size
+= curs
+ sizeof (struct grub_module_header
);
829 memdisk_size
= ALIGN_UP(grub_util_get_image_size (memdisk_path
), 512);
830 grub_util_info ("the size of memory disk is 0x%llx",
831 (unsigned long long) memdisk_size
);
832 total_module_size
+= memdisk_size
+ sizeof (struct grub_module_header
);
837 config_size_pure
= grub_util_get_image_size (config_path
) + 1;
838 config_size
= ALIGN_ADDR (config_size_pure
);
839 grub_util_info ("the size of config file is 0x%llx",
840 (unsigned long long) config_size
);
841 total_module_size
+= config_size
+ sizeof (struct grub_module_header
);
846 prefix_size
= ALIGN_ADDR (strlen (prefix
) + 1);
847 total_module_size
+= prefix_size
+ sizeof (struct grub_module_header
);
850 for (p
= path_list
; p
; p
= p
->next
)
851 total_module_size
+= (ALIGN_ADDR (grub_util_get_image_size (p
->name
))
852 + sizeof (struct grub_module_header
));
854 grub_util_info ("the total module size is 0x%llx",
855 (unsigned long long) total_module_size
);
857 if (image_target
->voidp_sizeof
== 4)
858 kernel_img
= load_image32 (kernel_path
, &exec_size
, &kernel_size
, &bss_size
,
859 total_module_size
, &start_address
, &rel_section
,
860 &reloc_size
, &align
, image_target
);
862 kernel_img
= load_image64 (kernel_path
, &exec_size
, &kernel_size
, &bss_size
,
863 total_module_size
, &start_address
, &rel_section
,
864 &reloc_size
, &align
, image_target
);
866 if ((image_target
->flags
& PLATFORM_FLAGS_DECOMPRESSORS
)
867 && (image_target
->total_module_size
!= TARGET_NO_FIELD
))
868 *((grub_uint32_t
*) (kernel_img
+ image_target
->total_module_size
))
869 = grub_host_to_target32 (total_module_size
);
871 if (image_target
->flags
& PLATFORM_FLAGS_MODULES_BEFORE_KERNEL
)
872 memmove (kernel_img
+ total_module_size
, kernel_img
, kernel_size
);
874 if (image_target
->voidp_sizeof
== 8)
876 /* Fill in the grub_module_info structure. */
877 struct grub_module_info64
*modinfo
;
878 if (image_target
->flags
& PLATFORM_FLAGS_MODULES_BEFORE_KERNEL
)
879 modinfo
= (struct grub_module_info64
*) kernel_img
;
881 modinfo
= (struct grub_module_info64
*) (kernel_img
+ kernel_size
);
882 memset (modinfo
, 0, sizeof (struct grub_module_info64
));
883 modinfo
->magic
= grub_host_to_target32 (GRUB_MODULE_MAGIC
);
884 modinfo
->offset
= grub_host_to_target_addr (sizeof (struct grub_module_info64
));
885 modinfo
->size
= grub_host_to_target_addr (total_module_size
);
886 if (image_target
->flags
& PLATFORM_FLAGS_MODULES_BEFORE_KERNEL
)
887 offset
= sizeof (struct grub_module_info64
);
889 offset
= kernel_size
+ sizeof (struct grub_module_info64
);
893 /* Fill in the grub_module_info structure. */
894 struct grub_module_info32
*modinfo
;
895 if (image_target
->flags
& PLATFORM_FLAGS_MODULES_BEFORE_KERNEL
)
896 modinfo
= (struct grub_module_info32
*) kernel_img
;
898 modinfo
= (struct grub_module_info32
*) (kernel_img
+ kernel_size
);
899 memset (modinfo
, 0, sizeof (struct grub_module_info32
));
900 modinfo
->magic
= grub_host_to_target32 (GRUB_MODULE_MAGIC
);
901 modinfo
->offset
= grub_host_to_target_addr (sizeof (struct grub_module_info32
));
902 modinfo
->size
= grub_host_to_target_addr (total_module_size
);
903 if (image_target
->flags
& PLATFORM_FLAGS_MODULES_BEFORE_KERNEL
)
904 offset
= sizeof (struct grub_module_info32
);
906 offset
= kernel_size
+ sizeof (struct grub_module_info32
);
909 for (p
= path_list
; p
; p
= p
->next
)
911 struct grub_module_header
*header
;
912 size_t mod_size
, orig_size
;
914 orig_size
= grub_util_get_image_size (p
->name
);
915 mod_size
= ALIGN_ADDR (orig_size
);
917 header
= (struct grub_module_header
*) (kernel_img
+ offset
);
918 memset (header
, 0, sizeof (struct grub_module_header
));
919 header
->type
= grub_host_to_target32 (OBJ_TYPE_ELF
);
920 header
->size
= grub_host_to_target32 (mod_size
+ sizeof (*header
));
921 offset
+= sizeof (*header
);
922 memset (kernel_img
+ offset
+ orig_size
, 0, mod_size
- orig_size
);
924 grub_util_load_image (p
->name
, kernel_img
+ offset
);
930 for (i
= 0; i
< npubkeys
; i
++)
933 struct grub_module_header
*header
;
935 curs
= grub_util_get_image_size (pubkey_paths
[i
]);
937 header
= (struct grub_module_header
*) (kernel_img
+ offset
);
938 memset (header
, 0, sizeof (struct grub_module_header
));
939 header
->type
= grub_host_to_target32 (OBJ_TYPE_PUBKEY
);
940 header
->size
= grub_host_to_target32 (curs
+ sizeof (*header
));
941 offset
+= sizeof (*header
);
943 grub_util_load_image (pubkey_paths
[i
], kernel_img
+ offset
);
944 offset
+= ALIGN_ADDR (curs
);
950 struct grub_module_header
*header
;
952 header
= (struct grub_module_header
*) (kernel_img
+ offset
);
953 memset (header
, 0, sizeof (struct grub_module_header
));
954 header
->type
= grub_host_to_target32 (OBJ_TYPE_MEMDISK
);
955 header
->size
= grub_host_to_target32 (memdisk_size
+ sizeof (*header
));
956 offset
+= sizeof (*header
);
958 grub_util_load_image (memdisk_path
, kernel_img
+ offset
);
959 offset
+= memdisk_size
;
964 struct grub_module_header
*header
;
966 header
= (struct grub_module_header
*) (kernel_img
+ offset
);
967 memset (header
, 0, sizeof (struct grub_module_header
));
968 header
->type
= grub_host_to_target32 (OBJ_TYPE_CONFIG
);
969 header
->size
= grub_host_to_target32 (config_size
+ sizeof (*header
));
970 offset
+= sizeof (*header
);
972 grub_util_load_image (config_path
, kernel_img
+ offset
);
973 *(kernel_img
+ offset
+ config_size_pure
- 1) = 0;
974 offset
+= config_size
;
979 struct grub_module_header
*header
;
981 header
= (struct grub_module_header
*) (kernel_img
+ offset
);
982 memset (header
, 0, sizeof (struct grub_module_header
));
983 header
->type
= grub_host_to_target32 (OBJ_TYPE_PREFIX
);
984 header
->size
= grub_host_to_target32 (prefix_size
+ sizeof (*header
));
985 offset
+= sizeof (*header
);
987 grub_memset (kernel_img
+ offset
, 0, prefix_size
);
988 grub_strcpy (kernel_img
+ offset
, prefix
);
989 offset
+= prefix_size
;
992 grub_util_info ("kernel_img=%p, kernel_size=0x%llx", kernel_img
,
993 (unsigned long long) kernel_size
);
994 compress_kernel (image_target
, kernel_img
, kernel_size
+ total_module_size
,
995 &core_img
, &core_size
, comp
);
998 grub_util_info ("the core size is 0x%llx", (unsigned long long) core_size
);
1000 if (!(image_target
->flags
& PLATFORM_FLAGS_DECOMPRESSORS
)
1001 && image_target
->total_module_size
!= TARGET_NO_FIELD
)
1002 *((grub_uint32_t
*) (core_img
+ image_target
->total_module_size
))
1003 = grub_host_to_target32 (total_module_size
);
1005 if (image_target
->flags
& PLATFORM_FLAGS_DECOMPRESSORS
)
1009 char *decompress_path
, *decompress_img
;
1014 case COMPRESSION_XZ
:
1015 name
= "xz_decompress.img";
1017 case COMPRESSION_LZMA
:
1018 name
= "lzma_decompress.img";
1020 case COMPRESSION_NONE
:
1021 name
= "none_decompress.img";
1024 grub_util_error (_("unknown compression %d\n"), comp
);
1027 decompress_path
= grub_util_get_path (dir
, name
);
1028 decompress_size
= grub_util_get_image_size (decompress_path
);
1029 decompress_img
= grub_util_read_image (decompress_path
);
1031 if ((image_target
->id
== IMAGE_I386_PC
1032 || image_target
->id
== IMAGE_I386_PC_PXE
)
1033 && decompress_size
> GRUB_KERNEL_I386_PC_LINK_ADDR
- 0x8200)
1034 grub_util_error ("%s", _("Decompressor is too big"));
1036 if (image_target
->decompressor_compressed_size
!= TARGET_NO_FIELD
)
1037 *((grub_uint32_t
*) (decompress_img
1038 + image_target
->decompressor_compressed_size
))
1039 = grub_host_to_target32 (core_size
);
1041 if (image_target
->decompressor_uncompressed_size
!= TARGET_NO_FIELD
)
1042 *((grub_uint32_t
*) (decompress_img
1043 + image_target
->decompressor_uncompressed_size
))
1044 = grub_host_to_target32 (kernel_size
+ total_module_size
);
1046 if (image_target
->decompressor_uncompressed_addr
!= TARGET_NO_FIELD
)
1048 if (image_target
->flags
& PLATFORM_FLAGS_MODULES_BEFORE_KERNEL
)
1049 *((grub_uint32_t
*) (decompress_img
+ image_target
->decompressor_uncompressed_addr
))
1050 = grub_host_to_target_addr (image_target
->link_addr
- total_module_size
);
1052 *((grub_uint32_t
*) (decompress_img
+ image_target
->decompressor_uncompressed_addr
))
1053 = grub_host_to_target_addr (image_target
->link_addr
);
1055 full_size
= core_size
+ decompress_size
;
1057 full_img
= xmalloc (full_size
);
1058 memset (full_img
, 0, full_size
);
1060 memcpy (full_img
, decompress_img
, decompress_size
);
1062 memcpy (full_img
+ decompress_size
, core_img
, core_size
);
1064 memset (full_img
+ decompress_size
+ core_size
, 0,
1065 full_size
- (decompress_size
+ core_size
));
1068 core_img
= full_img
;
1069 core_size
= full_size
;
1072 switch (image_target
->id
)
1075 case IMAGE_I386_PC_PXE
:
1076 if (GRUB_KERNEL_I386_PC_LINK_ADDR
+ core_size
> 0x78000
1077 || (core_size
> (0xffff << GRUB_DISK_SECTOR_BITS
))
1078 || (kernel_size
+ bss_size
+ GRUB_KERNEL_I386_PC_LINK_ADDR
> 0x68000))
1079 grub_util_error (_("core image is too big (0x%x > 0x%x)"),
1080 GRUB_KERNEL_I386_PC_LINK_ADDR
+ (unsigned) core_size
,
1083 case IMAGE_COREBOOT
:
1085 if (kernel_size
+ bss_size
+ GRUB_KERNEL_I386_PC_LINK_ADDR
> 0x68000)
1086 grub_util_error (_("kernel image is too big (0x%x > 0x%x)"),
1087 (unsigned) kernel_size
+ (unsigned) bss_size
1088 + GRUB_KERNEL_I386_PC_LINK_ADDR
,
1091 case IMAGE_LOONGSON_ELF
:
1092 case IMAGE_YEELOONG_FLASH
:
1093 case IMAGE_FULOONG2F_FLASH
:
1095 case IMAGE_MIPS_ARC
:
1096 case IMAGE_QEMU_MIPS_FLASH
:
1098 case IMAGE_SPARC64_AOUT
:
1099 case IMAGE_SPARC64_RAW
:
1100 case IMAGE_SPARC64_CDCORE
:
1101 case IMAGE_I386_IEEE1275
:
1107 switch (image_target
->id
)
1110 case IMAGE_I386_PC_PXE
:
1113 char *boot_path
, *boot_img
;
1116 num
= ((core_size
+ GRUB_DISK_SECTOR_SIZE
- 1) >> GRUB_DISK_SECTOR_BITS
);
1117 if (image_target
->id
== IMAGE_I386_PC_PXE
)
1119 char *pxeboot_path
, *pxeboot_img
;
1120 size_t pxeboot_size
;
1123 pxeboot_path
= grub_util_get_path (dir
, "pxeboot.img");
1124 pxeboot_size
= grub_util_get_image_size (pxeboot_path
);
1125 pxeboot_img
= grub_util_read_image (pxeboot_path
);
1127 grub_util_write_image (pxeboot_img
, pxeboot_size
, out
,
1130 free (pxeboot_path
);
1132 /* Remove Multiboot header to avoid confusing ipxe. */
1133 for (ptr
= (grub_uint32_t
*) core_img
;
1134 ptr
< (grub_uint32_t
*) (core_img
+ MULTIBOOT_SEARCH
); ptr
++)
1135 if (*ptr
== grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC
)
1136 && grub_target_to_host32 (ptr
[0])
1137 + grub_target_to_host32 (ptr
[1])
1138 + grub_target_to_host32 (ptr
[2]) == 0)
1145 boot_path
= grub_util_get_path (dir
, "diskboot.img");
1146 boot_size
= grub_util_get_image_size (boot_path
);
1147 if (boot_size
!= GRUB_DISK_SECTOR_SIZE
)
1148 grub_util_error (_("diskboot.img size must be %u bytes"),
1149 GRUB_DISK_SECTOR_SIZE
);
1151 boot_img
= grub_util_read_image (boot_path
);
1154 struct grub_pc_bios_boot_blocklist
*block
;
1155 block
= (struct grub_pc_bios_boot_blocklist
*) (boot_img
1156 + GRUB_DISK_SECTOR_SIZE
1158 block
->len
= grub_host_to_target16 (num
);
1160 /* This is filled elsewhere. Verify it just in case. */
1161 assert (block
->segment
1162 == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG
1163 + (GRUB_DISK_SECTOR_SIZE
>> 4)));
1166 grub_util_write_image (boot_img
, boot_size
, out
, outname
);
1174 grub_uint8_t
*header
;
1177 struct grub_pe32_coff_header
*c
;
1178 struct grub_pe32_section_table
*text_section
, *data_section
;
1179 struct grub_pe32_section_table
*mods_section
, *reloc_section
;
1180 static const grub_uint8_t stub
[] = GRUB_PE32_MSDOS_STUB
;
1184 if (image_target
->voidp_sizeof
== 4)
1185 header_size
= EFI32_HEADER_SIZE
;
1187 header_size
= EFI64_HEADER_SIZE
;
1189 reloc_addr
= ALIGN_UP (header_size
+ core_size
,
1190 image_target
->section_align
);
1192 pe_size
= ALIGN_UP (reloc_addr
+ reloc_size
,
1193 image_target
->section_align
);
1194 pe_img
= xmalloc (reloc_addr
+ reloc_size
);
1195 memset (pe_img
, 0, header_size
);
1196 memcpy ((char *) pe_img
+ header_size
, core_img
, core_size
);
1197 memcpy ((char *) pe_img
+ reloc_addr
, rel_section
, reloc_size
);
1201 memcpy (header
, stub
, GRUB_PE32_MSDOS_STUB_SIZE
);
1202 memcpy (header
+ GRUB_PE32_MSDOS_STUB_SIZE
, "PE\0\0",
1203 GRUB_PE32_SIGNATURE_SIZE
);
1205 /* The COFF file header. */
1206 c
= (struct grub_pe32_coff_header
*) (header
+ GRUB_PE32_MSDOS_STUB_SIZE
1207 + GRUB_PE32_SIGNATURE_SIZE
);
1208 c
->machine
= grub_host_to_target16 (image_target
->pe_target
);
1210 c
->num_sections
= grub_host_to_target16 (4);
1211 c
->time
= grub_host_to_target32 (time (0));
1212 c
->characteristics
= grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE
1213 | GRUB_PE32_LINE_NUMS_STRIPPED
1214 | ((image_target
->voidp_sizeof
== 4)
1215 ? GRUB_PE32_32BIT_MACHINE
1217 | GRUB_PE32_LOCAL_SYMS_STRIPPED
1218 | GRUB_PE32_DEBUG_STRIPPED
);
1220 /* The PE Optional header. */
1221 if (image_target
->voidp_sizeof
== 4)
1223 struct grub_pe32_optional_header
*o
;
1225 c
->optional_header_size
= grub_host_to_target16 (sizeof (struct grub_pe32_optional_header
));
1227 o
= (struct grub_pe32_optional_header
*)
1228 (header
+ GRUB_PE32_MSDOS_STUB_SIZE
+ GRUB_PE32_SIGNATURE_SIZE
1229 + sizeof (struct grub_pe32_coff_header
));
1230 o
->magic
= grub_host_to_target16 (GRUB_PE32_PE32_MAGIC
);
1231 o
->code_size
= grub_host_to_target32 (exec_size
);
1232 o
->data_size
= grub_cpu_to_le32 (reloc_addr
- exec_size
1234 o
->bss_size
= grub_cpu_to_le32 (bss_size
);
1235 o
->entry_addr
= grub_cpu_to_le32 (start_address
);
1236 o
->code_base
= grub_cpu_to_le32 (header_size
);
1238 o
->data_base
= grub_host_to_target32 (header_size
+ exec_size
);
1241 o
->section_alignment
= grub_host_to_target32 (image_target
->section_align
);
1242 o
->file_alignment
= grub_host_to_target32 (image_target
->section_align
);
1243 o
->image_size
= grub_host_to_target32 (pe_size
);
1244 o
->header_size
= grub_host_to_target32 (header_size
);
1245 o
->subsystem
= grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION
);
1247 /* Do these really matter? */
1248 o
->stack_reserve_size
= grub_host_to_target32 (0x10000);
1249 o
->stack_commit_size
= grub_host_to_target32 (0x10000);
1250 o
->heap_reserve_size
= grub_host_to_target32 (0x10000);
1251 o
->heap_commit_size
= grub_host_to_target32 (0x10000);
1253 o
->num_data_directories
= grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES
);
1255 o
->base_relocation_table
.rva
= grub_host_to_target32 (reloc_addr
);
1256 o
->base_relocation_table
.size
= grub_host_to_target32 (reloc_size
);
1261 struct grub_pe64_optional_header
*o
;
1263 c
->optional_header_size
= grub_host_to_target16 (sizeof (struct grub_pe64_optional_header
));
1265 o
= (struct grub_pe64_optional_header
*)
1266 (header
+ GRUB_PE32_MSDOS_STUB_SIZE
+ GRUB_PE32_SIGNATURE_SIZE
1267 + sizeof (struct grub_pe32_coff_header
));
1268 o
->magic
= grub_host_to_target16 (GRUB_PE32_PE64_MAGIC
);
1269 o
->code_size
= grub_host_to_target32 (exec_size
);
1270 o
->data_size
= grub_cpu_to_le32 (reloc_addr
- exec_size
1272 o
->bss_size
= grub_cpu_to_le32 (bss_size
);
1273 o
->entry_addr
= grub_cpu_to_le32 (start_address
);
1274 o
->code_base
= grub_cpu_to_le32 (header_size
);
1276 o
->section_alignment
= grub_host_to_target32 (image_target
->section_align
);
1277 o
->file_alignment
= grub_host_to_target32 (image_target
->section_align
);
1278 o
->image_size
= grub_host_to_target32 (pe_size
);
1279 o
->header_size
= grub_host_to_target32 (header_size
);
1280 o
->subsystem
= grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION
);
1282 /* Do these really matter? */
1283 o
->stack_reserve_size
= grub_host_to_target64 (0x10000);
1284 o
->stack_commit_size
= grub_host_to_target64 (0x10000);
1285 o
->heap_reserve_size
= grub_host_to_target64 (0x10000);
1286 o
->heap_commit_size
= grub_host_to_target64 (0x10000);
1288 o
->num_data_directories
1289 = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES
);
1291 o
->base_relocation_table
.rva
= grub_host_to_target32 (reloc_addr
);
1292 o
->base_relocation_table
.size
= grub_host_to_target32 (reloc_size
);
1296 text_section
= sections
;
1297 strcpy (text_section
->name
, ".text");
1298 text_section
->virtual_size
= grub_cpu_to_le32 (exec_size
);
1299 text_section
->virtual_address
= grub_cpu_to_le32 (header_size
);
1300 text_section
->raw_data_size
= grub_cpu_to_le32 (exec_size
);
1301 text_section
->raw_data_offset
= grub_cpu_to_le32 (header_size
);
1302 text_section
->characteristics
= grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE
1303 | GRUB_PE32_SCN_MEM_EXECUTE
1304 | GRUB_PE32_SCN_MEM_READ
);
1306 data_section
= text_section
+ 1;
1307 strcpy (data_section
->name
, ".data");
1308 data_section
->virtual_size
= grub_cpu_to_le32 (kernel_size
- exec_size
);
1309 data_section
->virtual_address
= grub_cpu_to_le32 (header_size
+ exec_size
);
1310 data_section
->raw_data_size
= grub_cpu_to_le32 (kernel_size
- exec_size
);
1311 data_section
->raw_data_offset
= grub_cpu_to_le32 (header_size
+ exec_size
);
1312 data_section
->characteristics
1313 = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1314 | GRUB_PE32_SCN_MEM_READ
1315 | GRUB_PE32_SCN_MEM_WRITE
);
1318 bss_section
= data_section
+ 1;
1319 strcpy (bss_section
->name
, ".bss");
1320 bss_section
->virtual_size
= grub_cpu_to_le32 (bss_size
);
1321 bss_section
->virtual_address
= grub_cpu_to_le32 (header_size
+ kernel_size
);
1322 bss_section
->raw_data_size
= 0;
1323 bss_section
->raw_data_offset
= 0;
1324 bss_section
->characteristics
1325 = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ
1326 | GRUB_PE32_SCN_MEM_WRITE
1327 | GRUB_PE32_SCN_ALIGN_64BYTES
1328 | GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1332 mods_section
= data_section
+ 1;
1333 strcpy (mods_section
->name
, "mods");
1334 mods_section
->virtual_size
= grub_cpu_to_le32 (reloc_addr
- kernel_size
- header_size
);
1335 mods_section
->virtual_address
= grub_cpu_to_le32 (header_size
+ kernel_size
+ bss_size
);
1336 mods_section
->raw_data_size
= grub_cpu_to_le32 (reloc_addr
- kernel_size
- header_size
);
1337 mods_section
->raw_data_offset
= grub_cpu_to_le32 (header_size
+ kernel_size
);
1338 mods_section
->characteristics
1339 = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1340 | GRUB_PE32_SCN_MEM_READ
1341 | GRUB_PE32_SCN_MEM_WRITE
);
1343 reloc_section
= mods_section
+ 1;
1344 strcpy (reloc_section
->name
, ".reloc");
1345 reloc_section
->virtual_size
= grub_cpu_to_le32 (reloc_size
);
1346 reloc_section
->virtual_address
= grub_cpu_to_le32 (reloc_addr
+ bss_size
);
1347 reloc_section
->raw_data_size
= grub_cpu_to_le32 (reloc_size
);
1348 reloc_section
->raw_data_offset
= grub_cpu_to_le32 (reloc_addr
);
1349 reloc_section
->characteristics
1350 = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1351 | GRUB_PE32_SCN_MEM_DISCARDABLE
1352 | GRUB_PE32_SCN_MEM_READ
);
1355 core_size
= pe_size
;
1362 char *boot_path
, *boot_img
;
1365 boot_path
= grub_util_get_path (dir
, "boot.img");
1366 boot_size
= grub_util_get_image_size (boot_path
);
1367 boot_img
= grub_util_read_image (boot_path
);
1369 /* Rom sizes must be 64k-aligned. */
1370 rom_size
= ALIGN_UP (core_size
+ boot_size
, 64 * 1024);
1372 rom_img
= xmalloc (rom_size
);
1373 memset (rom_img
, 0, rom_size
);
1375 *((grub_int32_t
*) (core_img
+ GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR
))
1376 = grub_host_to_target32 ((grub_uint32_t
) -rom_size
);
1378 memcpy (rom_img
, core_img
, core_size
);
1380 *((grub_int32_t
*) (boot_img
+ GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR
))
1381 = grub_host_to_target32 ((grub_uint32_t
) -rom_size
);
1383 memcpy (rom_img
+ rom_size
- boot_size
, boot_img
, boot_size
);
1387 core_size
= rom_size
;
1393 case IMAGE_SPARC64_AOUT
:
1397 struct grub_aout32_header
*aout_head
;
1399 aout_size
= core_size
+ sizeof (*aout_head
);
1400 aout_img
= xmalloc (aout_size
);
1401 aout_head
= aout_img
;
1402 grub_memset (aout_head
, 0, sizeof (*aout_head
));
1403 aout_head
->a_midmag
= grub_host_to_target32 ((AOUT_MID_SUN
<< 16)
1405 aout_head
->a_text
= grub_host_to_target32 (core_size
);
1407 = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS
);
1408 memcpy ((char *) aout_img
+ sizeof (*aout_head
), core_img
, core_size
);
1411 core_img
= aout_img
;
1412 core_size
= aout_size
;
1415 case IMAGE_SPARC64_RAW
:
1418 char *boot_path
, *boot_img
;
1421 num
= ((core_size
+ GRUB_DISK_SECTOR_SIZE
- 1) >> GRUB_DISK_SECTOR_BITS
);
1422 num
<<= GRUB_DISK_SECTOR_BITS
;
1424 boot_path
= grub_util_get_path (dir
, "diskboot.img");
1425 boot_size
= grub_util_get_image_size (boot_path
);
1426 if (boot_size
!= GRUB_DISK_SECTOR_SIZE
)
1427 grub_util_error (_("diskboot.img size must be %u bytes"),
1428 GRUB_DISK_SECTOR_SIZE
);
1430 boot_img
= grub_util_read_image (boot_path
);
1432 *((grub_uint32_t
*) (boot_img
+ GRUB_DISK_SECTOR_SIZE
1433 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE
+ 8))
1434 = grub_host_to_target32 (num
);
1436 grub_util_write_image (boot_img
, boot_size
, out
, outname
);
1441 case IMAGE_SPARC64_CDCORE
:
1443 case IMAGE_YEELOONG_FLASH
:
1444 case IMAGE_FULOONG2F_FLASH
:
1448 char *boot_path
, *boot_img
;
1450 grub_uint8_t context
[GRUB_MD_SHA512
->contextsize
];
1451 /* fwstart.img is the only part which can't be tested by using *-elf
1452 target. Check it against the checksum. */
1453 const grub_uint8_t yeeloong_fwstart_good_hash
[512 / 8] =
1455 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a,
1456 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5,
1457 0x75, 0x64, 0x6b, 0xbb, 0x24, 0xcd, 0xb4, 0xbc,
1458 0xf2, 0x3e, 0x23, 0xf9, 0xc2, 0x6a, 0x8c, 0xde,
1459 0x3b, 0x94, 0x9c, 0xcc, 0xa5, 0xa7, 0x58, 0xb1,
1460 0xbe, 0x8b, 0x3d, 0x73, 0x98, 0x18, 0x7e, 0x68,
1461 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7,
1462 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25
1464 const grub_uint8_t fuloong2f_fwstart_good_hash
[512 / 8] =
1466 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62,
1467 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c,
1468 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d,
1469 0x02, 0x84, 0xa0, 0x85, 0xf2, 0xd1, 0xb9, 0x53,
1470 0xa2, 0xbc, 0xf2, 0xe1, 0x39, 0x1e, 0x51, 0xb5,
1471 0xaf, 0xec, 0x9e, 0xf2, 0xf1, 0xf3, 0x0a, 0x2f,
1472 0xe6, 0xf1, 0x08, 0x89, 0xbe, 0xbc, 0x73, 0xab,
1473 0x46, 0x50, 0xd6, 0x21, 0xce, 0x8e, 0x24, 0xa7
1475 const grub_uint8_t
*fwstart_good_hash
;
1477 if (image_target
->id
== IMAGE_FULOONG2F_FLASH
)
1479 fwstart_good_hash
= fuloong2f_fwstart_good_hash
;
1480 boot_path
= grub_util_get_path (dir
, "fwstart_fuloong2f.img");
1484 fwstart_good_hash
= yeeloong_fwstart_good_hash
;
1485 boot_path
= grub_util_get_path (dir
, "fwstart.img");
1488 boot_size
= grub_util_get_image_size (boot_path
);
1489 boot_img
= grub_util_read_image (boot_path
);
1491 grub_memset (context
, 0, sizeof (context
));
1492 GRUB_MD_SHA512
->init (context
);
1493 GRUB_MD_SHA512
->write (context
, boot_img
, boot_size
);
1494 GRUB_MD_SHA512
->final (context
);
1495 if (grub_memcmp (GRUB_MD_SHA512
->read (context
), fwstart_good_hash
,
1496 GRUB_MD_SHA512
->mdlen
) != 0)
1497 /* TRANSLATORS: fwstart.img may still be good, just it wasn't checked. */
1498 grub_util_warn ("%s",
1499 _("fwstart.img doesn't match the known good version. "
1500 "proceed at your own risk"));
1502 if (core_size
+ boot_size
> 512 * 1024)
1503 grub_util_error ("%s", _("firmware image is too big"));
1504 rom_size
= 512 * 1024;
1506 rom_img
= xmalloc (rom_size
);
1507 memset (rom_img
, 0, rom_size
);
1509 memcpy (rom_img
, boot_img
, boot_size
);
1511 memcpy (rom_img
+ boot_size
, core_img
, core_size
);
1513 memset (rom_img
+ boot_size
+ core_size
, 0,
1514 rom_size
- (boot_size
+ core_size
));
1518 core_size
= rom_size
;
1521 case IMAGE_QEMU_MIPS_FLASH
:
1526 if (core_size
> 512 * 1024)
1527 grub_util_error ("%s", _("firmware image is too big"));
1528 rom_size
= 512 * 1024;
1530 rom_img
= xmalloc (rom_size
);
1531 memset (rom_img
, 0, rom_size
);
1533 memcpy (rom_img
, core_img
, core_size
);
1535 memset (rom_img
+ core_size
, 0,
1536 rom_size
- core_size
);
1540 core_size
= rom_size
;
1546 struct grub_uboot_image_header
*hdr
;
1547 GRUB_PROPERLY_ALIGNED_ARRAY (crc32_context
, GRUB_MD_CRC32
->contextsize
);
1549 hdr
= xmalloc (core_size
+ sizeof (struct grub_uboot_image_header
));
1550 memcpy (hdr
+ 1, core_img
, core_size
);
1552 memset (hdr
, 0, sizeof (*hdr
));
1553 hdr
->ih_magic
= grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC
);
1554 hdr
->ih_time
= grub_cpu_to_be32 (time (0));
1555 hdr
->ih_size
= grub_cpu_to_be32 (core_size
);
1556 hdr
->ih_load
= grub_cpu_to_be32 (image_target
->link_addr
);
1557 hdr
->ih_ep
= grub_cpu_to_be32 (image_target
->link_addr
);
1558 hdr
->ih_type
= GRUB_UBOOT_IH_TYPE_KERNEL
;
1559 hdr
->ih_os
= GRUB_UBOOT_IH_OS_LINUX
;
1560 hdr
->ih_arch
= GRUB_UBOOT_IH_ARCH_ARM
;
1561 hdr
->ih_comp
= GRUB_UBOOT_IH_COMP_NONE
;
1563 GRUB_MD_CRC32
->init(crc32_context
);
1564 GRUB_MD_CRC32
->write(crc32_context
, hdr
+ 1, core_size
);
1565 GRUB_MD_CRC32
->final(crc32_context
);
1566 hdr
->ih_dcrc
= grub_get_unaligned32 (GRUB_MD_CRC32
->read (crc32_context
));
1568 GRUB_MD_CRC32
->init(crc32_context
);
1569 GRUB_MD_CRC32
->write(crc32_context
, hdr
, sizeof (*hdr
));
1570 GRUB_MD_CRC32
->final(crc32_context
);
1571 hdr
->ih_hcrc
= grub_get_unaligned32 (GRUB_MD_CRC32
->read (crc32_context
));
1574 core_img
= (char *) hdr
;
1575 core_size
+= sizeof (struct grub_uboot_image_header
);
1579 case IMAGE_MIPS_ARC
:
1582 struct ecoff_header
{
1583 grub_uint16_t magic
;
1587 grub_uint32_t nsyms
;
1589 grub_uint16_t flags
;
1590 grub_uint16_t magic2
;
1591 grub_uint16_t version
;
1592 grub_uint32_t textsize
;
1593 grub_uint32_t datasize
;
1594 grub_uint32_t bsssize
;
1595 grub_uint32_t entry
;
1596 grub_uint32_t text_start
;
1597 grub_uint32_t data_start
;
1598 grub_uint32_t bss_start
;
1599 grub_uint32_t gprmask
;
1600 grub_uint32_t cprmask
[4];
1601 grub_uint32_t gp_value
;
1603 struct ecoff_section
1606 grub_uint32_t paddr
;
1607 grub_uint32_t vaddr
;
1609 grub_uint32_t file_offset
;
1610 grub_uint32_t reloc
;
1612 grub_uint16_t nreloc
;
1614 grub_uint32_t flags
;
1616 struct ecoff_header
*head
;
1617 struct ecoff_section
*section
;
1618 grub_uint32_t target_addr
;
1619 size_t program_size
;
1621 program_size
= ALIGN_ADDR (core_size
);
1622 if (comp
== COMPRESSION_NONE
)
1623 target_addr
= (image_target
->link_addr
- decompress_size
);
1625 target_addr
= ALIGN_UP (image_target
->link_addr
1626 + kernel_size
+ total_module_size
, 32);
1628 ecoff_img
= xmalloc (program_size
+ sizeof (*head
) + sizeof (*section
));
1629 grub_memset (ecoff_img
, 0, program_size
+ sizeof (*head
) + sizeof (*section
));
1630 head
= (void *) ecoff_img
;
1631 section
= (void *) (head
+ 1);
1632 head
->magic
= image_target
->bigendian
? grub_host_to_target16 (0x160)
1633 : grub_host_to_target16 (0x166);
1634 head
->nsec
= grub_host_to_target16 (1);
1635 head
->time
= grub_host_to_target32 (0);
1636 head
->opt
= grub_host_to_target16 (0x38);
1637 head
->flags
= image_target
->bigendian
1638 ? grub_host_to_target16 (0x207)
1639 : grub_host_to_target16 (0x103);
1640 head
->magic2
= grub_host_to_target16 (0x107);
1641 head
->textsize
= grub_host_to_target32 (program_size
);
1642 head
->entry
= grub_host_to_target32 (target_addr
);
1643 head
->text_start
= grub_host_to_target32 (target_addr
);
1644 head
->data_start
= grub_host_to_target32 (target_addr
+ program_size
);
1645 grub_memcpy (section
->name
, ".text", sizeof (".text") - 1);
1646 section
->vaddr
= grub_host_to_target32 (target_addr
);
1647 section
->size
= grub_host_to_target32 (program_size
);
1648 section
->file_offset
= grub_host_to_target32 (sizeof (*head
) + sizeof (*section
));
1649 if (!image_target
->bigendian
)
1651 section
->paddr
= grub_host_to_target32 (0xaa60);
1652 section
->flags
= grub_host_to_target32 (0x20);
1654 memcpy (section
+ 1, core_img
, core_size
);
1656 core_img
= ecoff_img
;
1657 core_size
= program_size
+ sizeof (*head
) + sizeof (*section
);
1660 case IMAGE_LOONGSON_ELF
:
1662 case IMAGE_COREBOOT
:
1663 case IMAGE_I386_IEEE1275
:
1666 size_t program_size
;
1669 grub_uint32_t target_addr
;
1670 int header_size
, footer_size
= 0;
1673 if (image_target
->id
!= IMAGE_LOONGSON_ELF
)
1679 footer_size
+= sizeof (struct grub_ieee1275_note
);
1681 header_size
= ALIGN_ADDR (sizeof (*ehdr
) + phnum
* sizeof (*phdr
));
1683 program_size
= ALIGN_ADDR (core_size
);
1685 elf_img
= xmalloc (program_size
+ header_size
+ footer_size
);
1686 memset (elf_img
, 0, program_size
+ header_size
);
1687 memcpy (elf_img
+ header_size
, core_img
, core_size
);
1688 ehdr
= (void *) elf_img
;
1689 phdr
= (void *) (elf_img
+ sizeof (*ehdr
));
1690 memcpy (ehdr
->e_ident
, ELFMAG
, SELFMAG
);
1691 ehdr
->e_ident
[EI_CLASS
] = ELFCLASS32
;
1692 if (!image_target
->bigendian
)
1693 ehdr
->e_ident
[EI_DATA
] = ELFDATA2LSB
;
1695 ehdr
->e_ident
[EI_DATA
] = ELFDATA2MSB
;
1696 ehdr
->e_ident
[EI_VERSION
] = EV_CURRENT
;
1697 ehdr
->e_ident
[EI_OSABI
] = ELFOSABI_NONE
;
1698 ehdr
->e_type
= grub_host_to_target16 (ET_EXEC
);
1699 ehdr
->e_machine
= grub_host_to_target16 (image_target
->elf_target
);
1700 ehdr
->e_version
= grub_host_to_target32 (EV_CURRENT
);
1702 ehdr
->e_phoff
= grub_host_to_target32 ((char *) phdr
- (char *) ehdr
);
1703 ehdr
->e_phentsize
= grub_host_to_target16 (sizeof (*phdr
));
1704 ehdr
->e_phnum
= grub_host_to_target16 (phnum
);
1706 /* No section headers. */
1707 ehdr
->e_shoff
= grub_host_to_target32 (0);
1708 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
1709 ehdr
->e_shentsize
= grub_host_to_target16 (0);
1711 ehdr
->e_shentsize
= grub_host_to_target16 (sizeof (Elf32_Shdr
));
1712 ehdr
->e_shnum
= grub_host_to_target16 (0);
1713 ehdr
->e_shstrndx
= grub_host_to_target16 (0);
1715 ehdr
->e_ehsize
= grub_host_to_target16 (sizeof (*ehdr
));
1717 phdr
->p_type
= grub_host_to_target32 (PT_LOAD
);
1718 phdr
->p_offset
= grub_host_to_target32 (header_size
);
1719 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
1721 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
1723 if (comp
== COMPRESSION_NONE
)
1724 target_addr
= (image_target
->link_addr
- decompress_size
);
1726 target_addr
= ALIGN_UP (image_target
->link_addr
1727 + kernel_size
+ total_module_size
, 32);
1730 target_addr
= image_target
->link_addr
;
1731 ehdr
->e_entry
= grub_host_to_target32 (target_addr
);
1732 phdr
->p_vaddr
= grub_host_to_target32 (target_addr
);
1733 phdr
->p_paddr
= grub_host_to_target32 (target_addr
);
1734 phdr
->p_align
= grub_host_to_target32 (align
> image_target
->link_align
? align
: image_target
->link_align
);
1735 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
1736 ehdr
->e_flags
= grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER
1737 | EF_MIPS_PIC
| EF_MIPS_CPIC
);
1740 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
1742 phdr
->p_filesz
= grub_host_to_target32 (core_size
);
1743 phdr
->p_memsz
= grub_host_to_target32 (core_size
);
1747 grub_uint32_t target_addr_mods
;
1748 phdr
->p_filesz
= grub_host_to_target32 (kernel_size
);
1749 phdr
->p_memsz
= grub_host_to_target32 (kernel_size
+ bss_size
);
1752 phdr
->p_type
= grub_host_to_target32 (PT_GNU_STACK
);
1753 phdr
->p_offset
= grub_host_to_target32 (header_size
+ kernel_size
);
1754 phdr
->p_paddr
= phdr
->p_vaddr
= phdr
->p_filesz
= phdr
->p_memsz
= 0;
1755 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
1756 phdr
->p_align
= grub_host_to_target32 (image_target
->link_align
);
1759 phdr
->p_type
= grub_host_to_target32 (PT_LOAD
);
1760 phdr
->p_offset
= grub_host_to_target32 (header_size
+ kernel_size
);
1761 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
1762 phdr
->p_filesz
= phdr
->p_memsz
1763 = grub_host_to_target32 (core_size
- kernel_size
);
1765 if (image_target
->id
== IMAGE_COREBOOT
)
1766 target_addr_mods
= GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR
;
1768 target_addr_mods
= ALIGN_UP (target_addr
+ kernel_size
+ bss_size
1769 + image_target
->mod_gap
,
1770 image_target
->mod_align
);
1771 phdr
->p_vaddr
= grub_host_to_target32 (target_addr_mods
);
1772 phdr
->p_paddr
= grub_host_to_target32 (target_addr_mods
);
1773 phdr
->p_align
= grub_host_to_target32 (image_target
->link_align
);
1778 int note_size
= sizeof (struct grub_ieee1275_note
);
1779 struct grub_ieee1275_note
*note_ptr
= (struct grub_ieee1275_note
*)
1780 (elf_img
+ program_size
+ header_size
);
1782 grub_util_info ("adding CHRP NOTE segment");
1784 note_ptr
->header
.namesz
= grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME
));
1785 note_ptr
->header
.descsz
= grub_host_to_target32 (note_size
);
1786 note_ptr
->header
.type
= grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE
);
1787 strcpy (note_ptr
->header
.name
, GRUB_IEEE1275_NOTE_NAME
);
1788 note_ptr
->descriptor
.real_mode
= grub_host_to_target32 (0xffffffff);
1789 note_ptr
->descriptor
.real_base
= grub_host_to_target32 (0x00c00000);
1790 note_ptr
->descriptor
.real_size
= grub_host_to_target32 (0xffffffff);
1791 note_ptr
->descriptor
.virt_base
= grub_host_to_target32 (0xffffffff);
1792 note_ptr
->descriptor
.virt_size
= grub_host_to_target32 (0xffffffff);
1793 note_ptr
->descriptor
.load_base
= grub_host_to_target32 (0x00004000);
1796 phdr
->p_type
= grub_host_to_target32 (PT_NOTE
);
1797 phdr
->p_flags
= grub_host_to_target32 (PF_R
);
1798 phdr
->p_align
= grub_host_to_target32 (image_target
->voidp_sizeof
);
1801 phdr
->p_filesz
= grub_host_to_target32 (note_size
);
1803 phdr
->p_offset
= grub_host_to_target32 (header_size
+ program_size
);
1808 core_size
= program_size
+ header_size
+ footer_size
;
1813 grub_util_write_image (core_img
, core_size
, out
, outname
);
1819 next
= path_list
->next
;
1820 free ((void *) path_list
->name
);
1828 static struct argp_option options
[] = {
1829 {"directory", 'd', N_("DIR"), 0,
1830 /* TRANSLATORS: platform here isn't identifier. It can be translated. */
1831 N_("use images and modules under DIR [default=%s/<platform>]"), 0},
1832 {"prefix", 'p', N_("DIR"), 0, N_("set prefix directory [default=%s]"), 0},
1833 {"memdisk", 'm', N_("FILE"), 0,
1834 /* TRANSLATORS: "memdisk" here isn't an identifier, it can be translated.
1835 "embed" is a verb (command description). "*/
1836 N_("embed FILE as a memdisk image\n"
1837 "Implies `-p (memdisk)/boot/grub' but prefix can be overridden by "
1838 "later options"), 0},
1839 /* TRANSLATORS: "embed" is a verb (command description). "*/
1840 {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0},
1841 /* TRANSLATORS: "embed" is a verb (command description). "*/
1842 {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0},
1843 /* TRANSLATORS: NOTE is a name of segment. */
1844 {"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0},
1845 {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
1846 {"format", 'O', N_("FORMAT"), 0, 0, 0},
1847 {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
1848 {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
1849 { 0, 0, 0, 0, 0, 0 }
1853 help_filter (int key
, const char *text
, void *input
__attribute__ ((unused
)))
1858 return xasprintf (text
, GRUB_PKGLIBDIR
);
1860 return xasprintf (text
, DEFAULT_DIRECTORY
);
1868 for (i
= 0; i
< ARRAY_SIZE (image_targets
); i
++)
1869 format_len
+= strlen (image_targets
[i
].names
[0]) + 2;
1870 ptr
= formats
= xmalloc (format_len
);
1871 for (i
= 0; i
< ARRAY_SIZE (image_targets
); i
++)
1873 strcpy (ptr
, image_targets
[i
].names
[0]);
1874 ptr
+= strlen (image_targets
[i
].names
[0]);
1879 ret
= xasprintf ("%s\n%s %s", _("generate an image in FORMAT"),
1880 _("available formats:"), formats
);
1885 return (char *) text
;
1903 struct image_target_desc
*image_target
;
1904 grub_compression_t comp
;
1908 argp_parser (int key
, char *arg
, struct argp_state
*state
)
1910 /* Get the input argument from argp_parse, which we
1911 know is a pointer to our arguments structure. */
1912 struct arguments
*arguments
= state
->input
;
1917 if (arguments
->output
)
1918 free (arguments
->output
);
1920 arguments
->output
= xstrdup (arg
);
1926 for (i
= 0; i
< ARRAY_SIZE (image_targets
); i
++)
1927 for (j
= 0; image_targets
[i
].names
[j
]
1928 && j
< ARRAY_SIZE (image_targets
[i
].names
); j
++)
1929 if (strcmp (arg
, image_targets
[i
].names
[j
]) == 0)
1930 arguments
->image_target
= &image_targets
[i
];
1931 if (!arguments
->image_target
)
1933 printf (_("unknown target format %s\n"), arg
);
1941 free (arguments
->dir
);
1943 arguments
->dir
= xstrdup (arg
);
1947 arguments
->note
= 1;
1951 if (arguments
->memdisk
)
1952 free (arguments
->memdisk
);
1954 arguments
->memdisk
= xstrdup (arg
);
1956 if (arguments
->prefix
)
1957 free (arguments
->prefix
);
1959 arguments
->prefix
= xstrdup ("(memdisk)/boot/grub");
1963 arguments
->pubkeys
= xrealloc (arguments
->pubkeys
,
1964 sizeof (arguments
->pubkeys
[0])
1965 * (arguments
->npubkeys
+ 1));
1966 arguments
->pubkeys
[arguments
->npubkeys
++] = xstrdup (arg
);
1970 if (arguments
->config
)
1971 free (arguments
->config
);
1973 arguments
->config
= xstrdup (arg
);
1977 if (grub_strcmp (arg
, "xz") == 0)
1980 arguments
->comp
= COMPRESSION_XZ
;
1982 grub_util_error ("%s",
1983 _("grub-mkimage is compiled without XZ support"));
1986 else if (grub_strcmp (arg
, "none") == 0)
1987 arguments
->comp
= COMPRESSION_NONE
;
1988 else if (grub_strcmp (arg
, "auto") == 0)
1989 arguments
->comp
= COMPRESSION_AUTO
;
1991 grub_util_error (_("Unknown compression format %s"), arg
);
1995 if (arguments
->prefix
)
1996 free (arguments
->prefix
);
1998 arguments
->prefix
= xstrdup (arg
);
2005 assert (arguments
->nmodules
< arguments
->modules_max
);
2006 arguments
->modules
[arguments
->nmodules
++] = xstrdup(arg
);
2010 return ARGP_ERR_UNKNOWN
;
2015 static struct argp argp
= {
2016 options
, argp_parser
, N_("[OPTION]... [MODULES]"),
2017 N_("Make a bootable image of GRUB."),
2018 NULL
, help_filter
, NULL
2022 main (int argc
, char *argv
[])
2025 struct arguments arguments
;
2027 set_program_name (argv
[0]);
2029 grub_util_init_nls ();
2031 memset (&arguments
, 0, sizeof (struct arguments
));
2032 arguments
.comp
= COMPRESSION_AUTO
;
2033 arguments
.modules_max
= argc
+ 1;
2034 arguments
.modules
= xmalloc ((arguments
.modules_max
+ 1)
2035 * sizeof (arguments
.modules
[0]));
2036 memset (arguments
.modules
, 0, (arguments
.modules_max
+ 1)
2037 * sizeof (arguments
.modules
[0]));
2039 if (argp_parse (&argp
, argc
, argv
, 0, 0, &arguments
) != 0)
2041 fprintf (stderr
, "%s", _("Error in parsing command line arguments\n"));
2045 if (!arguments
.image_target
)
2047 char *program
= xstrdup(program_name
);
2048 printf ("%s\n", _("Target format not specified (use the -O option)."));
2049 argp_help (&argp
, stderr
, ARGP_HELP_STD_USAGE
, program
);
2054 if (arguments
.output
)
2056 fp
= fopen (arguments
.output
, "wb");
2058 grub_util_error (_("cannot open `%s': %s"), arguments
.output
,
2064 arguments
.dir
= xmalloc (sizeof (GRUB_PKGLIBDIR
)
2065 + grub_strlen (arguments
.image_target
->dirname
)
2067 memcpy (arguments
.dir
, GRUB_PKGLIBDIR
,
2068 sizeof (GRUB_PKGLIBDIR
) - 1);
2069 *(arguments
.dir
+ sizeof (GRUB_PKGLIBDIR
) - 1) = '/';
2070 strcpy (arguments
.dir
+ sizeof (GRUB_PKGLIBDIR
),
2071 arguments
.image_target
->dirname
);
2074 generate_image (arguments
.dir
, arguments
.prefix
? : DEFAULT_DIRECTORY
, fp
,
2076 arguments
.modules
, arguments
.memdisk
, arguments
.pubkeys
,
2077 arguments
.npubkeys
, arguments
.config
,
2078 arguments
.image_target
, arguments
.note
, arguments
.comp
);
2081 fsync (fileno (fp
));
2085 free (arguments
.dir
);
2087 if (arguments
.output
)
2088 free (arguments
.output
);