From 614be3f11949a6a2e7033e2f2dc4caa3e5a772a3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 00:45:21 +0200 Subject: [PATCH] #if-less grub-mkimage --- include/grub/i386/pc/boot.h | 17 +- include/grub/i386/pc/kernel.h | 24 +- include/grub/i386/pc/memory.h | 6 +- include/grub/i386/qemu/boot.h | 3 - include/grub/i386/qemu/kernel.h | 3 - include/grub/sparc64/ieee1275/boot.h | 4 - include/grub/sparc64/ieee1275/kernel.h | 13 - util/grub-mkimage.c | 1378 +++++++++++++----------- util/grub-mkrescue.in | 2 +- 9 files changed, 765 insertions(+), 685 deletions(-) diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index e88c62b71..09d01caee 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,6 +19,9 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 +#define MACHINE I386_PC +#include + /* The signature for bootloader. */ #define GRUB_BOOT_MACHINE_SIGNATURE 0xaa55 @@ -57,9 +60,6 @@ floppy. */ #define GRUB_BOOT_MACHINE_BIOS_HD_FLAG 0x80 -/* The segment where the kernel is loaded. */ -#define GRUB_BOOT_MACHINE_KERNEL_SEG 0x800 - /* The address where the kernel is loaded. */ #define GRUB_BOOT_MACHINE_KERNEL_ADDR (GRUB_BOOT_MACHINE_KERNEL_SEG << 4) @@ -68,16 +68,7 @@ #define GRUB_BOOT_MACHINE_PXE_DL 0x7f -#ifndef ASM_FILE - /* This is the blocklist used in the diskboot image. */ -struct grub_boot_blocklist -{ - grub_uint64_t start; - grub_uint16_t len; - grub_uint16_t segment; -} __attribute__ ((packed)); - -#endif /* ! ASM_FILE */ +#define grub_boot_blocklist grub_pc_bios_boot_blocklist #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index e830afae2..77d5c6e5a 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,29 +19,9 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 +#define MACHINE I386_PC -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE 0x10 - -/* The offset of GRUB_INSTALL_DOS_PART. */ -#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART 0x14 - -/* The offset of GRUB_INSTALL_BSD_PART. */ -#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART 0x18 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x1c - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x5c - -/* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0) +#include /* Enable LZMA compression */ #define ENABLE_LZMA 1 diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 841b06164..0b4191734 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -29,6 +29,9 @@ #include +#define MACHINE I386_PC +#include + /* The scratch buffer used in real mode code. */ #define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 #define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) @@ -40,9 +43,6 @@ /* The size of the protect mode stack. */ #define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE 0x8000 -/* The upper memory area (starting at 640 kiB). */ -#define GRUB_MEMORY_MACHINE_UPPER 0xa0000 - /* The protected mode stack. */ #define GRUB_MEMORY_MACHINE_PROT_STACK \ (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \ diff --git a/include/grub/i386/qemu/boot.h b/include/grub/i386/qemu/boot.h index 6fbb57750..5f53eabfb 100644 --- a/include/grub/i386/qemu/boot.h +++ b/include/grub/i386/qemu/boot.h @@ -22,7 +22,4 @@ /* The size of boot.img. */ #define GRUB_BOOT_MACHINE_SIZE (0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR) -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR 0x4 - #endif diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index bc0b93d4f..3d22c9d9f 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,9 +19,6 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR 0x8 - /* The offset of GRUB_KERNEL_IMAGE_SIZE. */ #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 9671c6900..bd0a7bf3c 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -50,10 +50,6 @@ #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) -#define GRUB_BOOT_MACHINE_LIST_SIZE 12 - -#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS 0x4400 - #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index a16fb88e7..2948a8d2f 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -42,21 +42,8 @@ #define GRUB_KERNEL_MACHINE_RAW_SIZE 0 #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, aout" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_AOUT -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_AOUT GRUB_PLATFORM_IMAGE_AOUT - #include #include diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 71376eaee..af2988a3f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -19,9 +19,6 @@ #include #include -#include -#include -#include #include #include #include @@ -30,6 +27,7 @@ #include #include #include +#include #include #include @@ -44,7 +42,144 @@ #include "progname.h" -#define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +#define TARGET_NO_FIELD 0xffffffff +struct image_target_desc +{ + const char *name; + grub_size_t voidp_sizeof; + int bigendian; + enum { + IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, + IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, + IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC + } id; + enum {FORMAT_RAW, FORMAT_AOUT, FORMAT_ELF, FORMAT_PE} format; + enum + { + PLATFORM_FLAGS_NONE = 0, + PLATFORM_FLAGS_LZMA = 1 + } flags; + unsigned prefix; + unsigned data_end; + unsigned raw_size; + unsigned total_module_size; + unsigned kernel_image_size; + unsigned compressed_size; + unsigned link_align; + grub_uint16_t elf_target; + unsigned section_align; + signed vaddr_offset; + unsigned install_dos_part, install_bsd_part; +}; + +struct image_target_desc image_targets[] = + { + {"i386-coreboot", 4, 0, IMAGE_COREBOOT, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + {"i386-pc", 4, 0, IMAGE_I386_PC, FORMAT_RAW, PLATFORM_FLAGS_LZMA, + GRUB_KERNEL_I386_PC_PREFIX, GRUB_KERNEL_I386_PC_DATA_END, + GRUB_KERNEL_I386_PC_RAW_SIZE, GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, GRUB_KERNEL_I386_PC_INSTALL_BSD_PART + }, + {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"i386-qemu", 4, 0, IMAGE_QEMU, FORMAT_RAW, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"powerpc-ieee1275", 4, 1, IMAGE_PPC, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"sparc64-ieee1275-raw", 8, 1, IMAGE_SPARC64_RAW, + FORMAT_RAW, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"sparc64-ieee1275-aout", 8, 1, IMAGE_SPARC64_AOUT, + FORMAT_AOUT, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + }; + +#define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) +#define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) +#define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) +#define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) + +static inline grub_uint32_t +grub_target_to_host32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu32 (in); + else + return grub_le_to_cpu32 (in); +} + +static inline grub_uint64_t +grub_target_to_host64_real (struct image_target_desc *image_target, grub_uint64_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu64 (in); + else + return grub_le_to_cpu64 (in); +} + +static inline grub_uint32_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_target_to_host64_real (image_target, in); + else + return grub_target_to_host32_real (image_target, in); +} + +static inline grub_uint32_t +grub_host_to_target32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be32 (in); + else + return grub_cpu_to_le32 (in); +} + +static inline grub_uint16_t +grub_target_to_host16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu16 (in); + else + return grub_le_to_cpu16 (in); +} + +static inline grub_uint16_t +grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be16 (in); + else + return grub_cpu_to_le16 (in); +} #define GRUB_IEEE1275_NOTE_NAME "PowerPC" #define GRUB_IEEE1275_NOTE_TYPE 0x1275 @@ -76,21 +211,8 @@ struct grub_ieee1275_note struct grub_ieee1275_note_desc descriptor; }; -#ifdef GRUB_MACHINE_EFI -#define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT -#define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) -#else -#define SECTION_ALIGN 1 -#define VADDR_OFFSET 0 -#endif +#define grub_target_to_host(val) grub_target_to_host_real(image_target, (val)) -#if GRUB_TARGET_WORDSIZE == 32 -# define grub_target_to_host(val) grub_target_to_host32(val) -#elif GRUB_TARGET_WORDSIZE == 64 -# define grub_target_to_host(val) grub_target_to_host64(val) -#endif - -#ifdef ENABLE_LZMA #include static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); } @@ -98,8 +220,8 @@ static void SzFree(void *p, void *address) { p = p; free(address); } static ISzAlloc g_Alloc = { SzAlloc, SzFree }; static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) +compress_kernel_lzma (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size, size_t raw_size) { CLzmaEncProps props; unsigned char out_props[5]; @@ -112,45 +234,47 @@ compress_kernel (char *kernel_img, size_t kernel_size, props.pb = 2; props.numThreads = 1; - if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE) + if (kernel_size < raw_size) grub_util_error (_("the core image is too small")); *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE); + memcpy (*core_img, kernel_img, raw_size); - *core_size = kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE; - if (LzmaEncode((unsigned char *) *core_img + GRUB_KERNEL_MACHINE_RAW_SIZE, - core_size, - (unsigned char *) kernel_img + GRUB_KERNEL_MACHINE_RAW_SIZE, - kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE, - &props, out_props, &out_props_size, - 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) + *core_size = kernel_size - raw_size; + if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, + (unsigned char *) kernel_img + raw_size, + kernel_size - raw_size, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) grub_util_error (_("cannot compress the kernel image")); - *core_size += GRUB_KERNEL_MACHINE_RAW_SIZE; + *core_size += raw_size; } -#else /* No lzma compression */ - static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) +compress_kernel (struct image_target_desc *image_target, char *kernel_img, + size_t kernel_size, char **core_img, size_t *core_size) { + if (image_target->flags & PLATFORM_FLAGS_LZMA) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size, image_target->raw_size); + return; + } + *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, kernel_size); *core_size = kernel_size; } -#endif /* No lzma compression */ - -#ifdef GRUB_MACHINE_EFI /* Relocate symbols; note that this function overwrites the symbol table. Return the address of a start symbol. */ static Elf_Addr relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections) + Elf_Half section_entsize, Elf_Half num_sections, + struct image_target_desc *image_target) { Elf_Word symtab_size, sym_size, num_syms; Elf_Off symtab_offset; @@ -209,7 +333,8 @@ relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, /* Return the address of a symbol at the index I in the section S. */ static Elf_Addr -get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) +get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + struct image_target_desc *image_target) { Elf_Sym *sym; @@ -221,7 +346,8 @@ get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) /* Return the address of a modified value. */ static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) +get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + struct image_target_desc *image_target) { return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); } @@ -234,7 +360,7 @@ static void relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr *section_addresses, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) + const char *strtab, struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -283,79 +409,84 @@ relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr addend; offset = grub_target_to_host (r->r_offset); - target = get_target_address (e, target_section, offset); + target = get_target_address (e, target_section, offset, image_target); info = grub_target_to_host (r->r_info); sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info)); + ELF_R_SYM (info), image_target); addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? r->r_addend : 0; - switch (ELF_R_TYPE (info)) - { -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - case R_386_NONE: - break; + if (image_target->voidp_sizeof == 4) + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; - case R_386_32: - /* This is absolute. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; - case R_386_PC32: - /* This is relative. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr - - target_section_addr - offset - - VADDR_OFFSET); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + else + switch (ELF_R_TYPE (info)) + { -#else + case R_X86_64_NONE: + break; - case R_X86_64_NONE: - break; + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; - case R_X86_64_64: - *target = grub_host_to_target64 (grub_target_to_host64 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", - *target, offset); - break; + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } - case R_X86_64_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr - - target_section_addr - offset - - VADDR_OFFSET); - grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } - case R_X86_64_32: - case R_X86_64_32S: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - -#endif - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } } } } @@ -371,7 +502,8 @@ struct fixup_block_list after having written to the file OUT. */ Elf_Addr add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address) + Elf_Addr addr, int flush, Elf_Addr current_address, + struct image_target_desc *image_target) { struct grub_pe32_fixup_block *b; @@ -393,7 +525,7 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, size_t index; next_address = current_address + b->block_size; - padding_size = ((ALIGN_UP (next_address, SECTION_ALIGN) + padding_size = ((ALIGN_UP (next_address, image_target->section_align) - next_address) >> 1); index = ((b->block_size - sizeof (*b)) >> 1); @@ -466,7 +598,7 @@ static Elf_Addr make_reloc_section (Elf_Ehdr *e, void **out, Elf_Addr *section_addresses, Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) + const char *strtab, struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -509,39 +641,44 @@ make_reloc_section (Elf_Ehdr *e, void **out, info = grub_le_to_cpu32 (r->r_info); /* Necessary to relocate only absolute addresses. */ -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - if (ELF_R_TYPE (info) == R_386_32) + if (image_target->voidp_sizeof == 4) { - Elf_Addr addr; + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%x", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address); + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + image_target); + } } -#else - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) + else { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address); + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } } -#endif } } - current_address = add_fixup_entry (&lst, 0, 0, 1, current_address); + current_address = add_fixup_entry (&lst, 0, 0, 1, current_address, image_target); { grub_uint8_t *ptr; @@ -562,17 +699,14 @@ make_reloc_section (Elf_Ehdr *e, void **out, return current_address; } -#endif - /* Determine if this section is a text section. Return false if this section is not allocated. */ static int -is_text_section (Elf_Shdr *s) +is_text_section (Elf_Shdr *s, struct image_target_desc *image_target) { -#ifndef GRUB_MACHINE_EFI - if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; -#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -581,12 +715,11 @@ is_text_section (Elf_Shdr *s) BSS is also a data section, since the converter initializes BSS when producing PE32 to avoid a bug in EFI implementations. */ static int -is_data_section (Elf_Shdr *s) +is_data_section (Elf_Shdr *s, struct image_target_desc *image_target) { -#ifndef GRUB_MACHINE_EFI - if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; -#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -597,7 +730,8 @@ is_data_section (Elf_Shdr *s) static Elf_Addr * locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, const char *strtab, - grub_size_t *exec_size, grub_size_t *kernel_sz) + grub_size_t *exec_size, grub_size_t *kernel_sz, + struct image_target_desc *image_target) { int i; Elf_Addr current_address; @@ -613,14 +747,14 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) + if (is_text_section (s, image_target)) { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) - image_target->vaddr_offset; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -628,22 +762,24 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; *exec_size = current_address; /* .data */ for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) + if (is_data_section (s, image_target)) { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -651,15 +787,15 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; *kernel_sz = current_address; return section_addresses; } /* Return if the ELF header is valid. */ static int -check_elf_header (Elf_Ehdr *e, size_t size) +check_elf_header (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) { if (size < sizeof (*e) || e->e_ident[EI_MAG0] != ELFMAG0 @@ -677,7 +813,8 @@ static char * load_image (const char *kernel_path, grub_size_t *exec_size, grub_size_t *kernel_sz, grub_size_t *bss_size, grub_size_t total_module_size, Elf_Addr *start, - void **reloc_section, grub_size_t *reloc_size) + void **reloc_section, grub_size_t *reloc_size, + struct image_target_desc *image_target) { char *kernel_img, *out_img; const char *strtab; @@ -700,7 +837,7 @@ load_image (const char *kernel_path, grub_size_t *exec_size, grub_util_load_image (kernel_path, kernel_img); e = (Elf_Ehdr *) kernel_img; - if (! check_elf_header (e, kernel_size)) + if (! check_elf_header (e, kernel_size, image_target)) grub_util_error ("invalid ELF header"); section_offset = grub_target_to_host32 (e->e_shoff); @@ -719,85 +856,86 @@ load_image (const char *kernel_path, grub_size_t *exec_size, section_addresses = locate_sections (sections, section_entsize, num_sections, strtab, - exec_size, kernel_sz); + exec_size, kernel_sz, image_target); -#ifdef GRUB_MACHINE_EFI - { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + if (image_target->id == IMAGE_EFI) + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + VADDR_OFFSET; + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; #if 0 - { - Elf_Addr current_address = *kernel_sz; + { + Elf_Addr current_address = *kernel_sz; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); + symtab_section = s; + break; } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = relocate_symbols (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, image_target); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + relocate_addresses (e, sections, section_addresses, section_entsize, + num_sections, strtab, image_target); + + *reloc_size = make_reloc_section (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, image_target); + + } + else + { + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; } -#else - *bss_size = 0; -#endif - - symtab_section = NULL; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) - { - symtab_section = s; - break; - } - - if (! symtab_section) - grub_util_error ("no symbol table"); - - *start = relocate_symbols (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections); - if (*start == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - relocate_addresses (e, sections, section_addresses, section_entsize, - num_sections, strtab); - - *reloc_size = make_reloc_section (e, reloc_section, - section_vaddresses, sections, - section_entsize, num_sections, - strtab); - - } -#else - *bss_size = 0; - *reloc_size = 0; - *reloc_section = NULL; -#endif out_img = xmalloc (*kernel_sz + total_module_size); for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s) || is_text_section (s)) + if (is_data_section (s, image_target) || is_text_section (s, image_target)) { if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) memset (out_img + section_addresses[i], 0, @@ -815,13 +953,7 @@ load_image (const char *kernel_path, grub_size_t *exec_size, static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format, -#else - int dummy __attribute__ ((unused)), -#endif - int note -) + struct image_target_desc *image_target, int note) { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size, exec_size; @@ -869,11 +1001,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size); + &reloc_size, image_target); - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); - strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); + strcpy (kernel_img + image_target->prefix, prefix); /* Fill in the grub_module_info structure. */ modinfo = (struct grub_module_info *) (kernel_img + kernel_size); @@ -946,402 +1078,401 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); - compress_kernel (kernel_img, kernel_size + total_module_size, + compress_kernel (image_target, kernel_img, kernel_size + total_module_size, &core_img, &core_size); grub_util_info ("the core size is 0x%x", core_size); -#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) - = grub_host_to_target32 (total_module_size); -#endif -#ifdef GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) - = grub_host_to_target32 (kernel_size); -#endif -#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) - = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); -#endif + if (image_target->total_module_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + if (image_target->kernel_image_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->kernel_image_size)) + = grub_host_to_target32 (kernel_size); + if (image_target->compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->compressed_size)) + = grub_host_to_target32 (core_size - image_target->raw_size); -#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) /* If we included a drive in our prefix, let GRUB know it doesn't have to prepend the drive told by BIOS. */ - if (prefix[0] == '(') + if (image_target->install_dos_part != TARGET_NO_FIELD + && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') { - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) + *((grub_int32_t *) (core_img + image_target->install_dos_part)) = grub_host_to_target32 (-2); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) + *((grub_int32_t *) (core_img + image_target->install_bsd_part)) = grub_host_to_target32 (-2); } -#endif - -#ifdef GRUB_MACHINE_PCBIOS - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) - grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, - GRUB_MEMORY_MACHINE_UPPER); -#endif - -#if defined(GRUB_MACHINE_PCBIOS) - { - unsigned num; - char *boot_path, *boot_img; - size_t boot_size; - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - if (num > 0xffff) - grub_util_error (_("the core image is too big")); - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("diskboot.img size must be %u bytes"), - GRUB_DISK_SECTOR_SIZE); - - boot_img = grub_util_read_image (boot_path); + switch (image_target->id) { - struct grub_boot_blocklist *block; - block = (struct grub_boot_blocklist *) (boot_img - + GRUB_DISK_SECTOR_SIZE - - sizeof (*block)); - block->len = grub_host_to_target16 (num); + case IMAGE_I386_PC: + { + unsigned num; + char *boot_path, *boot_img; + size_t boot_size; - /* This is filled elsewhere. Verify it just in case. */ - assert (block->segment - == grub_host_to_target16 (GRUB_BOOT_MACHINE_KERNEL_SEG - + (GRUB_DISK_SECTOR_SIZE >> 4))); - } + if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) + grub_util_error (_("core image is too big (%p > %p)"), + GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, + GRUB_MEMORY_I386_PC_UPPER); - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_EFI) - { - void *pe_img; - size_t pe_size; - struct grub_pe32_header *header; - struct grub_pe32_coff_header *c; - struct grub_pe32_optional_header *o; - struct grub_pe32_section_table *text_section, *data_section; - struct grub_pe32_section_table *mods_section, *reloc_section; - static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), - SECTION_ALIGN); - int reloc_addr = ALIGN_UP (header_size + core_size, SECTION_ALIGN); + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (num > 0xffff) + grub_util_error (_("the core image is too big")); - pe_size = ALIGN_UP (reloc_addr + reloc_size, SECTION_ALIGN); - pe_img = xmalloc (reloc_addr + reloc_size); - memset (pe_img, 0, header_size); - memcpy (pe_img + header_size, core_img, core_size); - memcpy (pe_img + reloc_addr, rel_section, reloc_size); - header = pe_img; + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); - /* The magic. */ - memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); - memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + boot_img = grub_util_read_image (boot_path); - /* The COFF file header. */ - c = &header->coff_header; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); -#else - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); -#endif + { + struct grub_pc_bios_boot_blocklist *block; + block = (struct grub_pc_bios_boot_blocklist *) (boot_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + block->len = grub_host_to_target16 (num); - c->num_sections = grub_host_to_target16 (4); - c->time = grub_host_to_target32 (time (0)); - c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); - c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE - | GRUB_PE32_LINE_NUMS_STRIPPED -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - | GRUB_PE32_32BIT_MACHINE -#endif - | GRUB_PE32_LOCAL_SYMS_STRIPPED - | GRUB_PE32_DEBUG_STRIPPED); + /* This is filled elsewhere. Verify it just in case. */ + assert (block->segment + == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4))); + } - /* The PE Optional header. */ - o = &header->optional_header; - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); - o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - o->data_base = grub_host_to_target32 (header_size + exec_size); -#endif - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (SECTION_ALIGN); - o->file_alignment = grub_host_to_target32 (SECTION_ALIGN); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_EFI: + { + void *pe_img; + size_t pe_size; + struct grub_pe32_header *header; + struct grub_pe32_coff_header *c; + struct grub_pe32_optional_header *o; + struct grub_pe32_section_table *text_section, *data_section; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + image_target->section_align); + int reloc_addr = ALIGN_UP (header_size + core_size, image_target->section_align); - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target32 (0x10000); - o->stack_commit_size = grub_host_to_target32 (0x10000); - o->heap_reserve_size = grub_host_to_target32 (0x10000); - o->heap_commit_size = grub_host_to_target32 (0x10000); + pe_size = ALIGN_UP (reloc_addr + reloc_size, image_target->section_align); + pe_img = xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy (pe_img + header_size, core_img, core_size); + memcpy (pe_img + reloc_addr, rel_section, reloc_size); + header = pe_img; + + /* The magic. */ + memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); + memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + + /* The COFF file header. */ + c = &header->coff_header; + if (image_target->voidp_sizeof == 4) + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); + else + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (time (0)); + c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED + | ((image_target->voidp_sizeof == 4) + ? GRUB_PE32_32BIT_MACHINE + : 0) + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + o = &header->optional_header; + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + if (image_target->voidp_sizeof == 4) + o->data_base = grub_host_to_target32 (header_size + exec_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); - o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); - /* The sections. */ - text_section = (struct grub_pe32_section_table *) (header + 1); - strcpy (text_section->name, ".text"); - text_section->virtual_size = grub_cpu_to_le32 (exec_size); - text_section->virtual_address = grub_cpu_to_le32 (header_size); - text_section->raw_data_size = grub_cpu_to_le32 (exec_size); - text_section->raw_data_offset = grub_cpu_to_le32 (header_size); - text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_ALIGN_64BYTES); + /* The sections. */ + text_section = (struct grub_pe32_section_table *) (header + 1); + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_ALIGN_64BYTES); - data_section = text_section + 1; - strcpy (data_section->name, ".data"); - data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); - data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); - data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); - data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); - data_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); #if 0 - bss_section = data_section + 1; - strcpy (bss_section->name, ".bss"); - bss_section->virtual_size = grub_cpu_to_le32 (bss_size); - bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); - bss_section->raw_data_size = 0; - bss_section->raw_data_offset = 0; - bss_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES - | GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | 0x80); + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); #endif - mods_section = data_section + 1; - strcpy (mods_section->name, "mods"); - mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); - mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); - mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); - mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); - mods_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); - reloc_section = mods_section + 1; - strcpy (reloc_section->name, ".reloc"); - reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); - reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); - reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); - reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); - reloc_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE - | GRUB_PE32_SCN_MEM_READ); - free (core_img); - core_img = pe_img; - core_size = pe_size; - } -#elif defined(GRUB_MACHINE_QEMU) - { - char *rom_img; - size_t rom_size; - char *boot_path, *boot_img; - size_t boot_size; + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } + break; + case IMAGE_QEMU: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; - boot_path = grub_util_get_path (dir, "boot.img"); - boot_size = grub_util_get_image_size (boot_path); - boot_img = grub_util_read_image (boot_path); + boot_path = grub_util_get_path (dir, "boot.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); - /* Rom sizes must be 64k-aligned. */ - rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); + /* Rom sizes must be 64k-aligned. */ + rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); - rom_img = xmalloc (rom_size); - memset (rom_img, 0, rom_size); + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); - memcpy (rom_img, core_img, core_size); + memcpy (rom_img, core_img, core_size); - *((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); + *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); - memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); + memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); - free (core_img); - core_img = rom_img; - core_size = rom_size; + free (core_img); + core_img = rom_img; + core_size = rom_size; - free (boot_img); - free (boot_path); - } -#elif defined (GRUB_MACHINE_SPARC64) - if (format == GRUB_PLATFORM_IMAGE_AOUT) - { - void *aout_img; - size_t aout_size; - struct grub_aout32_header *aout_head; + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_AOUT: + { + void *aout_img; + size_t aout_size; + struct grub_aout32_header *aout_head; - aout_size = core_size + sizeof (*aout_head); - aout_img = xmalloc (aout_size); - aout_head = aout_img; - aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) - | AOUT32_OMAGIC); - aout_head->a_text = grub_host_to_target32 (core_size); - aout_head->a_entry - = grub_host_to_target32 (GRUB_BOOT_MACHINE_IMAGE_ADDRESS); - memcpy (aout_img + sizeof (*aout_head), core_img, core_size); + aout_size = core_size + sizeof (*aout_head); + aout_img = xmalloc (aout_size); + aout_head = aout_img; + aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text = grub_host_to_target32 (core_size); + aout_head->a_entry + = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS); + memcpy (aout_img + sizeof (*aout_head), core_img, core_size); - free (core_img); - core_img = aout_img; - core_size = aout_size; + free (core_img); + core_img = aout_img; + core_size = aout_size; + } + break; + case IMAGE_SPARC64_RAW: + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("diskboot.img is not one sector size"); + + boot_img = grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_YEELOONG_ELF: + case IMAGE_PPC: + case IMAGE_COREBOOT: + case IMAGE_I386_IEEE1275: + { + char *elf_img; + size_t program_size; + Elf32_Ehdr *ehdr; + Elf32_Phdr *phdr; + grub_uint32_t target_addr; + int header_size, footer_size = 0; + int phnum = 1; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); + + program_size = ALIGN_ADDR (core_size); + + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size); + memcpy (elf_img + header_size, core_img, core_size); + ehdr = (void *) elf_img; + phdr = (void *) (elf_img + sizeof (*ehdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASS32; + if (!image_target->bigendian) + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + else + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr->e_type = grub_host_to_target16 (ET_EXEC); + ehdr->e_machine = grub_host_to_target16 (image_target->elf_target); + ehdr->e_version = grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); + ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum = grub_host_to_target16 (phnum); + + /* No section headers. */ + ehdr->e_shoff = grub_host_to_target32 (0); + ehdr->e_shentsize = grub_host_to_target16 (0); + ehdr->e_shnum = grub_host_to_target16 (0); + ehdr->e_shstrndx = grub_host_to_target16 (0); + + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + + if (image_target->id == IMAGE_YEELOONG_ELF) + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + + kernel_size + total_module_size, 32); + else + target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; + ehdr->e_entry = grub_host_to_target32 (target_addr); + phdr->p_vaddr = grub_host_to_target32 (target_addr); + phdr->p_paddr = grub_host_to_target32 (target_addr); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + | EF_MIPS_PIC | EF_MIPS_CPIC); + else + ehdr->e_flags = 0; + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note->header.descsz = grub_host_to_target32 (note_size); + note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); + note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note->descriptor.real_base = grub_host_to_target32 (0x00c00000); + note->descriptor.real_size = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note->descriptor.load_base = grub_host_to_target32 (0x00004000); + + phdr[1].p_type = grub_host_to_target32 (PT_NOTE); + phdr[1].p_flags = grub_host_to_target32 (PF_R); + phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_vaddr = 0; + phdr[1].p_paddr = 0; + phdr[1].p_filesz = grub_host_to_target32 (note_size); + phdr[1].p_memsz = 0; + phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + } + + free (core_img); + core_img = elf_img; + core_size = program_size + header_size + footer_size; + } + break; } - else - { - unsigned int num; - char *boot_path, *boot_img; - size_t boot_size; - - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - num <<= GRUB_DISK_SECTOR_BITS; - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error ("diskboot.img is not one sector size"); - - boot_img = grub_util_read_image (boot_path); - - *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_host_to_target32 (num); - - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_MIPS) || defined (GRUB_MACHINE_IEEE1275) - if (format == GRUB_PLATFORM_IMAGE_ELF) - { - char *elf_img; - size_t program_size; - Elf32_Ehdr *ehdr; - Elf32_Phdr *phdr; - grub_uint32_t target_addr; - int header_size, footer_size = 0; - int phnum = 1; - - if (note) - { - phnum++; - footer_size += sizeof (struct grub_ieee1275_note); - } - header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); - - program_size = ALIGN_ADDR (core_size); - - elf_img = xmalloc (program_size + header_size + footer_size); - memset (elf_img, 0, program_size + header_size); - memcpy (elf_img + header_size, core_img, core_size); - ehdr = (void *) elf_img; - phdr = (void *) (elf_img + sizeof (*ehdr)); - memcpy (ehdr->e_ident, ELFMAG, SELFMAG); - ehdr->e_ident[EI_CLASS] = ELFCLASS32; -#ifdef GRUB_CPU_MIPSEL - ehdr->e_ident[EI_DATA] = ELFDATA2LSB; -#else - ehdr->e_ident[EI_DATA] = ELFDATA2MSB; -#endif - ehdr->e_ident[EI_VERSION] = EV_CURRENT; - ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; - ehdr->e_type = grub_host_to_target16 (ET_EXEC); - ehdr->e_machine = grub_host_to_target16 (EM_TARGET); - ehdr->e_version = grub_host_to_target32 (EV_CURRENT); - - ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); - ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum = grub_host_to_target16 (phnum); - - /* No section headers. */ - ehdr->e_shoff = grub_host_to_target32 (0); - ehdr->e_shentsize = grub_host_to_target16 (0); - ehdr->e_shnum = grub_host_to_target16 (0); - ehdr->e_shstrndx = grub_host_to_target16 (0); - - ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); - - phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (header_size); - phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - -#if defined(GRUB_MACHINE_MIPS) - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); -#else - target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; -#endif - ehdr->e_entry = grub_host_to_target32 (target_addr); - phdr->p_vaddr = grub_host_to_target32 (target_addr); - phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); -#if defined(GRUB_MACHINE_MIPS) - ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER - | EF_MIPS_PIC | EF_MIPS_CPIC); -#else - ehdr->e_flags = 0; -#endif - phdr->p_filesz = grub_host_to_target32 (core_size); - phdr->p_memsz = grub_host_to_target32 (core_size); - - if (note) - { - int note_size = sizeof (struct grub_ieee1275_note); - struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) - (elf_img + program_size + header_size); - - grub_util_info ("adding CHRP NOTE segment"); - - note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); - note->header.descsz = grub_host_to_target32 (note_size); - note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); - strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); - note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); - note->descriptor.real_base = grub_host_to_target32 (0x00c00000); - note->descriptor.real_size = grub_host_to_target32 (0xffffffff); - note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); - note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); - note->descriptor.load_base = grub_host_to_target32 (0x00004000); - - phdr[1].p_type = grub_host_to_target32 (PT_NOTE); - phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr[1].p_vaddr = 0; - phdr[1].p_paddr = 0; - phdr[1].p_filesz = grub_host_to_target32 (note_size); - phdr[1].p_memsz = 0; - phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); - } - - free (core_img); - core_img = elf_img; - core_size = program_size + header_size + footer_size; - } -#endif grub_util_write_image (core_img, core_size, out); free (kernel_img); @@ -1368,9 +1499,7 @@ static struct option options[] = {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, {"note", no_argument, 0, 'n'}, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT {"format", required_argument, 0, 'O'}, -#endif {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -1383,7 +1512,24 @@ usage (int status) if (status) fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); else - printf (_("\ + { + int format_len = 0; + char *formats; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + format_len += strlen (image_targets[i].name) + 2; + ptr = formats = xmalloc (format_len); + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + { + strcpy (ptr, image_targets[i].name); + ptr += strlen (image_targets[i].name); + *ptr++ = ','; + *ptr++ = ' '; + } + ptr[-2] = 0; + + printf (_("\ Usage: %s [OPTION]... [MODULES]\n\ \n\ Make a bootable image of GRUB.\n\ @@ -1394,25 +1540,20 @@ Make a bootable image of GRUB.\n\ -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ -n, --note add NOTE segment for CHRP Open Firmware\n\ - -o, --output=FILE output a generated image to FILE [default=stdout]\n" -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - "\ - -O, --format=FORMAT generate an image in format [default=%s]\n\ - available formats: %s\n" -#endif - "\ + -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -O, --format=FORMAT generate an image in format\n\ + available formats: %s\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ "), -program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT, GRUB_PLATFORM_IMAGE_FORMATS, -#endif -PACKAGE_BUGREPORT); - + program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, + formats, + PACKAGE_BUGREPORT); + free (formats); + } exit (status); } @@ -1427,9 +1568,7 @@ main (int argc, char *argv[]) char *config = NULL; FILE *fp = stdout; int note = 0; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; -#endif + struct image_target_desc *image_target = NULL; set_program_name (argv[0]); @@ -1451,27 +1590,19 @@ main (int argc, char *argv[]) output = xstrdup (optarg); break; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT case 'O': -#ifdef GRUB_PLATFORM_IMAGE_RAW - if (strcmp (optarg, "raw") == 0) - format = GRUB_PLATFORM_IMAGE_RAW; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_ELF - if (strcmp (optarg, "elf") == 0) - format = GRUB_PLATFORM_IMAGE_ELF; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_AOUT - if (strcmp (optarg, "aout") == 0) - format = GRUB_PLATFORM_IMAGE_AOUT; - else -#endif - usage (1); - break; -#endif - + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + if (strcmp (optarg, image_targets[i].name) == 0) + image_target = &image_targets[i]; + if (!image_target) + { + printf ("unknown target %s\n", optarg); + usage (1); + } + break; + } case 'd': if (dir) free (dir); @@ -1534,6 +1665,12 @@ main (int argc, char *argv[]) } } + if (!image_target) + { + printf ("Target not specified.\n"); + usage (1); + } + if (output) { fp = fopen (output, "wb"); @@ -1544,12 +1681,7 @@ main (int argc, char *argv[]) generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - format, -#else - 0, -#endif - note); + image_target, note); fclose (fp); diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index aafdfb059..7d553a767 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -171,7 +171,7 @@ fi if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ + grub-mkimage -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img