From 2296410ffbef1c180f3c001dff7abcc39fc6a242 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 22:26:29 +0200 Subject: [PATCH] initial support for ppc in grub-mkimage (bugs for now) --- conf/common.rmk | 7 ++ conf/i386-pc.rmk | 7 -- conf/i386-qemu.rmk | 6 -- conf/mips.rmk | 7 -- conf/sparc64-ieee1275.rmk | 5 -- conf/x86-efi.rmk | 8 -- include/grub/mips/kernel.h | 2 + include/grub/powerpc/ieee1275/kernel.h | 19 ++++ include/grub/powerpc/kernel.h | 3 - kern/powerpc/ieee1275/startup.S | 6 +- util/elf/grub-mkimage.c | 5 +- util/grub-mkimage.c | 115 +++++++++++++++++++++---- 12 files changed, 133 insertions(+), 57 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..011bb2773 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -21,6 +21,13 @@ grub_mkelfimage_SOURCES = gnulib/progname.c \ util/resolve.c util/elf/grub-mkimage.c_DEPENDENCIES = Makefile +# For grub-mkimage. +bin_UTILITIES += grub-mkimage +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ + util/resolve.c lib/LzmaEnc.c lib/LzFind.c +grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +util/grub-mkimage.c_DEPENDENCIES = Makefile + # For grub-probe. sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 2dd874e13..1e0a3ff58 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -61,15 +61,8 @@ kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkimage.c_DEPENDENCIES = Makefile - # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 003f86c33..ff263245d 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -13,12 +13,6 @@ boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_M boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR) boot_img_FORMAT = binary -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ - util/resolve.c gnulib/progname.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkimage.c_DEPENDENCIES = Makefile - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ diff --git a/conf/mips.rmk b/conf/mips.rmk index c748d3945..7d30f55f1 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -10,13 +10,6 @@ kernel_img_HEADERS += cpu/cache.h sbin_SCRIPTS = bin_SCRIPTS = -# For grub-mkimage. -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/grub-mkimage.c_DEPENDENCIES = Makefile - # For serial.mod. pkglib_MODULES += serial.mod serial_mod_SOURCES = term/serial.c diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index dd1524df1..5b71d4cb2 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -41,13 +41,8 @@ kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc kernel_img_FORMAT = binary # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname -# For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ - util/resolve.c gnulib/progname.c - # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 8bf0a08d9..99a9938ef 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -1,13 +1,5 @@ # -*- makefile -*- -# Utilities. -bin_UTILITIES = grub-mkimage - -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c \ - util/misc.c util/resolve.c -util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile - # Scripts. sbin_SCRIPTS = grub-install diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 8b68f7b6b..172c1dbe2 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -46,6 +46,8 @@ #define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW +#define EM_TARGET EM_MIPS + #ifndef ASM_FILE typedef enum { diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h index a76c2a4df..229416243 100644 --- a/include/grub/powerpc/ieee1275/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -21,8 +21,27 @@ #include +#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" +#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" + +#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW +#define GRUB_KERNEL_MACHINE_PREFIX 0x4 +#define GRUB_KERNEL_MACHINE_DATA_END 0x44 +#define GRUB_KERNEL_MACHINE_LINK_ALIGN 4 + +#define EM_TARGET EM_PPC +#define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 + #ifndef ASM_FILE +typedef enum { + GRUB_PLATFORM_IMAGE_RAW, + GRUB_PLATFORM_IMAGE_ELF +} + grub_platform_image_format_t; +#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW +#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF + /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h index b4687337f..e4ff65174 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -26,7 +26,4 @@ rewrite grub-mkimage to generate valid ELF files. */ #define GRUB_MOD_GAP 0x8000 -#define GRUB_KERNEL_CPU_PREFIX 0x4 -#define GRUB_KERNEL_CPU_DATA_END 0x44 - #endif diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S index 75e1ed852..979f260f8 100644 --- a/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end @@ -30,7 +30,7 @@ start: _start: b codestart - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkelfimage */ @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: li 2, 0 diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c index 04a19bc4e..f37837c19 100644 --- a/util/elf/grub-mkimage.c +++ b/util/elf/grub-mkimage.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "progname.h" @@ -323,9 +324,9 @@ add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char * if (prefix) { - if (GRUB_KERNEL_CPU_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_CPU_DATA_END) + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error ("prefix too long"); - grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_CPU_PREFIX, out); + grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_MACHINE_PREFIX, out); } free (phdrs); diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 30608a932..71376eaee 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -46,6 +46,36 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define GRUB_IEEE1275_NOTE_NAME "PowerPC" +#define GRUB_IEEE1275_NOTE_TYPE 0x1275 + +/* These structures are defined according to the CHRP binding to IEEE1275, + "Client Program Format" section. */ + +struct grub_ieee1275_note_hdr +{ + grub_uint32_t namesz; + grub_uint32_t descsz; + grub_uint32_t type; + char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; +}; + +struct grub_ieee1275_note_desc +{ + grub_uint32_t real_mode; + grub_uint32_t real_base; + grub_uint32_t real_size; + grub_uint32_t virt_base; + grub_uint32_t virt_size; + grub_uint32_t load_base; +}; + +struct grub_ieee1275_note +{ + struct grub_ieee1275_note_hdr header; + 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) @@ -786,11 +816,11 @@ 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 + grub_platform_image_format_t format, #else - int dummy __attribute__ ((unused)) + int dummy __attribute__ ((unused)), #endif - + int note ) { char *kernel_img, *core_img; @@ -1205,7 +1235,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_img); free (boot_path); } -#elif defined(GRUB_MACHINE_MIPS) +#elif defined(GRUB_MACHINE_MIPS) || defined (GRUB_MACHINE_IEEE1275) if (format == GRUB_PLATFORM_IMAGE_ELF) { char *elf_img; @@ -1213,12 +1243,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], 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 + sizeof (*ehdr) + sizeof (*phdr)); - memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr)); - memcpy (elf_img + sizeof (*ehdr) + sizeof (*phdr), core_img, 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); @@ -1231,12 +1270,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], 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_MIPS); + 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 (1); + ehdr->e_phnum = grub_host_to_target16 (phnum); /* No section headers. */ ehdr->e_shoff = grub_host_to_target32 (0); @@ -1247,23 +1286,60 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], 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 (sizeof (*ehdr) + sizeof (*phdr)); + phdr->p_offset = grub_host_to_target32 (header_size); phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR +#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 + sizeof (*ehdr) + sizeof (*phdr); + core_size = program_size + header_size + footer_size; } #endif @@ -1291,6 +1367,7 @@ static struct option options[] = {"font", required_argument, 0, 'f'}, {"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 @@ -1316,6 +1393,7 @@ Make a bootable image of GRUB.\n\ -m, --memdisk=FILE embed FILE as a memdisk image\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 "\ @@ -1348,6 +1426,7 @@ main (int argc, char *argv[]) char *font = NULL; 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 @@ -1358,7 +1437,7 @@ main (int argc, char *argv[]) while (1) { - int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVvn", options, 0); if (c == -1) break; @@ -1400,6 +1479,10 @@ main (int argc, char *argv[]) dir = xstrdup (optarg); break; + case 'n': + note = 1; + break; + case 'm': if (memdisk) free (memdisk); @@ -1462,11 +1545,11 @@ 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 + format, #else - 0 + 0, #endif - ); + note); fclose (fp);