diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 37a9f5b..89ad861 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -155,7 +155,7 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \ vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \ videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod \ ata.mod vga.mod memdisk.mod jpeg.mod png.mod pci.mod lspci.mod \ - aout.mod _bsd.mod bsd.mod + aout.mod _bsd.mod bsd.mod findroot.mod # For biosdisk.mod. biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c @@ -322,4 +322,9 @@ bsd_mod_SOURCES = loader/i386/bsd_normal.c bsd_mod_CFLAGS = $(COMMON_CFLAGS) bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For findroot.mod. +findroot_mod_SOURCES = kern/findroot.c +findroot_mod_CFLAGS = $(COMMON_CFLAGS) +findroot_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 43a8d5b..c35b8d4 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -68,7 +68,7 @@ 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[]; +extern char EXPORT_VAR(grub_prefix) []; /* The boot BIOS drive number. */ extern grub_int32_t EXPORT_VAR(grub_boot_drive); diff --git a/kern/findroot.c b/kern/findroot.c new file mode 100755 index 0000000..6a6cc69 --- /dev/null +++ b/kern/findroot.c @@ -0,0 +1,77 @@ +/* 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 +find_root (void) +{ + char *buf = 0; + auto int iterate_device (const char *name); + + int iterate_device (const char *name) + { + grub_size_t len; + char *p; + grub_file_t file; + + len = grub_strlen (name) + 2 + grub_strlen (grub_prefix) + + sizeof (KERNEL_FILE); + + p = grub_realloc (buf, len); + if (! p) + return 1; + + buf = p; + grub_sprintf (buf, "(%s)%s" KERNEL_FILE, name, grub_prefix); + + file = grub_file_open (buf); + if (file) + { + buf[grub_strlen (name) + 2 + grub_strlen (grub_prefix)] = 0; + grub_env_set ("prefix", buf); + + grub_file_close (file); + + return 1; + } + + grub_errno = GRUB_ERR_NONE; + return 0; + } + + grub_device_iterate (iterate_device); + + grub_free (buf); +} + +GRUB_MOD_INIT(findroot) +{ + find_root (); +} diff --git a/kern/main.c b/kern/main.c index 09de03a..a7e1e4f 100644 --- a/kern/main.c +++ b/kern/main.c @@ -124,7 +124,9 @@ grub_main (void) /* It is better to set the root device as soon as possible, for convenience. */ - grub_machine_set_prefix (); + if (! grub_env_get ("prefix")) + grub_machine_set_prefix (); + grub_set_root_dev (); /* Load the normal mode module. */