From bf697e283111fcb2d32728ac718055b6ff2a62f6 Mon Sep 17 00:00:00 2001 From: robertmh Date: Thu, 21 Jun 2007 21:01:11 +0000 Subject: [PATCH] 2007-06-21 Robert Millan * include/grub/i386/pc/kernel.h: Define GRUB_KERNEL_MACHINE_DATA_END to indicate end of data section in kernel image. * include/grub/i386/efi/kernel.h: Define GRUB_KERNEL_MACHINE_PREFIX and GRUB_KERNEL_MACHINE_DATA_END. * kern/i386/pc/startup.S: Do not initialize grub_prefix, only reserve space for it. * kern/i386/efi/startup.S: Likewise. * util/i386/pc/grub-mkimage.c: Initialize grub_prefix to /boot/grub during image generation. Implement --prefix option to override this patch. * util/i386/efi/grub-mkimage.c: Likewise. * util/update-grub_lib.in (convert_system_path_to_grub_path): Split code to make path relative to its root into a separate function. * util/i386/pc/grub-install.in: Use newly provided make_system_path_relative_to_its_root() to convert ${grubdir}, then pass the result to grub-install --prefix. --- ChangeLog | 23 +++++++++++++++++++++++ include/grub/i386/efi/kernel.h | 6 ++++++ include/grub/i386/pc/kernel.h | 3 +++ kern/i386/efi/startup.S | 2 +- kern/i386/pc/startup.S | 2 +- util/i386/efi/grub-mkimage.c | 25 +++++++++++++++++++------ util/i386/pc/grub-mkimage.c | 26 ++++++++++++++++++++------ 7 files changed, 73 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5fe95360..fe0a0cd83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2007-06-21 Robert Millan + + * include/grub/i386/pc/kernel.h: Define GRUB_KERNEL_MACHINE_DATA_END to + indicate end of data section in kernel image. + * include/grub/i386/efi/kernel.h: Define GRUB_KERNEL_MACHINE_PREFIX and + GRUB_KERNEL_MACHINE_DATA_END. + + * kern/i386/pc/startup.S: Do not initialize grub_prefix, only reserve + space for it. + * kern/i386/efi/startup.S: Likewise. + + * util/i386/pc/grub-mkimage.c: Initialize grub_prefix to /boot/grub + during image generation. Implement --prefix option to override this + patch. + * util/i386/efi/grub-mkimage.c: Likewise. + + * util/update-grub_lib.in (convert_system_path_to_grub_path): Split + code to make path relative to its root into a separate function. + + * util/i386/pc/grub-install.in: Use newly provided + make_system_path_relative_to_its_root() to convert ${grubdir}, then + pass the result to grub-install --prefix. + 2007-06-13 Robert Millan * include/grub/util/misc.h: Define DEFAULT_DIRECTORY and diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h index de802787e..7fda826b9 100644 --- a/include/grub/i386/efi/kernel.h +++ b/include/grub/i386/efi/kernel.h @@ -24,5 +24,11 @@ configuration file are located. */ extern char grub_prefix[]; +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_MACHINE_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_MACHINE_DATA_END 0x50 + #endif /* ! GRUB_MACHINE_KERNEL_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index cc2cdb05a..2ecfebf9a 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -38,6 +38,9 @@ /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_MACHINE_PREFIX 0x1c +/* End of the data section. */ +#define GRUB_KERNEL_MACHINE_DATA_END 0x50 + /* The size of the first region which won't be compressed. */ #define GRUB_KERNEL_MACHINE_RAW_SIZE 0x4A0 diff --git a/kern/i386/efi/startup.S b/kern/i386/efi/startup.S index 6326ba5b7..25ae43785 100644 --- a/kern/i386/efi/startup.S +++ b/kern/i386/efi/startup.S @@ -45,7 +45,7 @@ _start: . = EXT_C(start) + 0x8 VARIABLE(grub_prefix) - .string "/boot/grub" + /* to be filled by grub-mkimage */ /* * Leave some breathing room for the prefix. diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index c79535362..8037c12c3 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -96,7 +96,7 @@ VARIABLE(grub_install_dos_part) VARIABLE(grub_install_bsd_part) .long 0xFFFFFFFF VARIABLE(grub_prefix) - .string "/boot/grub" + /* to be filled by grub-mkimage */ /* * Leave some breathing room for the prefix. diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c index acbfc7a8a..68f45f665 100644 --- a/util/i386/efi/grub-mkimage.c +++ b/util/i386/efi/grub-mkimage.c @@ -30,6 +30,7 @@ #include #include #include +#include static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; @@ -48,7 +49,7 @@ align_pe32_section (Elf32_Addr addr) /* Read the whole kernel image. Return the pointer to a read image, and store the size in bytes in *SIZE. */ static char * -read_kernel_module (const char *dir, size_t *size) +read_kernel_module (const char *dir, char *prefix, size_t *size) { char *kernel_image; char *kernel_path; @@ -58,6 +59,10 @@ read_kernel_module (const char *dir, size_t *size) kernel_image = grub_util_read_image (kernel_path); free (kernel_path); + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + grub_util_error ("prefix too long"); + strcpy (kernel_image + 0x34 + GRUB_KERNEL_MACHINE_PREFIX, prefix); + return kernel_image; } @@ -838,7 +843,7 @@ make_header (FILE *out, Elf32_Addr text_address, Elf32_Addr data_address, /* Convert an ELF relocatable object into an EFI Application (PE32). */ void -convert_elf (const char *dir, FILE *out, char *mods[]) +convert_elf (const char *dir, char *prefix, FILE *out, char *mods[]) { char *kernel_image; size_t kernel_size; @@ -855,7 +860,7 @@ convert_elf (const char *dir, FILE *out, char *mods[]) Elf32_Addr end_address; /* Get the kernel image and check the format. */ - kernel_image = read_kernel_module (dir, &kernel_size); + kernel_image = read_kernel_module (dir, prefix, &kernel_size); e = (Elf32_Ehdr *) kernel_image; if (! check_elf_header (e, kernel_size)) grub_util_error ("invalid ELF header"); @@ -912,6 +917,7 @@ convert_elf (const char *dir, FILE *out, char *mods[]) static struct option options[] = { {"directory", required_argument, 0, 'd'}, + {"prefix", required_argument, 0, 'p'}, {"output", required_argument, 0, 'o'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, @@ -931,13 +937,14 @@ Usage: grub-mkimage -o FILE [OPTION]... [MODULES]\n\ Make a bootable image of GRUB.\n\ \n\ -d, --directory=DIR use images and modules under DIR [default=%s]\n\ +-p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -o, --output=FILE output a generated image to FILE\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\ -", GRUB_LIBDIR, PACKAGE_BUGREPORT); +", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); exit (status); } @@ -948,12 +955,13 @@ main (int argc, char *argv[]) FILE *fp; char *output = NULL; char *dir = NULL; + char *prefix = NULL; progname = "grub-mkimage"; while (1) { - int c = getopt_long (argc, argv, "d:o:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0); if (c == -1) break; @@ -972,6 +980,11 @@ main (int argc, char *argv[]) free (output); output = xstrdup (optarg); break; + case 'p': + if (prefix) + free (prefix); + prefix = xstrdup (optarg); + break; case 'V': printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); return 0; @@ -991,7 +1004,7 @@ main (int argc, char *argv[]) if (! fp) grub_util_error ("cannot open %s", output); - convert_elf (dir ? : GRUB_LIBDIR, fp, argv + optind); + convert_elf (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind); fclose (fp); diff --git a/util/i386/pc/grub-mkimage.c b/util/i386/pc/grub-mkimage.c index 8bb3ea8bf..1f4ca48d0 100644 --- a/util/i386/pc/grub-mkimage.c +++ b/util/i386/pc/grub-mkimage.c @@ -76,7 +76,7 @@ compress_kernel (char *kernel_img, size_t kernel_size, } static void -generate_image (const char *dir, FILE *out, char *mods[]) +generate_image (const char *dir, char *prefix, FILE *out, char *mods[]) { grub_addr_t module_addr = 0; char *kernel_img, *boot_img, *core_img; @@ -102,6 +102,10 @@ generate_image (const char *dir, FILE *out, char *mods[]) kernel_img = xmalloc (kernel_size + total_module_size); grub_util_load_image (kernel_path, kernel_img); + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + grub_util_error ("prefix too long"); + strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); + /* Fill in the grub_module_info structure. */ modinfo = (struct grub_module_info *) (kernel_img + kernel_size); modinfo->magic = GRUB_MODULE_MAGIC; @@ -182,6 +186,7 @@ generate_image (const char *dir, FILE *out, char *mods[]) static struct option options[] = { {"directory", required_argument, 0, 'd'}, + {"prefix", required_argument, 0, 'p'}, {"output", required_argument, 0, 'o'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, @@ -201,13 +206,14 @@ Usage: grub-mkimage [OPTION]... [MODULES]\n\ Make a bootable image of GRUB.\n\ \n\ -d, --directory=DIR use images and modules under DIR [default=%s]\n\ + -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\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\ -", GRUB_LIBDIR, PACKAGE_BUGREPORT); +", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); exit (status); } @@ -215,15 +221,16 @@ Report bugs to <%s>.\n\ int main (int argc, char *argv[]) { - char *output = 0; - char *dir = 0; + char *output = NULL; + char *dir = NULL; + char *prefix = NULL; FILE *fp = stdout; progname = "grub-mkimage"; while (1) { - int c = getopt_long (argc, argv, "d:o:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0); if (c == -1) break; @@ -248,6 +255,13 @@ main (int argc, char *argv[]) usage (0); break; + case 'p': + if (prefix) + free (prefix); + + prefix = xstrdup (optarg); + break; + case 'V': printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); return 0; @@ -269,7 +283,7 @@ main (int argc, char *argv[]) grub_util_error ("cannot open %s", output); } - generate_image (dir ? : GRUB_LIBDIR, fp, argv + optind); + generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind); fclose (fp);