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. */