diff --git a/boot/i386/pc/lnxboot.S b/boot/i386/pc/lnxboot.S index 955cc41..380ef08 100644 --- a/boot/i386/pc/lnxboot.S +++ b/boot/i386/pc/lnxboot.S @@ -185,7 +185,7 @@ real_code_2: call move_memory /* Check for multiboot signature. */ - cmpl $MULTIBOOT_MAGIC, %ss:(DATA_ADDR + 0x50) + cmpl $MULTIBOOT_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END) jz 1f movl (ramdisk_image - start), %esi diff --git a/conf/common.rmk b/conf/common.rmk index acbebc7..0582d56 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -94,6 +94,12 @@ grub_fstest_init.c: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_ rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ DISTCLEANFILES += grub_fstest_init.c +# for grub-editenv +bin_UTILITIES += grub-editenv +grub_editenv_SOURCES = util/grub-editenv.c util/envblk.c util/misc.c \ + kern/err.c kern/misc.c +CLEANFILES += grub-editenv + # For update-grub update-grub: util/update-grub.in config.status ./config.status --file=$@:$< @@ -365,7 +371,7 @@ hexdump_mod_CFLAGS = $(COMMON_CFLAGS) hexdump_mod_LDFLAGS = $(COMMON_LDFLAGS) # Misc. -pkglib_MODULES += gzio.mod elf.mod +pkglib_MODULES += gzio.mod elf.mod findroot.mod # For elf.mod. elf_mod_SOURCES = kern/elf.c @@ -386,3 +392,8 @@ read_mod_LDFLAGS = $(COMMON_LDFLAGS) sleep_mod_SOURCES = commands/sleep.c sleep_mod_CFLAGS = $(COMMON_CFLAGS) sleep_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For findroot.mod. +findroot_mod_SOURCES = kern/findroot.c +findroot_mod_CFLAGS = $(COMMON_CFLAGS) +findroot_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/envblk.h b/include/grub/envblk.h new file mode 100755 index 0000000..7811723 --- /dev/null +++ b/include/grub/envblk.h @@ -0,0 +1,47 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ENVBLK_HEADER +#define GRUB_ENVBLK_HEADER 1 + +#define GRUB_ENVBLK_SIGNATURE 0x4b627645 /* EvbK */ + +#define GRUB_ENVBLK_MAXLEN 8192 + +/* Names of important environment variables. */ +#define GRUB_ENVBLK_RDIR "rdir" +#define GRUB_ENVBLK_UUID "uuid" +#define GRUB_ENVBLK_LABEL "label" + +#ifndef ASM_FILE + +struct grub_envblk +{ + grub_uint32_t signature; + grub_uint16_t length; + char data[0]; +} __attribute__ ((packed)); +typedef struct grub_envblk *grub_envblk_t; + +grub_envblk_t grub_envblk_find (char *buf); +int grub_envblk_insert (grub_envblk_t envblk, char *name, char *value); +void grub_envblk_delete (grub_envblk_t envblk, char *name); + +#endif + +#endif /* ! GRUB_ENVBLK_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 43a8d5b..13548c5 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -37,14 +37,14 @@ /* The offset of GRUB_MEMDISK_IMAGE_SIZE. */ #define GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE 0x1c -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x20 +/* The offset of GRUB_ENVBLK. */ +#define GRUB_KERNEL_MACHINE_ENVBLK 0x26 /* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 +#define GRUB_KERNEL_MACHINE_DATA_END 0x70 /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_MACHINE_RAW_SIZE 0x4A0 +#define GRUB_KERNEL_MACHINE_RAW_SIZE 0x4C0 #ifndef ASM_FILE @@ -66,9 +66,9 @@ extern grub_int32_t grub_install_bsd_part; /* The size of memory disk image, if present. */ extern grub_int32_t grub_memdisk_image_size; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; +/* The envblk contains variable which can be used to locate the directory where + GRUB modules and its configuration file. */ +extern char grub_envblk[]; /* The boot BIOS drive number. */ extern grub_int32_t EXPORT_VAR(grub_boot_drive); diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 4a4e2cc..49f3516 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -55,8 +55,10 @@ void grub_machine_init (void); /* The machine-specific finalization. */ void grub_machine_fini (void); -/* The machine-specific prefix initialization. */ -void grub_machine_set_prefix (void); +/* The machine-specific root initialization. */ +void grub_machine_set_root (void); + +char *grub_machine_get_envblk (void); /* Register all the exported symbols. This is automatically generated. */ void grub_register_exported_symbols (void); diff --git a/kern/findroot.c b/kern/findroot.c new file mode 100755 index 0000000..3ac5ce5 --- /dev/null +++ b/kern/findroot.c @@ -0,0 +1,96 @@ +/* findroot.c - search for root device */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KERNEL_FILE "/normal.mod" + +static void +findroot (void) +{ + char *label, *uuid; + + auto int iterate_device (const char *name); + int iterate_device (const char *name) + { + int found = 0; + grub_device_t dev; + grub_fs_t fs; + + dev = grub_device_open (name); + if (dev) + { + fs = grub_fs_probe (dev); + if (fs) + { + if ((uuid) && (fs->uuid)) + { + char *cur; + + fs->uuid (dev, &cur); + if (cur) + { + found = (! grub_strcmp (uuid, cur)); + grub_free (cur); + } + } + else if ((label) && (fs->label)) + { + char *cur; + + fs->label (dev, &cur); + if (cur) + { + found = (! grub_strcmp (label, cur)); + grub_free (cur); + } + } + + if (found) + grub_env_set ("root", name); + } + + grub_device_close (dev); + } + + grub_errno = GRUB_ERR_NONE; + return found; + } + + label = grub_env_get ("label"); + uuid = grub_env_get ("uuid"); + + if ((! label) && (! uuid)) + return; + + grub_device_iterate (iterate_device); +} + +GRUB_MOD_INIT(findroot) +{ + findroot (); +} diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index 757f5d5..aabdff2 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -58,40 +58,6 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), { } -static char * -make_install_device (void) -{ - /* XXX: This should be enough. */ - char dev[100]; - - if (grub_memdisk_image_size) - { - grub_sprintf (dev, "(memdisk)%s", grub_prefix); - grub_strcpy (grub_prefix, dev); - } - else if (grub_install_dos_part != -2) - { - /* If the root drive is not set explicitly, assume that it is identical - to the boot drive. */ - if (grub_root_drive == 0xFF) - grub_root_drive = grub_boot_drive; - - grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f', - grub_root_drive & 0x7f); - - if (grub_install_dos_part >= 0) - grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1); - - if (grub_install_bsd_part >= 0) - grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a'); - - grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix); - grub_strcpy (grub_prefix, dev); - } - - return grub_prefix; -} - /* Add a memory region. */ static void add_mem_region (grub_addr_t addr, grub_size_t size) @@ -238,11 +204,40 @@ grub_machine_init (void) grub_fatal ("no upper memory"); } +char * +grub_machine_get_envblk (void) +{ + return grub_envblk; +} + void -grub_machine_set_prefix (void) +grub_machine_set_root (void) { - /* Initialize the prefix. */ - grub_env_set ("prefix", make_install_device ()); + /* XXX: This should be enough. */ + char dev[100]; + + if (grub_memdisk_image_size) + { + grub_env_set ("root", "memdisk"); + } + else if (grub_install_dos_part != -2) + { + /* If the root drive is not set explicitly, assume that it is identical + to the boot drive. */ + if (grub_root_drive == 0xFF) + grub_root_drive = grub_boot_drive; + + grub_sprintf (dev, "%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f', + grub_root_drive & 0x7f); + + if (grub_install_dos_part >= 0) + grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1); + + if (grub_install_bsd_part >= 0) + grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a'); + + grub_env_set ("root", dev); + } } void diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index ebb98fe..cba710a 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -52,6 +52,7 @@ #include #include #include +#include #define ABS(x) ((x) - EXT_C(start) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) @@ -98,14 +99,19 @@ VARIABLE(grub_install_bsd_part) .long 0xFFFFFFFF VARIABLE(grub_memdisk_image_size) .long 0 -VARIABLE(grub_prefix) + .long GRUB_ENVBLK_SIGNATURE + .word envblk_end - grub_envblk +VARIABLE(grub_envblk) + .byte 0 /* to be filled by grub-mkimage */ /* * Leave some breathing room for the prefix. */ - . = EXT_C(start) + 0x50 + . = EXT_C(start) + 0x70 + +envblk_end: /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). diff --git a/kern/main.c b/kern/main.c index 09de03a..729dd78 100644 --- a/kern/main.c +++ b/kern/main.c @@ -28,6 +28,33 @@ #include #include +static void +grub_parse_envblk (void) +{ + char *env; + + env = grub_machine_get_envblk (); + if (! env) + return; + + while (*env) + { + char *value; + + value = grub_strchr (env, '='); + if (value) + { + *(value++) = 0; + grub_env_set (env, value); + env = value; + } + else + grub_env_set (env, ""); + + env += grub_strlen (env) + 1; + } +} + /* Load all modules in core. */ static void grub_load_modules (void) @@ -75,24 +102,28 @@ grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)), static void grub_set_root_dev (void) { - const char *prefix; + char *root, *rdir, *prefix; + + if (! grub_env_get ("root")) + grub_machine_set_root (); grub_register_variable_hook ("root", 0, grub_env_write_root); grub_env_export ("root"); - prefix = grub_env_get ("prefix"); + root = grub_env_get ("root"); + if (! *root) + return; - if (prefix) - { - char *dev; - - dev = grub_file_get_device_name (prefix); - if (dev) - { - grub_env_set ("root", dev); - grub_free (dev); - } - } + rdir = grub_env_get ("rdir"); + if (! rdir) + rdir = "/"; + + prefix = grub_malloc (grub_strlen (root) + grub_strlen (rdir) + 3); + grub_sprintf (prefix, "(%s)%s", root, rdir); + + grub_env_set ("prefix", prefix); + + grub_free (prefix); } /* Load the normal mode module and execute the normal mode if possible. */ @@ -118,13 +149,15 @@ grub_main (void) grub_printf ("Welcome to GRUB!\n\n"); grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + /* Parse the environment block. */ + grub_parse_envblk (); + /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); grub_load_modules (); /* It is better to set the root device as soon as possible, for convenience. */ - grub_machine_set_prefix (); grub_set_root_dev (); /* Load the normal mode module. */ diff --git a/util/envblk.c b/util/envblk.c new file mode 100755 index 0000000..82ec674 --- /dev/null +++ b/util/envblk.c @@ -0,0 +1,123 @@ +/* envblk.c - Common function for environment block. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +grub_envblk_t +grub_envblk_find (char *buf) +{ + grub_uint32_t *pd; + int len; + + pd = (grub_uint32_t *) buf; + + for (len = GRUB_ENVBLK_MAXLEN - 6; len > 0; len -= 4, pd++) + if (*pd == GRUB_ENVBLK_SIGNATURE) + { + grub_envblk_t p; + + p = (grub_envblk_t) pd; + if (p->length <= len) + return p; + } + + return 0; +} + +int +grub_envblk_insert (grub_envblk_t envblk, char *name, char *value) +{ + char *p, *pend; + char *found = 0; + int nl; + + nl = grub_strlen (name); + p = envblk->data; + pend = p + envblk->length; + + while (*p) + { + if ((! found) && (! grub_memcmp (name, p, nl)) && (p[nl] == '=')) + found = p + nl + 1; + + p += strlen (p) + 1; + if (p >= pend) + return 1; + } + + if (found) + { + int len1, len2; + + len1 = grub_strlen (found); + len2 = grub_strlen (value); + if ((p - envblk->data) + 1 - len1 + len2 > envblk->length) + return 1; + + grub_memcpy (found + len2 + 1, found + len1 + 1, (p - found) - len1); + grub_strcpy (found, value); + } + else + { + int len2 = grub_strlen (value); + + if ((p - envblk->data) + nl + 1 + len2 + 2 > envblk->length) + return 1; + + grub_strcpy (p, name); + p[nl] = '='; + grub_strcpy (p + nl + 1, value); + p[nl + 1 + len2 + 1] = 0; + } + + return 0; +} + +void +grub_envblk_delete (grub_envblk_t envblk, char *name) +{ + char *p, *pend; + char *found = 0; + int nl; + + nl = grub_strlen (name); + p = envblk->data; + pend = p + envblk->length; + + while (*p) + { + if ((! found) && (! grub_memcmp (name, p, nl)) && (p[nl] == '=')) + found = p; + + p += strlen (p) + 1; + if (p >= pend) + return; + } + + if (found) + { + int len; + + len = grub_strlen (found); + grub_memcpy (found, found + len + 1, (p - found) - len); + } +} diff --git a/util/grub-editenv.c b/util/grub-editenv.c new file mode 100755 index 0000000..d4d7919 --- /dev/null +++ b/util/grub-editenv.c @@ -0,0 +1,259 @@ +/* grub-editenv.c - tool to edit environment block. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +void * +grub_term_get_current (void) +{ + return 0; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + +char * +grub_env_get (const char * name) +{ + (void) name; + + return 0; +} + +static struct option options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} +}; + +char buffer[GRUB_ENVBLK_MAXLEN]; +grub_envblk_t envblk; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-editenv --help'' for more information.\n"); + else + printf ("\ +Usage: grub-editenv [OPTIONS] FILENAME COMMAND\n\ +\n\ +Tool to edit environment block.\n\ +\nCommands:\n\ + create create a blank environment block file\n\ + info show information about the environment block\n\ + list list the current variables\n\ + edit [name=value] ... change/delete variables\n\ + clear delete all variables\n\ +\nOptions:\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", PACKAGE_BUGREPORT); + + exit (status); +} + +int +create_envblk_file (char *name) +{ + FILE *f; + grub_envblk_t p; + + f = fopen (name, "w"); + if (! f) + return 1; + + /* Just in case OS don't save 0s. */ + memset (buffer, -1, sizeof (buffer)); + + p = (grub_envblk_t) &buffer[0]; + p->signature = GRUB_ENVBLK_SIGNATURE; + p->length = sizeof (buffer) - sizeof (struct grub_envblk); + p->data[0] = p->data[1] = 0; + + fwrite (buffer, sizeof (buffer), 1, f); + + fclose (f); + return 0; +} + +FILE * +open_envblk_file (char *name) +{ + FILE *f; + + f = fopen (name, "r+"); + if (! f) + grub_util_error ("Can\'t open file %s", name); + + if (fread (buffer, 1, sizeof (buffer), f) != sizeof (buffer)) + grub_util_error ("The envblk file is too short"); + + envblk = grub_envblk_find (buffer); + if (! envblk) + grub_util_error ("Can\'t find environment block"); + + return f; +} + +static void +cmd_info (void) +{ + printf ("Envblk offset: %d\n", (char *) envblk - buffer); + printf ("Envblk length: %d\n", envblk->length); +} + +static void +cmd_list (void) +{ + char *p = envblk->data; + + while (*p) + { + printf ("%s\n", p); + p += strlen (p) + 1; + } +} + +static void +cmd_edit (int argc, char *argv[]) +{ + while (argc) + { + char *p; + + p = strchr (argv[0], '='); + if (! p) + grub_util_error ("Invalid parameter"); + + *(p++) = 0; + + if (*p) + { + if (grub_envblk_insert (envblk, argv[0], p)) + grub_util_error ("Environment block too small"); + } + else + grub_envblk_delete (envblk, argv[0]); + + argc--; + argv++; + } +} + +static void +cmd_clear (void) +{ + envblk->data[0] = envblk->data[1] = 0; +} + +int +main (int argc, char *argv[]) +{ + FILE *f; + + progname = "grub-editenv"; + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + /* Obtain PATH. */ + if (optind + 1 >= argc) + { + fprintf (stderr, "Not enough parameter.\n"); + usage (1); + } + + if (! strcmp (argv[optind + 1], "create")) + return create_envblk_file (argv[optind]); + + f = open_envblk_file (argv[optind]); + + optind++; + if (! strcmp (argv[optind], "info")) + cmd_info (); + else if (! strcmp (argv[optind], "list")) + cmd_list (); + else + { + if (! strcmp (argv[optind], "edit")) + cmd_edit (argc - optind - 1, argv + optind + 1); + else if (! strcmp (argv[optind], "clear")) + cmd_clear (); + + fseek (f, 0, SEEK_SET); + fwrite (buffer, sizeof (buffer), 1, f); + } + fclose (f); + + return 0; +} diff --git a/util/grub-emu.c b/util/grub-emu.c index 00a2c49..aa7ceb9 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -36,15 +36,13 @@ #include #include #include +#include #include /* Used for going back to the main function. */ jmp_buf main_env; -/* Store the prefix specified by an argument. */ -static char *prefix = 0; - grub_addr_t grub_arch_modules_addr (void) { @@ -76,11 +74,15 @@ grub_machine_init (void) } void -grub_machine_set_prefix (void) +grub_machine_set_root (void) { - grub_env_set ("prefix", prefix); - free (prefix); - prefix = 0; + /* Do nothing, as root is already set. */ +} + +char * +grub_machine_get_envblk (void) +{ + return 0; } void @@ -205,8 +207,8 @@ main (int argc, char *argv[]) } dir = grub_get_prefix (dir); - prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1); - sprintf (prefix, "(%s)%s", root_dev, dir); + grub_env_set (GRUB_ENVBLK_RDIR, dir); + grub_env_set ("root", root_dev); free (dir); /* Start GRUB! */ diff --git a/util/i386/pc/grub-mkimage.c b/util/i386/pc/grub-mkimage.c index 48d6dfc..f71924b 100644 --- a/util/i386/pc/grub-mkimage.c +++ b/util/i386/pc/grub-mkimage.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -109,9 +110,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *me kernel_img = xmalloc (kernel_size + total_module_size + memdisk_size); grub_util_load_image (kernel_path, kernel_img); - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + if (GRUB_KERNEL_MACHINE_ENVBLK + sizeof (GRUB_ENVBLK_RDIR) + 2 + strlen (prefix) > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error ("prefix too long"); - strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); + strcpy (kernel_img + GRUB_KERNEL_MACHINE_ENVBLK, GRUB_ENVBLK_RDIR "="); + strcpy (kernel_img + GRUB_KERNEL_MACHINE_ENVBLK + sizeof (GRUB_ENVBLK_RDIR), prefix); /* Fill in the grub_module_info structure. */ modinfo = (struct grub_module_info *) (kernel_img + kernel_size); diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 535a8d0..2a243e8 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -34,6 +34,7 @@ #include #include #include +#include static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; @@ -235,7 +236,10 @@ setup (const char *prefix, const char *dir, install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART); install_prefix = (core_img + GRUB_DISK_SECTOR_SIZE - + GRUB_KERNEL_MACHINE_PREFIX); + + GRUB_KERNEL_MACHINE_ENVBLK); + + strcpy (install_prefix, GRUB_ENVBLK_RDIR "="); + install_prefix += sizeof (GRUB_ENVBLK_RDIR); /* Open the root device and the destination device. */ root_dev = grub_device_open (root);