]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - GRUB2/MOD_SRC/grub-2.04/util/mkimage.c
1.1.07 release
[Ventoy.git] / GRUB2 / MOD_SRC / grub-2.04 / util / mkimage.c
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.
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
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>
36
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>
49 #include <grub/util/mkimage.h>
50
51 #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
52
53 #ifdef USE_LIBLZMA
54 #include <lzma.h>
55 #endif
56
57 #pragma GCC diagnostic ignored "-Wcast-align"
58
59 #define TARGET_NO_FIELD 0xffffffff
60
61 /* use 2015-01-01T00:00:00+0000 as a stock timestamp */
62 #define STABLE_EMBEDDING_TIMESTAMP 1420070400
63
64 #define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
65 + GRUB_PE32_SIGNATURE_SIZE \
66 + sizeof (struct grub_pe32_coff_header) \
67 + sizeof (struct grub_pe32_optional_header) \
68 + 4 * sizeof (struct grub_pe32_section_table), \
69 GRUB_PE32_FILE_ALIGNMENT)
70
71 #define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
72 + GRUB_PE32_SIGNATURE_SIZE \
73 + sizeof (struct grub_pe32_coff_header) \
74 + sizeof (struct grub_pe64_optional_header) \
75 + 4 * sizeof (struct grub_pe32_section_table), \
76 GRUB_PE32_FILE_ALIGNMENT)
77
78 static const struct grub_install_image_target_desc image_targets[] =
79 {
80 {
81 .dirname = "i386-coreboot",
82 .names = { "i386-coreboot", NULL },
83 .voidp_sizeof = 4,
84 .bigendian = 0,
85 .id = IMAGE_COREBOOT,
86 .flags = PLATFORM_FLAGS_NONE,
87 .total_module_size = TARGET_NO_FIELD,
88 .decompressor_compressed_size = TARGET_NO_FIELD,
89 .decompressor_uncompressed_size = TARGET_NO_FIELD,
90 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
91 .reloc_table_offset = TARGET_NO_FIELD,
92 .section_align = 1,
93 .vaddr_offset = 0,
94 .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR,
95 .elf_target = EM_386,
96 .link_align = 4,
97 .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP,
98 .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
99 },
100 {
101 .dirname = "i386-multiboot",
102 .names = { "i386-multiboot", NULL},
103 .voidp_sizeof = 4,
104 .bigendian = 0,
105 .id = IMAGE_COREBOOT,
106 .flags = PLATFORM_FLAGS_NONE,
107 .total_module_size = TARGET_NO_FIELD,
108 .decompressor_compressed_size = TARGET_NO_FIELD,
109 .decompressor_uncompressed_size = TARGET_NO_FIELD,
110 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
111 .section_align = 1,
112 .vaddr_offset = 0,
113 .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR,
114 .elf_target = EM_386,
115 .link_align = 4,
116 .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP,
117 .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
118 },
119 {
120 .dirname = "i386-pc",
121 .names = { "i386-pc", NULL },
122 .voidp_sizeof = 4,
123 .bigendian = 0,
124 .id = IMAGE_I386_PC,
125 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
126 .total_module_size = TARGET_NO_FIELD,
127 .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
128 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
129 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
130 .section_align = 1,
131 .vaddr_offset = 0,
132 .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
133 .default_compression = GRUB_COMPRESSION_LZMA
134 },
135 {
136 .dirname = "i386-xen_pvh",
137 .names = { "i386-xen_pvh", NULL },
138 .voidp_sizeof = 4,
139 .bigendian = 0,
140 .id = IMAGE_XEN_PVH,
141 .flags = PLATFORM_FLAGS_NONE,
142 .total_module_size = TARGET_NO_FIELD,
143 .decompressor_compressed_size = TARGET_NO_FIELD,
144 .decompressor_uncompressed_size = TARGET_NO_FIELD,
145 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
146 .elf_target = EM_386,
147 .section_align = 1,
148 .vaddr_offset = 0,
149 .link_addr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR,
150 .mod_align = GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN,
151 .link_align = 4
152 },
153 {
154 .dirname = "i386-pc",
155 .names = { "i386-pc-pxe", NULL },
156 .voidp_sizeof = 4,
157 .bigendian = 0,
158 .id = IMAGE_I386_PC_PXE,
159 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
160 .total_module_size = TARGET_NO_FIELD,
161 .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
162 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
163 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
164 .section_align = 1,
165 .vaddr_offset = 0,
166 .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
167 .default_compression = GRUB_COMPRESSION_LZMA
168 },
169 {
170 .dirname = "i386-pc",
171 .names = { "i386-pc-eltorito", NULL },
172 .voidp_sizeof = 4,
173 .bigendian = 0,
174 .id = IMAGE_I386_PC_ELTORITO,
175 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
176 .total_module_size = TARGET_NO_FIELD,
177 .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
178 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
179 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
180 .section_align = 1,
181 .vaddr_offset = 0,
182 .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
183 .default_compression = GRUB_COMPRESSION_LZMA
184 },
185 {
186 .dirname = "i386-efi",
187 .names = { "i386-efi", NULL },
188 .voidp_sizeof = 4,
189 .bigendian = 0,
190 .id = IMAGE_EFI,
191 .flags = PLATFORM_FLAGS_NONE,
192 .total_module_size = TARGET_NO_FIELD,
193 .decompressor_compressed_size = TARGET_NO_FIELD,
194 .decompressor_uncompressed_size = TARGET_NO_FIELD,
195 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
196 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
197 .vaddr_offset = EFI32_HEADER_SIZE,
198 .pe_target = GRUB_PE32_MACHINE_I386,
199 .elf_target = EM_386,
200 },
201 {
202 .dirname = "i386-ieee1275",
203 .names = { "i386-ieee1275", NULL },
204 .voidp_sizeof = 4,
205 .bigendian = 0,
206 .id = IMAGE_I386_IEEE1275,
207 .flags = PLATFORM_FLAGS_NONE,
208 .total_module_size = TARGET_NO_FIELD,
209 .decompressor_compressed_size = TARGET_NO_FIELD,
210 .decompressor_uncompressed_size = TARGET_NO_FIELD,
211 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
212 .section_align = 1,
213 .vaddr_offset = 0,
214 .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR,
215 .elf_target = EM_386,
216 .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP,
217 .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN,
218 .link_align = 4,
219 },
220 {
221 .dirname = "i386-qemu",
222 .names = { "i386-qemu", NULL },
223 .voidp_sizeof = 4,
224 .bigendian = 0,
225 .id = IMAGE_QEMU,
226 .flags = PLATFORM_FLAGS_NONE,
227 .total_module_size = TARGET_NO_FIELD,
228 .decompressor_compressed_size = TARGET_NO_FIELD,
229 .decompressor_uncompressed_size = TARGET_NO_FIELD,
230 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
231 .section_align = 1,
232 .vaddr_offset = 0,
233 .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR
234 },
235 {
236 .dirname = "x86_64-efi",
237 .names = { "x86_64-efi", NULL },
238 .voidp_sizeof = 8,
239 .bigendian = 0,
240 .id = IMAGE_EFI,
241 .flags = PLATFORM_FLAGS_NONE,
242 .total_module_size = TARGET_NO_FIELD,
243 .decompressor_compressed_size = TARGET_NO_FIELD,
244 .decompressor_uncompressed_size = TARGET_NO_FIELD,
245 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
246 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
247 .vaddr_offset = EFI64_HEADER_SIZE,
248 .pe_target = GRUB_PE32_MACHINE_X86_64,
249 .elf_target = EM_X86_64,
250 },
251 {
252 .dirname = "i386-xen",
253 .names = { "i386-xen", NULL },
254 .voidp_sizeof = 4,
255 .bigendian = 0,
256 .id = IMAGE_XEN,
257 .flags = PLATFORM_FLAGS_NONE,
258 .total_module_size = TARGET_NO_FIELD,
259 .decompressor_compressed_size = TARGET_NO_FIELD,
260 .decompressor_uncompressed_size = TARGET_NO_FIELD,
261 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
262 .section_align = 1,
263 .vaddr_offset = 0,
264 .link_addr = 0,
265 .elf_target = EM_386,
266 .mod_gap = GRUB_KERNEL_I386_XEN_MOD_GAP,
267 .mod_align = GRUB_KERNEL_I386_XEN_MOD_ALIGN,
268 .link_align = 4
269 },
270 {
271 .dirname = "x86_64-xen",
272 .names = { "x86_64-xen", NULL },
273 .voidp_sizeof = 8,
274 .bigendian = 0,
275 .id = IMAGE_XEN,
276 .flags = PLATFORM_FLAGS_NONE,
277 .total_module_size = TARGET_NO_FIELD,
278 .decompressor_compressed_size = TARGET_NO_FIELD,
279 .decompressor_uncompressed_size = TARGET_NO_FIELD,
280 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
281 .section_align = 1,
282 .vaddr_offset = 0,
283 .link_addr = 0,
284 .elf_target = EM_X86_64,
285 .mod_gap = GRUB_KERNEL_X86_64_XEN_MOD_GAP,
286 .mod_align = GRUB_KERNEL_X86_64_XEN_MOD_ALIGN,
287 .link_align = 8
288 },
289 {
290 .dirname = "mipsel-loongson",
291 .names = { "mipsel-yeeloong-flash", NULL },
292 .voidp_sizeof = 4,
293 .bigendian = 0,
294 .id = IMAGE_YEELOONG_FLASH,
295 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
296 .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
297 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
298 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
299 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
300 .section_align = 1,
301 .vaddr_offset = 0,
302 .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
303 .elf_target = EM_MIPS,
304 .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
305 .default_compression = GRUB_COMPRESSION_NONE
306 },
307 {
308 .dirname = "mipsel-loongson",
309 .names = { "mipsel-fuloong2f-flash", NULL },
310 .voidp_sizeof = 4,
311 .bigendian = 0,
312 .id = IMAGE_FULOONG2F_FLASH,
313 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
314 .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
315 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
316 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
317 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
318 .section_align = 1,
319 .vaddr_offset = 0,
320 .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
321 .elf_target = EM_MIPS,
322 .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
323 .default_compression = GRUB_COMPRESSION_NONE
324 },
325 {
326 .dirname = "mipsel-loongson",
327 .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf",
328 "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf",
329 "mipsel-fuloong-elf", NULL },
330 .voidp_sizeof = 4,
331 .bigendian = 0,
332 .id = IMAGE_LOONGSON_ELF,
333 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
334 .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
335 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
336 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
337 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
338 .section_align = 1,
339 .vaddr_offset = 0,
340 .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR,
341 .elf_target = EM_MIPS,
342 .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN,
343 .default_compression = GRUB_COMPRESSION_NONE
344 },
345 {
346 .dirname = "powerpc-ieee1275",
347 .names = { "powerpc-ieee1275", NULL },
348 .voidp_sizeof = 4,
349 .bigendian = 1,
350 .id = IMAGE_PPC,
351 .flags = PLATFORM_FLAGS_NONE,
352 .total_module_size = TARGET_NO_FIELD,
353 .decompressor_compressed_size = TARGET_NO_FIELD,
354 .decompressor_uncompressed_size = TARGET_NO_FIELD,
355 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
356 .section_align = 1,
357 .vaddr_offset = 0,
358 .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR,
359 .elf_target = EM_PPC,
360 .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP,
361 .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN,
362 .link_align = 4
363 },
364 {
365 .dirname = "sparc64-ieee1275",
366 .names = { "sparc64-ieee1275-raw", NULL },
367 .voidp_sizeof = 8,
368 .bigendian = 1,
369 .id = IMAGE_SPARC64_RAW,
370 .flags = PLATFORM_FLAGS_NONE,
371 .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
372 .decompressor_compressed_size = TARGET_NO_FIELD,
373 .decompressor_uncompressed_size = TARGET_NO_FIELD,
374 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
375 .section_align = 1,
376 .vaddr_offset = 0,
377 .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
378 .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
379 },
380 {
381 .dirname = "sparc64-ieee1275",
382 .names = { "sparc64-ieee1275-cdcore", NULL },
383 .voidp_sizeof = 8,
384 .bigendian = 1,
385 .id = IMAGE_SPARC64_CDCORE,
386 .flags = PLATFORM_FLAGS_NONE,
387 .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
388 .decompressor_compressed_size = TARGET_NO_FIELD,
389 .decompressor_uncompressed_size = TARGET_NO_FIELD,
390 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
391 .section_align = 1,
392 .vaddr_offset = 0,
393 .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
394 .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
395 },
396 {
397 .dirname = "sparc64-ieee1275",
398 .names = { "sparc64-ieee1275-aout", NULL },
399 .voidp_sizeof = 8,
400 .bigendian = 1,
401 .id = IMAGE_SPARC64_AOUT,
402 .flags = PLATFORM_FLAGS_NONE,
403 .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
404 .decompressor_compressed_size = TARGET_NO_FIELD,
405 .decompressor_uncompressed_size = TARGET_NO_FIELD,
406 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
407 .section_align = 1,
408 .vaddr_offset = 0,
409 .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR,
410 .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN,
411 },
412 {
413 .dirname = "ia64-efi",
414 .names = {"ia64-efi", NULL},
415 .voidp_sizeof = 8,
416 .bigendian = 0,
417 .id = IMAGE_EFI,
418 .flags = PLATFORM_FLAGS_NONE,
419 .total_module_size = TARGET_NO_FIELD,
420 .decompressor_compressed_size = TARGET_NO_FIELD,
421 .decompressor_uncompressed_size = TARGET_NO_FIELD,
422 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
423 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
424 .vaddr_offset = EFI64_HEADER_SIZE,
425 .pe_target = GRUB_PE32_MACHINE_IA64,
426 .elf_target = EM_IA_64,
427 },
428 {
429 .dirname = "mips-arc",
430 .names = {"mips-arc", NULL},
431 .voidp_sizeof = 4,
432 .bigendian = 1,
433 .id = IMAGE_MIPS_ARC,
434 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
435 .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE,
436 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
437 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
438 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
439 .section_align = 1,
440 .vaddr_offset = 0,
441 .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR,
442 .elf_target = EM_MIPS,
443 .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN,
444 .default_compression = GRUB_COMPRESSION_NONE
445 },
446 {
447 .dirname = "mipsel-arc",
448 .names = {"mipsel-arc", NULL},
449 .voidp_sizeof = 4,
450 .bigendian = 0,
451 .id = IMAGE_MIPS_ARC,
452 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
453 .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE,
454 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
455 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
456 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
457 .section_align = 1,
458 .vaddr_offset = 0,
459 .link_addr = GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR,
460 .elf_target = EM_MIPS,
461 .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN,
462 .default_compression = GRUB_COMPRESSION_NONE
463 },
464 {
465 .dirname = "mipsel-qemu_mips",
466 .names = { "mipsel-qemu_mips-elf", NULL },
467 .voidp_sizeof = 4,
468 .bigendian = 0,
469 .id = IMAGE_LOONGSON_ELF,
470 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
471 .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
472 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
473 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
474 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
475 .section_align = 1,
476 .vaddr_offset = 0,
477 .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
478 .elf_target = EM_MIPS,
479 .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
480 .default_compression = GRUB_COMPRESSION_NONE
481 },
482 {
483 .dirname = "mips-qemu_mips",
484 .names = { "mips-qemu_mips-flash", NULL },
485 .voidp_sizeof = 4,
486 .bigendian = 1,
487 .id = IMAGE_QEMU_MIPS_FLASH,
488 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
489 .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
490 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
491 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
492 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
493 .section_align = 1,
494 .vaddr_offset = 0,
495 .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
496 .elf_target = EM_MIPS,
497 .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
498 .default_compression = GRUB_COMPRESSION_NONE
499 },
500 {
501 .dirname = "mipsel-qemu_mips",
502 .names = { "mipsel-qemu_mips-flash", NULL },
503 .voidp_sizeof = 4,
504 .bigendian = 0,
505 .id = IMAGE_QEMU_MIPS_FLASH,
506 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
507 .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
508 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
509 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
510 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
511 .section_align = 1,
512 .vaddr_offset = 0,
513 .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
514 .elf_target = EM_MIPS,
515 .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
516 .default_compression = GRUB_COMPRESSION_NONE
517 },
518 {
519 .dirname = "mips-qemu_mips",
520 .names = { "mips-qemu_mips-elf", NULL },
521 .voidp_sizeof = 4,
522 .bigendian = 1,
523 .id = IMAGE_LOONGSON_ELF,
524 .flags = PLATFORM_FLAGS_DECOMPRESSORS,
525 .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
526 .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE,
527 .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
528 .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
529 .section_align = 1,
530 .vaddr_offset = 0,
531 .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR,
532 .elf_target = EM_MIPS,
533 .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
534 .default_compression = GRUB_COMPRESSION_NONE
535 },
536 {
537 .dirname = "arm-uboot",
538 .names = { "arm-uboot", NULL },
539 .voidp_sizeof = 4,
540 .bigendian = 0,
541 .id = IMAGE_UBOOT,
542 .flags = PLATFORM_FLAGS_NONE,
543 .total_module_size = GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE,
544 .decompressor_compressed_size = TARGET_NO_FIELD,
545 .decompressor_uncompressed_size = TARGET_NO_FIELD,
546 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
547 .section_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
548 .vaddr_offset = 0,
549 .elf_target = EM_ARM,
550 .mod_gap = GRUB_KERNEL_ARM_UBOOT_MOD_GAP,
551 .mod_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
552 .link_align = 4
553 },
554 /* For coreboot versions that don't support self-relocating images. */
555 {
556 .dirname = "arm-coreboot-vexpress",
557 .names = { "arm-coreboot-vexpress", NULL },
558 .voidp_sizeof = 4,
559 .bigendian = 0,
560 .id = IMAGE_COREBOOT,
561 .flags = PLATFORM_FLAGS_NONE,
562 .total_module_size = GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE,
563 .decompressor_compressed_size = TARGET_NO_FIELD,
564 .decompressor_uncompressed_size = TARGET_NO_FIELD,
565 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
566 .section_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN,
567 .vaddr_offset = 0,
568 .elf_target = EM_ARM,
569 .mod_gap = GRUB_KERNEL_ARM_COREBOOT_MOD_GAP,
570 .mod_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN,
571 .link_align = 4,
572 .link_addr = 0x62000000,
573 },
574 {
575 .dirname = "arm-coreboot-veyron",
576 .names = { "arm-coreboot-veyron", NULL },
577 .voidp_sizeof = 4,
578 .bigendian = 0,
579 .id = IMAGE_COREBOOT,
580 .flags = PLATFORM_FLAGS_NONE,
581 .total_module_size = GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE,
582 .decompressor_compressed_size = TARGET_NO_FIELD,
583 .decompressor_uncompressed_size = TARGET_NO_FIELD,
584 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
585 .section_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN,
586 .vaddr_offset = 0,
587 .elf_target = EM_ARM,
588 .mod_gap = GRUB_KERNEL_ARM_COREBOOT_MOD_GAP,
589 .mod_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN,
590 .link_align = 4,
591 .link_addr = 0x43000000,
592 },
593 {
594 .dirname = "arm-efi",
595 .names = { "arm-efi", NULL },
596 .voidp_sizeof = 4,
597 .bigendian = 0,
598 .id = IMAGE_EFI,
599 .flags = PLATFORM_FLAGS_NONE,
600 .total_module_size = TARGET_NO_FIELD,
601 .decompressor_compressed_size = TARGET_NO_FIELD,
602 .decompressor_uncompressed_size = TARGET_NO_FIELD,
603 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
604 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
605 .vaddr_offset = EFI32_HEADER_SIZE,
606 .pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED,
607 .elf_target = EM_ARM,
608 },
609 {
610 .dirname = "arm64-efi",
611 .names = { "arm64-efi", NULL },
612 .voidp_sizeof = 8,
613 .bigendian = 0,
614 .id = IMAGE_EFI,
615 .flags = PLATFORM_FLAGS_NONE,
616 .total_module_size = TARGET_NO_FIELD,
617 .decompressor_compressed_size = TARGET_NO_FIELD,
618 .decompressor_uncompressed_size = TARGET_NO_FIELD,
619 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
620 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
621 .vaddr_offset = EFI64_HEADER_SIZE,
622 .pe_target = GRUB_PE32_MACHINE_ARM64,
623 .elf_target = EM_AARCH64,
624 },
625 {
626 .dirname = "mips64el-efi",
627 .names = { "mips64el-efi", NULL },
628 .voidp_sizeof = 8,
629 .bigendian = 0,
630 .id = IMAGE_EFI,
631 .flags = PLATFORM_FLAGS_NONE,
632 .total_module_size = TARGET_NO_FIELD,
633 .decompressor_compressed_size = TARGET_NO_FIELD,
634 .decompressor_uncompressed_size = TARGET_NO_FIELD,
635 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
636 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
637 .vaddr_offset = EFI64_HEADER_SIZE,
638 .pe_target = GRUB_PE32_MACHINE_MIPS,
639 .elf_target = EM_MIPS,
640 },
641 {
642 .dirname = "riscv32-efi",
643 .names = { "riscv32-efi", NULL },
644 .voidp_sizeof = 4,
645 .bigendian = 0,
646 .id = IMAGE_EFI,
647 .flags = PLATFORM_FLAGS_NONE,
648 .total_module_size = TARGET_NO_FIELD,
649 .decompressor_compressed_size = TARGET_NO_FIELD,
650 .decompressor_uncompressed_size = TARGET_NO_FIELD,
651 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
652 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
653 .vaddr_offset = EFI32_HEADER_SIZE,
654 .pe_target = GRUB_PE32_MACHINE_RISCV32,
655 .elf_target = EM_RISCV,
656 },
657 {
658 .dirname = "riscv64-efi",
659 .names = { "riscv64-efi", NULL },
660 .voidp_sizeof = 8,
661 .bigendian = 0,
662 .id = IMAGE_EFI,
663 .flags = PLATFORM_FLAGS_NONE,
664 .total_module_size = TARGET_NO_FIELD,
665 .decompressor_compressed_size = TARGET_NO_FIELD,
666 .decompressor_uncompressed_size = TARGET_NO_FIELD,
667 .decompressor_uncompressed_addr = TARGET_NO_FIELD,
668 .section_align = GRUB_PE32_SECTION_ALIGNMENT,
669 .vaddr_offset = EFI64_HEADER_SIZE,
670 .pe_target = GRUB_PE32_MACHINE_RISCV64,
671 .elf_target = EM_RISCV,
672 },
673 };
674
675 #include <grub/lib/LzmaEnc.h>
676
677 static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return xmalloc(size); }
678 static void SzFree(void *p __attribute__ ((unused)), void *address) { free(address); }
679 static ISzAlloc g_Alloc = { SzAlloc, SzFree };
680
681 static void
682 compress_kernel_lzma (char *kernel_img, size_t kernel_size,
683 char **core_img, size_t *core_size)
684 {
685 CLzmaEncProps props;
686 unsigned char out_props[5];
687 size_t out_props_size = 5;
688
689 LzmaEncProps_Init(&props);
690 props.dictSize = 1 << 16;
691 props.lc = 3;
692 props.lp = 0;
693 props.pb = 2;
694 props.numThreads = 1;
695
696 *core_img = xmalloc (kernel_size);
697
698 *core_size = kernel_size;
699 if (LzmaEncode ((unsigned char *) *core_img, core_size,
700 (unsigned char *) kernel_img,
701 kernel_size,
702 &props, out_props, &out_props_size,
703 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK)
704 grub_util_error ("%s", _("cannot compress the kernel image"));
705 }
706
707 #ifdef USE_LIBLZMA
708 static void
709 compress_kernel_xz (char *kernel_img, size_t kernel_size,
710 char **core_img, size_t *core_size)
711 {
712 lzma_stream strm = LZMA_STREAM_INIT;
713 lzma_ret xzret;
714 lzma_options_lzma lzopts = {
715 .dict_size = 1 << 16,
716 .preset_dict = NULL,
717 .preset_dict_size = 0,
718 .lc = 3,
719 .lp = 0,
720 .pb = 2,
721 .mode = LZMA_MODE_NORMAL,
722 .nice_len = 64,
723 .mf = LZMA_MF_BT4,
724 .depth = 0,
725 };
726 lzma_filter fltrs[] = {
727 { .id = LZMA_FILTER_LZMA2, .options = &lzopts},
728 { .id = LZMA_VLI_UNKNOWN, .options = NULL}
729 };
730
731 xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE);
732 if (xzret != LZMA_OK)
733 grub_util_error ("%s", _("cannot compress the kernel image"));
734
735 *core_img = xmalloc (kernel_size);
736
737 *core_size = kernel_size;
738 strm.next_in = (unsigned char *) kernel_img;
739 strm.avail_in = kernel_size;
740 strm.next_out = (unsigned char *) *core_img;
741 strm.avail_out = *core_size;
742
743 while (1)
744 {
745 xzret = lzma_code (&strm, LZMA_FINISH);
746 if (xzret == LZMA_OK)
747 continue;
748 if (xzret == LZMA_STREAM_END)
749 break;
750 grub_util_error ("%s", _("cannot compress the kernel image"));
751 }
752
753 *core_size -= strm.avail_out;
754 }
755 #endif
756
757 static void
758 compress_kernel (const struct grub_install_image_target_desc *image_target, char *kernel_img,
759 size_t kernel_size, char **core_img, size_t *core_size,
760 grub_compression_t comp)
761 {
762 if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
763 && (comp == GRUB_COMPRESSION_LZMA))
764 {
765 compress_kernel_lzma (kernel_img, kernel_size, core_img,
766 core_size);
767 return;
768 }
769
770 #ifdef USE_LIBLZMA
771 if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
772 && (comp == GRUB_COMPRESSION_XZ))
773 {
774 compress_kernel_xz (kernel_img, kernel_size, core_img,
775 core_size);
776 return;
777 }
778 #endif
779
780 if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
781 && (comp != GRUB_COMPRESSION_NONE))
782 grub_util_error (_("unknown compression %d"), comp);
783
784 *core_img = xmalloc (kernel_size);
785 memcpy (*core_img, kernel_img, kernel_size);
786 *core_size = kernel_size;
787 }
788
789 const struct grub_install_image_target_desc *
790 grub_install_get_image_target (const char *arg)
791 {
792 unsigned i, j;
793 for (i = 0; i < ARRAY_SIZE (image_targets); i++)
794 for (j = 0; j < ARRAY_SIZE (image_targets[i].names) &&
795 image_targets[i].names[j]; j++)
796 if (strcmp (arg, image_targets[i].names[j]) == 0)
797 return &image_targets[i];
798 return NULL;
799 }
800
801 const char *
802 grub_util_get_target_dirname (const struct grub_install_image_target_desc *t)
803 {
804 return t->dirname;
805 }
806
807 const char *
808 grub_util_get_target_name (const struct grub_install_image_target_desc *t)
809 {
810 return t->names[0];
811 }
812
813 char *
814 grub_install_get_image_targets_string (void)
815 {
816 int format_len = 0;
817 char *formats;
818 char *ptr;
819 unsigned i;
820 for (i = 0; i < ARRAY_SIZE (image_targets); i++)
821 format_len += strlen (image_targets[i].names[0]) + 2;
822 ptr = formats = xmalloc (format_len);
823 for (i = 0; i < ARRAY_SIZE (image_targets); i++)
824 {
825 strcpy (ptr, image_targets[i].names[0]);
826 ptr += strlen (image_targets[i].names[0]);
827 *ptr++ = ',';
828 *ptr++ = ' ';
829 }
830 ptr[-2] = 0;
831
832 return formats;
833 }
834
835 void
836 grub_install_generate_image (const char *dir, const char *prefix,
837 FILE *out, const char *outname, char *mods[],
838 char *memdisk_path, char **pubkey_paths,
839 size_t npubkeys, char *config_path,
840 const struct grub_install_image_target_desc *image_target,
841 int note, grub_compression_t comp, const char *dtb_path)
842 {
843 char *kernel_img, *core_img;
844 size_t total_module_size, core_size;
845 size_t memdisk_size = 0, config_size = 0;
846 size_t prefix_size = 0, dtb_size = 0;
847 char *kernel_path;
848 size_t offset;
849 struct grub_util_path_list *path_list, *p;
850 size_t decompress_size = 0;
851 struct grub_mkimage_layout layout;
852
853 if (comp == GRUB_COMPRESSION_AUTO)
854 comp = image_target->default_compression;
855
856 if (image_target->id == IMAGE_I386_PC
857 || image_target->id == IMAGE_I386_PC_PXE
858 || image_target->id == IMAGE_I386_PC_ELTORITO)
859 comp = GRUB_COMPRESSION_LZMA;
860
861 path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
862
863 kernel_path = grub_util_get_path (dir, "kernel.img");
864
865 if (image_target->voidp_sizeof == 8)
866 total_module_size = sizeof (struct grub_module_info64);
867 else
868 total_module_size = sizeof (struct grub_module_info32);
869
870 {
871 size_t i;
872 for (i = 0; i < npubkeys; i++)
873 {
874 size_t curs;
875 curs = ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i]));
876 grub_util_info ("the size of public key %u is 0x%"
877 GRUB_HOST_PRIxLONG_LONG,
878 (unsigned) i, (unsigned long long) curs);
879 total_module_size += curs + sizeof (struct grub_module_header);
880 }
881 }
882
883 if (memdisk_path)
884 {
885 memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
886 grub_util_info ("the size of memory disk is 0x%" GRUB_HOST_PRIxLONG_LONG,
887 (unsigned long long) memdisk_size);
888 total_module_size += memdisk_size + sizeof (struct grub_module_header);
889 }
890
891 if (dtb_path)
892 {
893 dtb_size = ALIGN_ADDR(grub_util_get_image_size (dtb_path));
894 total_module_size += dtb_size + sizeof (struct grub_module_header);
895 }
896
897 if (config_path)
898 {
899 config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
900 grub_util_info ("the size of config file is 0x%" GRUB_HOST_PRIxLONG_LONG,
901 (unsigned long long) config_size);
902 total_module_size += config_size + sizeof (struct grub_module_header);
903 }
904
905 if (prefix)
906 {
907 prefix_size = ALIGN_ADDR (strlen (prefix) + 1);
908 total_module_size += prefix_size + sizeof (struct grub_module_header);
909 }
910
911 for (p = path_list; p; p = p->next)
912 total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name))
913 + sizeof (struct grub_module_header));
914
915 grub_util_info ("the total module size is 0x%" GRUB_HOST_PRIxLONG_LONG,
916 (unsigned long long) total_module_size);
917
918 if (image_target->voidp_sizeof == 4)
919 kernel_img = grub_mkimage_load_image32 (kernel_path, total_module_size,
920 &layout, image_target);
921 else
922 kernel_img = grub_mkimage_load_image64 (kernel_path, total_module_size,
923 &layout, image_target);
924 if ((image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) &&
925 layout.align < 4096)
926 layout.align = 4096;
927
928 if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
929 && (image_target->total_module_size != TARGET_NO_FIELD))
930 *((grub_uint32_t *) (kernel_img + image_target->total_module_size))
931 = grub_host_to_target32 (total_module_size);
932
933 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
934 {
935 memmove (kernel_img + total_module_size, kernel_img, layout.kernel_size);
936 memset (kernel_img, 0, total_module_size);
937 }
938
939 if (image_target->voidp_sizeof == 8)
940 {
941 /* Fill in the grub_module_info structure. */
942 struct grub_module_info64 *modinfo;
943 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
944 modinfo = (struct grub_module_info64 *) kernel_img;
945 else
946 modinfo = (struct grub_module_info64 *) (kernel_img + layout.kernel_size);
947 modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
948 modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64));
949 modinfo->size = grub_host_to_target_addr (total_module_size);
950 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
951 offset = sizeof (struct grub_module_info64);
952 else
953 offset = layout.kernel_size + sizeof (struct grub_module_info64);
954 }
955 else
956 {
957 /* Fill in the grub_module_info structure. */
958 struct grub_module_info32 *modinfo;
959 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
960 modinfo = (struct grub_module_info32 *) kernel_img;
961 else
962 modinfo = (struct grub_module_info32 *) (kernel_img + layout.kernel_size);
963 modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
964 modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32));
965 modinfo->size = grub_host_to_target_addr (total_module_size);
966 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
967 offset = sizeof (struct grub_module_info32);
968 else
969 offset = layout.kernel_size + sizeof (struct grub_module_info32);
970 }
971
972 for (p = path_list; p; p = p->next)
973 {
974 struct grub_module_header *header;
975 size_t mod_size;
976
977 mod_size = ALIGN_ADDR (grub_util_get_image_size (p->name));
978
979 header = (struct grub_module_header *) (kernel_img + offset);
980 header->type = grub_host_to_target32 (OBJ_TYPE_ELF);
981 header->size = grub_host_to_target32 (mod_size + sizeof (*header));
982 offset += sizeof (*header);
983
984 grub_util_load_image (p->name, kernel_img + offset);
985 offset += mod_size;
986 }
987
988 {
989 size_t i;
990 for (i = 0; i < npubkeys; i++)
991 {
992 size_t curs;
993 struct grub_module_header *header;
994
995 curs = grub_util_get_image_size (pubkey_paths[i]);
996
997 header = (struct grub_module_header *) (kernel_img + offset);
998 header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY);
999 header->size = grub_host_to_target32 (curs + sizeof (*header));
1000 offset += sizeof (*header);
1001
1002 grub_util_load_image (pubkey_paths[i], kernel_img + offset);
1003 offset += ALIGN_ADDR (curs);
1004 }
1005 }
1006
1007 if (memdisk_path)
1008 {
1009 struct grub_module_header *header;
1010
1011 header = (struct grub_module_header *) (kernel_img + offset);
1012 header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK);
1013 header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
1014 offset += sizeof (*header);
1015
1016 grub_util_load_image (memdisk_path, kernel_img + offset);
1017 offset += memdisk_size;
1018 }
1019
1020 if (dtb_path)
1021 {
1022 struct grub_module_header *header;
1023
1024 header = (struct grub_module_header *) (kernel_img + offset);
1025 header->type = grub_host_to_target32 (OBJ_TYPE_DTB);
1026 header->size = grub_host_to_target32 (dtb_size + sizeof (*header));
1027 offset += sizeof (*header);
1028
1029 grub_util_load_image (dtb_path, kernel_img + offset);
1030 offset += dtb_size;
1031 }
1032
1033 if (config_path)
1034 {
1035 struct grub_module_header *header;
1036
1037 header = (struct grub_module_header *) (kernel_img + offset);
1038 header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG);
1039 header->size = grub_host_to_target32 (config_size + sizeof (*header));
1040 offset += sizeof (*header);
1041
1042 grub_util_load_image (config_path, kernel_img + offset);
1043 offset += config_size;
1044 }
1045
1046 if (prefix)
1047 {
1048 struct grub_module_header *header;
1049
1050 header = (struct grub_module_header *) (kernel_img + offset);
1051 header->type = grub_host_to_target32 (OBJ_TYPE_PREFIX);
1052 header->size = grub_host_to_target32 (prefix_size + sizeof (*header));
1053 offset += sizeof (*header);
1054
1055 grub_strcpy (kernel_img + offset, prefix);
1056 offset += prefix_size;
1057 }
1058
1059 grub_util_info ("kernel_img=%p, kernel_size=0x%" GRUB_HOST_PRIxLONG_LONG,
1060 kernel_img,
1061 (unsigned long long) layout.kernel_size);
1062 compress_kernel (image_target, kernel_img, layout.kernel_size + total_module_size,
1063 &core_img, &core_size, comp);
1064 free (kernel_img);
1065
1066 grub_util_info ("the core size is 0x%" GRUB_HOST_PRIxLONG_LONG,
1067 (unsigned long long) core_size);
1068
1069 if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
1070 && image_target->total_module_size != TARGET_NO_FIELD)
1071 *((grub_uint32_t *) (core_img + image_target->total_module_size))
1072 = grub_host_to_target32 (total_module_size);
1073
1074 if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
1075 {
1076 char *full_img;
1077 size_t full_size;
1078 char *decompress_path, *decompress_img;
1079 const char *name;
1080
1081 switch (comp)
1082 {
1083 case GRUB_COMPRESSION_XZ:
1084 name = "xz_decompress.img";
1085 break;
1086 case GRUB_COMPRESSION_LZMA:
1087 name = "lzma_decompress.img";
1088 break;
1089 case GRUB_COMPRESSION_NONE:
1090 name = "none_decompress.img";
1091 break;
1092 default:
1093 grub_util_error (_("unknown compression %d"), comp);
1094 }
1095
1096 decompress_path = grub_util_get_path (dir, name);
1097 decompress_size = grub_util_get_image_size (decompress_path);
1098 decompress_img = grub_util_read_image (decompress_path);
1099
1100 if ((image_target->id == IMAGE_I386_PC
1101 || image_target->id == IMAGE_I386_PC_PXE
1102 || image_target->id == IMAGE_I386_PC_ELTORITO)
1103 && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200)
1104 grub_util_error ("%s", _("Decompressor is too big"));
1105
1106 if (image_target->decompressor_compressed_size != TARGET_NO_FIELD)
1107 *((grub_uint32_t *) (decompress_img
1108 + image_target->decompressor_compressed_size))
1109 = grub_host_to_target32 (core_size);
1110
1111 if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD)
1112 *((grub_uint32_t *) (decompress_img
1113 + image_target->decompressor_uncompressed_size))
1114 = grub_host_to_target32 (layout.kernel_size + total_module_size);
1115
1116 if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD)
1117 {
1118 if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
1119 *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr))
1120 = grub_host_to_target_addr (image_target->link_addr - total_module_size);
1121 else
1122 *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr))
1123 = grub_host_to_target_addr (image_target->link_addr);
1124 }
1125 full_size = core_size + decompress_size;
1126
1127 full_img = xmalloc (full_size);
1128
1129 memcpy (full_img, decompress_img, decompress_size);
1130
1131 memcpy (full_img + decompress_size, core_img, core_size);
1132
1133 free (core_img);
1134 core_img = full_img;
1135 core_size = full_size;
1136 free (decompress_img);
1137 free (decompress_path);
1138 }
1139
1140 switch (image_target->id)
1141 {
1142 case IMAGE_I386_PC:
1143 case IMAGE_I386_PC_PXE:
1144 case IMAGE_I386_PC_ELTORITO:
1145 if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000
1146 || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS))
1147 || (layout.kernel_size + layout.bss_size
1148 + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000))
1149 grub_util_error (_("core image is too big (0x%x > 0x%x)"),
1150 GRUB_KERNEL_I386_PC_LINK_ADDR + (unsigned) core_size,
1151 0x78000);
1152 /* fallthrough */
1153 case IMAGE_COREBOOT:
1154 case IMAGE_QEMU:
1155 if (image_target->elf_target != EM_ARM && layout.kernel_size + layout.bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)
1156 grub_util_error (_("kernel image is too big (0x%x > 0x%x)"),
1157 (unsigned) layout.kernel_size + (unsigned) layout.bss_size
1158 + GRUB_KERNEL_I386_PC_LINK_ADDR,
1159 0x68000);
1160 break;
1161 case IMAGE_LOONGSON_ELF:
1162 case IMAGE_YEELOONG_FLASH:
1163 case IMAGE_FULOONG2F_FLASH:
1164 case IMAGE_EFI:
1165 case IMAGE_MIPS_ARC:
1166 case IMAGE_QEMU_MIPS_FLASH:
1167 case IMAGE_XEN:
1168 case IMAGE_XEN_PVH:
1169 break;
1170 case IMAGE_SPARC64_AOUT:
1171 case IMAGE_SPARC64_RAW:
1172 case IMAGE_SPARC64_CDCORE:
1173 case IMAGE_I386_IEEE1275:
1174 case IMAGE_PPC:
1175 case IMAGE_UBOOT:
1176 break;
1177 }
1178
1179 switch (image_target->id)
1180 {
1181 case IMAGE_I386_PC:
1182 case IMAGE_I386_PC_PXE:
1183 case IMAGE_I386_PC_ELTORITO:
1184 {
1185 unsigned num;
1186 char *boot_path, *boot_img;
1187 size_t boot_size;
1188
1189 num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
1190 if (image_target->id == IMAGE_I386_PC_PXE)
1191 {
1192 char *pxeboot_path, *pxeboot_img;
1193 size_t pxeboot_size;
1194 grub_uint32_t *ptr;
1195
1196 pxeboot_path = grub_util_get_path (dir, "pxeboot.img");
1197 pxeboot_size = grub_util_get_image_size (pxeboot_path);
1198 pxeboot_img = grub_util_read_image (pxeboot_path);
1199
1200 grub_util_write_image (pxeboot_img, pxeboot_size, out,
1201 outname);
1202 free (pxeboot_img);
1203 free (pxeboot_path);
1204
1205 /* Remove Multiboot header to avoid confusing ipxe. */
1206 for (ptr = (grub_uint32_t *) core_img;
1207 ptr < (grub_uint32_t *) (core_img + MULTIBOOT_SEARCH); ptr++)
1208 if (*ptr == grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC)
1209 && grub_target_to_host32 (ptr[0])
1210 + grub_target_to_host32 (ptr[1])
1211 + grub_target_to_host32 (ptr[2]) == 0)
1212 {
1213 *ptr = 0;
1214 break;
1215 }
1216 }
1217
1218 if (image_target->id == IMAGE_I386_PC_ELTORITO)
1219 {
1220 char *eltorito_path, *eltorito_img;
1221 size_t eltorito_size;
1222
1223 eltorito_path = grub_util_get_path (dir, "cdboot.img");
1224 eltorito_size = grub_util_get_image_size (eltorito_path);
1225 eltorito_img = grub_util_read_image (eltorito_path);
1226
1227 grub_util_write_image (eltorito_img, eltorito_size, out,
1228 outname);
1229 free (eltorito_img);
1230 free (eltorito_path);
1231 }
1232
1233 boot_path = grub_util_get_path (dir, "diskboot.img");
1234 boot_size = grub_util_get_image_size (boot_path);
1235 if (boot_size != GRUB_DISK_SECTOR_SIZE)
1236 grub_util_error (_("diskboot.img size must be %u bytes"),
1237 GRUB_DISK_SECTOR_SIZE);
1238
1239 boot_img = grub_util_read_image (boot_path);
1240
1241 {
1242 struct grub_pc_bios_boot_blocklist *block;
1243 block = (struct grub_pc_bios_boot_blocklist *) (boot_img
1244 + GRUB_DISK_SECTOR_SIZE
1245 - sizeof (*block));
1246 block->len = grub_host_to_target16 (num);
1247
1248 /* This is filled elsewhere. Verify it just in case. */
1249 assert (block->segment
1250 == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG
1251 + (GRUB_DISK_SECTOR_SIZE >> 4)));
1252 }
1253
1254 grub_util_write_image (boot_img, boot_size, out, outname);
1255 free (boot_img);
1256 free (boot_path);
1257 }
1258 break;
1259 case IMAGE_EFI:
1260 {
1261 void *pe_img;
1262 grub_uint8_t *header;
1263 void *sections;
1264 size_t pe_size;
1265 struct grub_pe32_coff_header *c;
1266 struct grub_pe32_section_table *text_section, *data_section;
1267 struct grub_pe32_section_table *mods_section, *reloc_section;
1268 static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
1269 int header_size;
1270 int reloc_addr;
1271
1272 if (image_target->voidp_sizeof == 4)
1273 header_size = EFI32_HEADER_SIZE;
1274 else
1275 header_size = EFI64_HEADER_SIZE;
1276
1277 reloc_addr = ALIGN_UP (header_size + core_size,
1278 GRUB_PE32_FILE_ALIGNMENT);
1279
1280 pe_size = ALIGN_UP (reloc_addr + layout.reloc_size,
1281 GRUB_PE32_FILE_ALIGNMENT);
1282 pe_img = xmalloc (reloc_addr + layout.reloc_size);
1283 memset (pe_img, 0, header_size);
1284 memcpy ((char *) pe_img + header_size, core_img, core_size);
1285 memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - (header_size + core_size));
1286 memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size);
1287 header = pe_img;
1288
1289 /* The magic. */
1290 memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE);
1291 memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0",
1292 GRUB_PE32_SIGNATURE_SIZE);
1293
1294 /* The COFF file header. */
1295 c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE
1296 + GRUB_PE32_SIGNATURE_SIZE);
1297 c->machine = grub_host_to_target16 (image_target->pe_target);
1298
1299 c->num_sections = grub_host_to_target16 (4);
1300 c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP);
1301 c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE
1302 | GRUB_PE32_LINE_NUMS_STRIPPED
1303 | ((image_target->voidp_sizeof == 4)
1304 ? GRUB_PE32_32BIT_MACHINE
1305 : 0)
1306 | GRUB_PE32_LOCAL_SYMS_STRIPPED
1307 | GRUB_PE32_DEBUG_STRIPPED);
1308
1309 /* The PE Optional header. */
1310 if (image_target->voidp_sizeof == 4)
1311 {
1312 struct grub_pe32_optional_header *o;
1313
1314 c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header));
1315
1316 o = (struct grub_pe32_optional_header *)
1317 (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
1318 + sizeof (struct grub_pe32_coff_header));
1319 o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
1320 o->code_size = grub_host_to_target32 (layout.exec_size);
1321 o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
1322 - header_size);
1323 o->bss_size = grub_cpu_to_le32 (layout.bss_size);
1324 o->entry_addr = grub_cpu_to_le32 (layout.start_address);
1325 o->code_base = grub_cpu_to_le32 (header_size);
1326
1327 o->data_base = grub_host_to_target32 (header_size + layout.exec_size);
1328
1329 o->image_base = 0;
1330 o->section_alignment = grub_host_to_target32 (image_target->section_align);
1331 o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
1332 o->image_size = grub_host_to_target32 (pe_size);
1333 o->header_size = grub_host_to_target32 (header_size);
1334 o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
1335
1336 /* Do these really matter? */
1337 o->stack_reserve_size = grub_host_to_target32 (0x10000);
1338 o->stack_commit_size = grub_host_to_target32 (0x10000);
1339 o->heap_reserve_size = grub_host_to_target32 (0x10000);
1340 o->heap_commit_size = grub_host_to_target32 (0x10000);
1341
1342 o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
1343
1344 o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
1345 o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
1346 sections = o + 1;
1347 }
1348 else
1349 {
1350 struct grub_pe64_optional_header *o;
1351
1352 c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header));
1353
1354 o = (struct grub_pe64_optional_header *)
1355 (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
1356 + sizeof (struct grub_pe32_coff_header));
1357 o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
1358 o->code_size = grub_host_to_target32 (layout.exec_size);
1359 o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
1360 - header_size);
1361 o->bss_size = grub_cpu_to_le32 (layout.bss_size);
1362 o->entry_addr = grub_cpu_to_le32 (layout.start_address);
1363 o->code_base = grub_cpu_to_le32 (header_size);
1364 o->image_base = 0;
1365 o->section_alignment = grub_host_to_target32 (image_target->section_align);
1366 o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
1367 o->image_size = grub_host_to_target32 (pe_size);
1368 o->header_size = grub_host_to_target32 (header_size);
1369 o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
1370
1371 /* Do these really matter? */
1372 o->stack_reserve_size = grub_host_to_target64 (0x10000);
1373 o->stack_commit_size = grub_host_to_target64 (0x10000);
1374 o->heap_reserve_size = grub_host_to_target64 (0x10000);
1375 o->heap_commit_size = grub_host_to_target64 (0x10000);
1376
1377 o->num_data_directories
1378 = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
1379
1380 o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
1381 o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
1382 sections = o + 1;
1383 }
1384 /* The sections. */
1385 text_section = sections;
1386 strcpy (text_section->name, ".text");
1387 text_section->virtual_size = grub_cpu_to_le32 (layout.exec_size);
1388 text_section->virtual_address = grub_cpu_to_le32 (header_size);
1389 text_section->raw_data_size = grub_cpu_to_le32 (layout.exec_size);
1390 text_section->raw_data_offset = grub_cpu_to_le32 (header_size);
1391 text_section->characteristics = grub_cpu_to_le32_compile_time (
1392 GRUB_PE32_SCN_CNT_CODE
1393 | GRUB_PE32_SCN_MEM_EXECUTE
1394 | GRUB_PE32_SCN_MEM_READ);
1395
1396 data_section = text_section + 1;
1397 strcpy (data_section->name, ".data");
1398 data_section->virtual_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
1399 data_section->virtual_address = grub_cpu_to_le32 (header_size + layout.exec_size);
1400 data_section->raw_data_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
1401 data_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.exec_size);
1402 data_section->characteristics
1403 = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1404 | GRUB_PE32_SCN_MEM_READ
1405 | GRUB_PE32_SCN_MEM_WRITE);
1406
1407 #if 0
1408 bss_section = data_section + 1;
1409 strcpy (bss_section->name, ".bss");
1410 bss_section->virtual_size = grub_cpu_to_le32 (layout.bss_size);
1411 bss_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size);
1412 bss_section->raw_data_size = 0;
1413 bss_section->raw_data_offset = 0;
1414 bss_section->characteristics
1415 = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ
1416 | GRUB_PE32_SCN_MEM_WRITE
1417 | GRUB_PE32_SCN_ALIGN_64BYTES
1418 | GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1419 | 0x80);
1420 #endif
1421
1422 mods_section = data_section + 1;
1423 strcpy (mods_section->name, "mods");
1424 mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
1425 mods_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size + layout.bss_size);
1426 mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
1427 mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.kernel_size);
1428 mods_section->characteristics
1429 = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1430 | GRUB_PE32_SCN_MEM_READ
1431 | GRUB_PE32_SCN_MEM_WRITE);
1432
1433 reloc_section = mods_section + 1;
1434 strcpy (reloc_section->name, ".reloc");
1435 reloc_section->virtual_size = grub_cpu_to_le32 (layout.reloc_size);
1436 reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + layout.bss_size);
1437 reloc_section->raw_data_size = grub_cpu_to_le32 (layout.reloc_size);
1438 reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr);
1439 reloc_section->characteristics
1440 = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
1441 | GRUB_PE32_SCN_MEM_DISCARDABLE
1442 | GRUB_PE32_SCN_MEM_READ);
1443 free (core_img);
1444 core_img = pe_img;
1445 core_size = pe_size;
1446 }
1447 break;
1448 case IMAGE_QEMU:
1449 {
1450 char *rom_img;
1451 size_t rom_size;
1452 char *boot_path, *boot_img;
1453 size_t boot_size;
1454
1455 boot_path = grub_util_get_path (dir, "boot.img");
1456 boot_size = grub_util_get_image_size (boot_path);
1457 boot_img = grub_util_read_image (boot_path);
1458
1459 /* Rom sizes must be 64k-aligned. */
1460 rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024);
1461
1462 rom_img = xmalloc (rom_size);
1463 memset (rom_img, 0, rom_size);
1464
1465 *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR))
1466 = grub_host_to_target32 ((grub_uint32_t) -rom_size);
1467
1468 memcpy (rom_img, core_img, core_size);
1469
1470 *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR))
1471 = grub_host_to_target32 ((grub_uint32_t) -rom_size);
1472
1473 memcpy (rom_img + rom_size - boot_size, boot_img, boot_size);
1474
1475 free (core_img);
1476 core_img = rom_img;
1477 core_size = rom_size;
1478
1479 free (boot_img);
1480 free (boot_path);
1481 }
1482 break;
1483 case IMAGE_SPARC64_AOUT:
1484 {
1485 void *aout_img;
1486 size_t aout_size;
1487 struct grub_aout32_header *aout_head;
1488
1489 aout_size = core_size + sizeof (*aout_head);
1490 aout_img = xmalloc (aout_size);
1491 aout_head = aout_img;
1492 grub_memset (aout_head, 0, sizeof (*aout_head));
1493 aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16)
1494 | AOUT32_OMAGIC);
1495 aout_head->a_text = grub_host_to_target32 (core_size);
1496 aout_head->a_entry
1497 = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS);
1498 memcpy ((char *) aout_img + sizeof (*aout_head), core_img, core_size);
1499
1500 free (core_img);
1501 core_img = aout_img;
1502 core_size = aout_size;
1503 }
1504 break;
1505 case IMAGE_SPARC64_RAW:
1506 {
1507 unsigned int num;
1508 char *boot_path, *boot_img;
1509 size_t boot_size;
1510
1511 num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
1512 num <<= GRUB_DISK_SECTOR_BITS;
1513
1514 boot_path = grub_util_get_path (dir, "diskboot.img");
1515 boot_size = grub_util_get_image_size (boot_path);
1516 if (boot_size != GRUB_DISK_SECTOR_SIZE)
1517 grub_util_error (_("diskboot.img size must be %u bytes"),
1518 GRUB_DISK_SECTOR_SIZE);
1519
1520 boot_img = grub_util_read_image (boot_path);
1521
1522 *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE
1523 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8))
1524 = grub_host_to_target32 (num);
1525
1526 grub_util_write_image (boot_img, boot_size, out, outname);
1527 free (boot_img);
1528 free (boot_path);
1529 }
1530 break;
1531 case IMAGE_SPARC64_CDCORE:
1532 break;
1533 case IMAGE_YEELOONG_FLASH:
1534 case IMAGE_FULOONG2F_FLASH:
1535 {
1536 char *rom_img;
1537 size_t rom_size;
1538 char *boot_path, *boot_img;
1539 size_t boot_size;
1540 /* fwstart.img is the only part which can't be tested by using *-elf
1541 target. Check it against the checksum. */
1542 const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] =
1543 {
1544 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a,
1545 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5,
1546 0x75, 0x64, 0x6b, 0xbb, 0x24, 0xcd, 0xb4, 0xbc,
1547 0xf2, 0x3e, 0x23, 0xf9, 0xc2, 0x6a, 0x8c, 0xde,
1548 0x3b, 0x94, 0x9c, 0xcc, 0xa5, 0xa7, 0x58, 0xb1,
1549 0xbe, 0x8b, 0x3d, 0x73, 0x98, 0x18, 0x7e, 0x68,
1550 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7,
1551 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25
1552 };
1553 const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] =
1554 {
1555 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62,
1556 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c,
1557 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d,
1558 0x02, 0x84, 0xa0, 0x85, 0xf2, 0xd1, 0xb9, 0x53,
1559 0xa2, 0xbc, 0xf2, 0xe1, 0x39, 0x1e, 0x51, 0xb5,
1560 0xaf, 0xec, 0x9e, 0xf2, 0xf1, 0xf3, 0x0a, 0x2f,
1561 0xe6, 0xf1, 0x08, 0x89, 0xbe, 0xbc, 0x73, 0xab,
1562 0x46, 0x50, 0xd6, 0x21, 0xce, 0x8e, 0x24, 0xa7
1563 };
1564 const grub_uint8_t *fwstart_good_hash;
1565 grub_uint8_t fwstart_hash[512 / 8];
1566
1567 if (image_target->id == IMAGE_FULOONG2F_FLASH)
1568 {
1569 fwstart_good_hash = fuloong2f_fwstart_good_hash;
1570 boot_path = grub_util_get_path (dir, "fwstart_fuloong2f.img");
1571 }
1572 else
1573 {
1574 fwstart_good_hash = yeeloong_fwstart_good_hash;
1575 boot_path = grub_util_get_path (dir, "fwstart.img");
1576 }
1577
1578 boot_size = grub_util_get_image_size (boot_path);
1579 boot_img = grub_util_read_image (boot_path);
1580
1581 grub_crypto_hash (GRUB_MD_SHA512, fwstart_hash, boot_img, boot_size);
1582
1583 if (grub_memcmp (fwstart_hash, fwstart_good_hash,
1584 GRUB_MD_SHA512->mdlen) != 0)
1585 /* TRANSLATORS: fwstart.img may still be good, just it wasn't checked. */
1586 grub_util_warn ("%s",
1587 _("fwstart.img doesn't match the known good version. "
1588 "proceed at your own risk"));
1589
1590 if (core_size + boot_size > 512 * 1024)
1591 grub_util_error ("%s", _("firmware image is too big"));
1592 rom_size = 512 * 1024;
1593
1594 rom_img = xmalloc (rom_size);
1595 memset (rom_img, 0, rom_size);
1596
1597 memcpy (rom_img, boot_img, boot_size);
1598
1599 memcpy (rom_img + boot_size, core_img, core_size);
1600
1601 memset (rom_img + boot_size + core_size, 0,
1602 rom_size - (boot_size + core_size));
1603
1604 free (core_img);
1605 core_img = rom_img;
1606 core_size = rom_size;
1607 free (boot_img);
1608 free (boot_path);
1609 }
1610 break;
1611 case IMAGE_QEMU_MIPS_FLASH:
1612 {
1613 char *rom_img;
1614 size_t rom_size;
1615
1616 if (core_size > 512 * 1024)
1617 grub_util_error ("%s", _("firmware image is too big"));
1618 rom_size = 512 * 1024;
1619
1620 rom_img = xmalloc (rom_size);
1621 memset (rom_img, 0, rom_size);
1622
1623 memcpy (rom_img, core_img, core_size);
1624
1625 memset (rom_img + core_size, 0,
1626 rom_size - core_size);
1627
1628 free (core_img);
1629 core_img = rom_img;
1630 core_size = rom_size;
1631 }
1632 break;
1633
1634 case IMAGE_UBOOT:
1635 {
1636 struct grub_uboot_image_header *hdr;
1637
1638 hdr = xmalloc (core_size + sizeof (struct grub_uboot_image_header));
1639 memcpy (hdr + 1, core_img, core_size);
1640
1641 memset (hdr, 0, sizeof (*hdr));
1642 hdr->ih_magic = grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC);
1643 hdr->ih_time = grub_cpu_to_be32 (STABLE_EMBEDDING_TIMESTAMP);
1644 hdr->ih_size = grub_cpu_to_be32 (core_size);
1645 hdr->ih_load = 0;
1646 hdr->ih_ep = 0;
1647 hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL_NOLOAD;
1648 hdr->ih_os = GRUB_UBOOT_IH_OS_LINUX;
1649 hdr->ih_arch = GRUB_UBOOT_IH_ARCH_ARM;
1650 hdr->ih_comp = GRUB_UBOOT_IH_COMP_NONE;
1651
1652 grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_dcrc, hdr + 1, core_size);
1653 grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_hcrc, hdr, sizeof (*hdr));
1654
1655 free (core_img);
1656 core_img = (char *) hdr;
1657 core_size += sizeof (struct grub_uboot_image_header);
1658 }
1659 break;
1660
1661 case IMAGE_MIPS_ARC:
1662 {
1663 char *ecoff_img;
1664 struct ecoff_header {
1665 grub_uint16_t magic;
1666 grub_uint16_t nsec;
1667 grub_uint32_t time;
1668 grub_uint32_t syms;
1669 grub_uint32_t nsyms;
1670 grub_uint16_t opt;
1671 grub_uint16_t flags;
1672 grub_uint16_t magic2;
1673 grub_uint16_t version;
1674 grub_uint32_t textsize;
1675 grub_uint32_t datasize;
1676 grub_uint32_t bsssize;
1677 grub_uint32_t entry;
1678 grub_uint32_t text_start;
1679 grub_uint32_t data_start;
1680 grub_uint32_t bss_start;
1681 grub_uint32_t gprmask;
1682 grub_uint32_t cprmask[4];
1683 grub_uint32_t gp_value;
1684 };
1685 struct ecoff_section
1686 {
1687 char name[8];
1688 grub_uint32_t paddr;
1689 grub_uint32_t vaddr;
1690 grub_uint32_t size;
1691 grub_uint32_t file_offset;
1692 grub_uint32_t reloc;
1693 grub_uint32_t gp;
1694 grub_uint16_t nreloc;
1695 grub_uint16_t ngp;
1696 grub_uint32_t flags;
1697 };
1698 struct ecoff_header *head;
1699 struct ecoff_section *section;
1700 grub_uint32_t target_addr;
1701 size_t program_size;
1702
1703 program_size = ALIGN_ADDR (core_size);
1704 if (comp == GRUB_COMPRESSION_NONE)
1705 target_addr = (image_target->link_addr - decompress_size);
1706 else
1707 target_addr = ALIGN_UP (image_target->link_addr
1708 + layout.kernel_size + total_module_size, 32);
1709
1710 ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section));
1711 grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section));
1712 head = (void *) ecoff_img;
1713 section = (void *) (head + 1);
1714 head->magic = image_target->bigendian ? grub_host_to_target16 (0x160)
1715 : grub_host_to_target16 (0x166);
1716 head->nsec = grub_host_to_target16 (1);
1717 head->time = grub_host_to_target32 (0);
1718 head->opt = grub_host_to_target16 (0x38);
1719 head->flags = image_target->bigendian
1720 ? grub_host_to_target16 (0x207)
1721 : grub_host_to_target16 (0x103);
1722 head->magic2 = grub_host_to_target16 (0x107);
1723 head->textsize = grub_host_to_target32 (program_size);
1724 head->entry = grub_host_to_target32 (target_addr);
1725 head->text_start = grub_host_to_target32 (target_addr);
1726 head->data_start = grub_host_to_target32 (target_addr + program_size);
1727 grub_memcpy (section->name, ".text", sizeof (".text") - 1);
1728 section->vaddr = grub_host_to_target32 (target_addr);
1729 section->size = grub_host_to_target32 (program_size);
1730 section->file_offset = grub_host_to_target32 (sizeof (*head) + sizeof (*section));
1731 if (!image_target->bigendian)
1732 {
1733 section->paddr = grub_host_to_target32 (0xaa60);
1734 section->flags = grub_host_to_target32 (0x20);
1735 }
1736 memcpy (section + 1, core_img, core_size);
1737 free (core_img);
1738 core_img = ecoff_img;
1739 core_size = program_size + sizeof (*head) + sizeof (*section);
1740 }
1741 break;
1742 case IMAGE_LOONGSON_ELF:
1743 case IMAGE_PPC:
1744 case IMAGE_XEN:
1745 case IMAGE_XEN_PVH:
1746 case IMAGE_COREBOOT:
1747 case IMAGE_I386_IEEE1275:
1748 {
1749 grub_uint64_t target_addr;
1750 if (image_target->id == IMAGE_LOONGSON_ELF)
1751 {
1752 if (comp == GRUB_COMPRESSION_NONE)
1753 target_addr = (image_target->link_addr - decompress_size);
1754 else
1755 target_addr = ALIGN_UP (image_target->link_addr
1756 + layout.kernel_size + total_module_size, 32);
1757 }
1758 else
1759 target_addr = image_target->link_addr;
1760 if (image_target->voidp_sizeof == 4)
1761 grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size,
1762 target_addr, &layout);
1763 else
1764 grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
1765 target_addr, &layout);
1766 }
1767 break;
1768 }
1769
1770 grub_util_write_image (core_img, core_size, out, outname);
1771 free (core_img);
1772 free (kernel_path);
1773 free (layout.reloc_section);
1774
1775 grub_util_free_path_list (path_list);
1776 }