Bug #178586, include support for booting from a GPT-style disk.
authorRobin H. Johnson <robbat2@gentoo.org>
Mon, 25 Feb 2008 01:44:38 +0000 (01:44 +0000)
committerRobin H. Johnson <robbat2@gentoo.org>
Mon, 25 Feb 2008 01:44:38 +0000 (01:44 +0000)
Package-Manager: portage-2.1.4.4

sys-boot/grub/Manifest
sys-boot/grub/files/grub-0.97-gpt.patch [new file with mode: 0644]
sys-boot/grub/grub-0.97-r4.ebuild [new file with mode: 0644]

index 90c786b5a7130d715f1b529352474a6e3409de7b..d622fe1142d55e03792fc0f77cf4eab920336f85 100644 (file)
@@ -1,6 +1,4 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
+AUX grub-0.97-gpt.patch 10682 RMD160 53dd38d52f2b38fb28dfb670d6fd27e47a562bbb SHA1 6057a076110d469fb63e56e57711d281221f9b42 SHA256 5e38046cfb727420e5b4b19d71c7fb4ddff22cbcc356c9f888763b0c1963d389
 AUX grub-1.95-build.patch 522 RMD160 eec01af7250a0883604530f321b154c575b14c41 SHA1 6f93b47a212ed0b3fb807bcf96e04792fa196ba1 SHA256 26d45247376f1e42b4197088161146173ea5bee3800282a707b331c49aed6ccf
 DIST grub-0.92-gentoo-0.2.tar.bz2 21727 RMD160 f420e3352d46fdfb77a1121879382265805bc3ef SHA1 1bb1463067679aab909d1bd96996cfa72556de81 SHA256 f579b49b2d24702905c333ce2b6170a554ce26d0232c65478a21a1fd2eb8b8fe
 DIST grub-0.92.tar.gz 877112 RMD160 97b377a542d415a73c681f2d4c2f57d28e708644 SHA1 15bd5aaa816728583235ab0d5477c1ac32855583 SHA256 197e690faed45bcbf854ab5dc591053d6f6ed1a5b8e5596c4ba27d6f0d50eb37
@@ -24,15 +22,9 @@ EBUILD grub-0.96-r2.ebuild 4343 RMD160 25a2d4263261501e48e6bbedb7fb4761f710778e
 EBUILD grub-0.96-r3.ebuild 4577 RMD160 4a1ac26fd3cce98617883b620255761b98cc8deb SHA1 04c61e8f7e638c3ecf8753ea02bd997f759726b9 SHA256 bbd95b515988ee477725067b1778d0c39665bdce66e61f2e7a9e374a425ac53c
 EBUILD grub-0.97-r2.ebuild 4837 RMD160 857c138748179eac8113fb04166b07d409ed5eca SHA1 41effb9a073d97587d1ffc5cc4ad3c8fcf9b6fab SHA256 433ac8c39e9c9d31e8f470a487d473d4a308520918bdd7763f9ca5b836be6bc0
 EBUILD grub-0.97-r3.ebuild 4702 RMD160 fed2384bb28b76dcf40721c5b2a1f28abc6af28d SHA1 4e14a9413c04827e4432c616d719bbbc88c7d993 SHA256 a005e82201ec3dc4c77b238186acfe0602e529f2d3d48caa0fb08f323e0f5d1a
+EBUILD grub-0.97-r4.ebuild 4747 RMD160 40929821153f0e98280d18f5b4ef691471b233d7 SHA1 b5b86f5c4062c69277ca9f085183eb03de981961 SHA256 1094289cc43c6f89d139d95dc5f71ef2a736e5968e8655a829a1fe429f53cfbe
 EBUILD grub-0.97.ebuild 4518 RMD160 d03dba427b2b040e2b741776a849c4f030793af2 SHA1 07484f2e49a04c267a8f3dec6118b4a2833dbdcd SHA256 7e8e3cd6a5e43507955850ae5d33aaecfb853d8573e54aca5b75b63de7bf48e6
 EBUILD grub-1.95.ebuild 1031 RMD160 1c23cad81706afa0c26f307728afd0241d4fed4e SHA1 ae977cab016f00866c6e689a9178fe7f58512302 SHA256 42be6335ab4b98d3b35db28f0e984730c7f026c2d54db13f838d4c55db6658f8
 EBUILD grub-1.96.ebuild 951 RMD160 e63c22f701ba3761265472679f081df6dc1ceebc SHA1 e39f533503448573a69ea65b2901c43e122434cf SHA256 c872f1879e32130517ef4a9ab5d920a1cb9980a56eec8dbbfeb13eff10579d9a
 MISC ChangeLog 18819 RMD160 3e2b52051d19493a52d13a2e5dd9856bc87fd948 SHA1 91208d9ea731a90e14bfe8840f31ca5c3bb4d51b SHA256 6545c58fb6723f8bb47ca6ea7a08c03cdc9d8cc43a507f55250697699b57117d
 MISC metadata.xml 164 RMD160 f43cbec30b7074319087c9acffdb9354b17b0db3 SHA1 9c213f5803676c56439df3716be07d6692588856 SHA256 f5f2891f2a4791cd31350bb2bb572131ad7235cd0eeb124c9912c187ac10ce92
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v2.0.7 (GNU/Linux)
-
-iD8DBQFHt145j9hvisErhMIRAmOrAJ9Qu6cizluwOOvjsdKtyx1gIojhbgCg45we
-0MBjU5BfP+Wwu73m1pwwZSE=
-=jahH
------END PGP SIGNATURE-----
diff --git a/sys-boot/grub/files/grub-0.97-gpt.patch b/sys-boot/grub/files/grub-0.97-gpt.patch
new file mode 100644 (file)
index 0000000..7b1a55c
--- /dev/null
@@ -0,0 +1,315 @@
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/builtins.c grub-0.96-patched/stage2/builtins.c
+--- grub-0.96/stage2/builtins.c        2004-06-20 09:33:04.000000000 -0400
++++ grub-0.96-patched/stage2/builtins.c        2007-01-04 13:56:06.000000000 -0500
+@@ -1229,14 +1229,15 @@
+   for (drive = 0x80; drive < 0x88; drive++)
+     {
+       unsigned long part = 0xFFFFFF;
+-      unsigned long start, len, offset, ext_offset;
+-      int type, entry;
++      unsigned long start, len, offset, ext_offset, gpt_offset;
++      int type, entry, gpt_count, gpt_size;
+       char buf[SECTOR_SIZE];
+ 
+       current_drive = drive;
+       while (next_partition (drive, 0xFFFFFF, &part, &type,
+                            &start, &len, &offset, &entry,
+-                           &ext_offset, buf))
++                            &ext_offset, &gpt_offset,
++                            &gpt_count, &gpt_size, buf))
+       {
+         if (type != PC_SLICE_TYPE_NONE
+             && ! IS_PC_SLICE_TYPE_BSD (type)
+@@ -2806,8 +2807,8 @@
+ {
+   int new_type;
+   unsigned long part = 0xFFFFFF;
+-  unsigned long start, len, offset, ext_offset;
+-  int entry, type;
++  unsigned long start, len, offset, ext_offset, gpt_offset;
++  int entry, type, gpt_count, gpt_size;
+   char mbr[512];
+ 
+   /* Get the drive and the partition.  */
+@@ -2844,7 +2845,14 @@
+   /* Look for the partition.  */
+   while (next_partition (current_drive, 0xFFFFFF, &part, &type,
+                        &start, &len, &offset, &entry,
+-                       &ext_offset, mbr))
++                       &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
++        /* The partition may not be a GPT partition.  */
++        if (gpt_offset != 0)
++          {
++              errnum = ERR_BAD_ARGUMENT;
++              return 1;
++          }
++
+     {
+       if (part == current_partition)
+       {
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/disk_io.c grub-0.96-patched/stage2/disk_io.c
+--- grub-0.96/stage2/disk_io.c 2004-05-23 12:35:24.000000000 -0400
++++ grub-0.96-patched/stage2/disk_io.c 2007-01-04 14:01:08.000000000 -0500
+@@ -21,6 +21,7 @@
+ 
+ #include <shared.h>
+ #include <filesys.h>
++#include <gpt.h>
+ 
+ #ifdef SUPPORT_NETBOOT
+ # define GRUB 1
+@@ -502,8 +503,8 @@
+ set_partition_hidden_flag (int hidden)
+ {
+   unsigned long part = 0xFFFFFF;
+-  unsigned long start, len, offset, ext_offset;
+-  int entry, type;
++  unsigned long start, len, offset, ext_offset, gpt_offset;
++  int entry, type, gpt_count, gpt_size;
+   char mbr[512];
+   
+   /* The drive must be a hard disk.  */
+@@ -524,7 +525,14 @@
+   /* Look for the partition.  */
+   while (next_partition (current_drive, 0xFFFFFF, &part, &type,           
+                        &start, &len, &offset, &entry,
+-                       &ext_offset, mbr))
++                       &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
++        /* The partition may not be a GPT partition.  */
++        if (gpt_offset != 0)
++          {
++              errnum = ERR_BAD_ARGUMENT;
++              return 1;
++          }
++
+     {                                                                       
+       if (part == current_partition)
+       {
+@@ -577,11 +585,14 @@
+               unsigned long *partition, int *type,
+               unsigned long *start, unsigned long *len,
+               unsigned long *offset, int *entry,
+-              unsigned long *ext_offset, char *buf)
++               unsigned long *ext_offset,
++               unsigned long *gpt_offset, int *gpt_count,
++               int *gpt_size, char *buf)
+ {
+   /* Forward declarations.  */
+   auto int next_bsd_partition (void);
+   auto int next_pc_slice (void);
++  auto int next_gpt_slice(void);
+ 
+   /* Get next BSD partition in current PC slice.  */
+   int next_bsd_partition (void)
+@@ -666,6 +677,40 @@
+         return 0;
+       }
+ 
++      /* If this is a GPT partition table, read it as such.  */
++      if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT)
++       {
++         struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf;
++
++         /* Read in the GPT Partition table header.  */
++         if (! rawread (drive, 1, 0, SECTOR_SIZE, buf))
++           return 0;
++
++         if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000)
++           {
++             /* Let gpt_offset point to the first entry in the GPT
++                partition table.  This can also be used by callers of
++                next_partition to determine if a entry comes from a
++                GPT partition table or not.  */
++             *gpt_offset = hdr->partitions;
++             *gpt_count = hdr->maxpart;
++             *gpt_size =  hdr->partentry_size;
++             
++             return next_gpt_slice();
++           }
++         else
++           {
++             /* This is not a valid header for a GPT partition table.
++                Re-read the MBR or the boot sector of the extended
++                partition.  */
++             if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
++               return 0;
++           }
++       }
++
++      /* Not a GPT partition.  */
++      *gpt_offset = 0;
++
+       /* Increase the entry number.  */
+       (*entry)++;
+ 
+@@ -710,6 +755,43 @@
+       return 1;
+     }
+ 
++  /* Get the next GPT slice.  */
++  int next_gpt_slice (void)
++    {
++      struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf;
++      /* Make GPT partitions show up as PC slices.  */
++      int pc_slice_no = (*partition & 0xFF0000) >> 16;
++
++      /* If this is the first time...  */
++      if (pc_slice_no == 0xFF)
++       {
++         pc_slice_no = -1;
++         *entry = -1;
++       }
++
++      do {
++       (*entry)++;
++
++       if (*entry >= *gpt_count)
++         {
++           errnum = ERR_NO_PART;
++           return 0;
++         }
++       /* Read in the GPT Partition table entry.  */
++       if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf))
++         return 0;
++      } while (! (gptentry->type1 && gptentry->type2));
++
++      pc_slice_no++;
++      *start = gptentry->start;
++      *len = gptentry->end - gptentry->start + 1;
++      *type = PC_SLICE_TYPE_EXT2FS;
++      *entry = pc_slice_no;
++      *partition = (*entry << 16) | 0xFFFF;
++
++      return 1;
++    }
++
+   /* Start the body of this function.  */
+   
+ #ifndef STAGE1_5
+@@ -717,6 +799,9 @@
+     return 0;
+ #endif
+ 
++  if (*partition != 0xFFFFFF && *gpt_offset != 0)
++    return next_gpt_slice ();
++
+   /* If previous partition is a BSD partition or a PC slice which
+      contains BSD partitions...  */
+   if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff))
+@@ -755,6 +840,9 @@
+   unsigned long dest_partition = current_partition;
+   unsigned long part_offset;
+   unsigned long ext_offset;
++  unsigned long gpt_offset;
++  int gpt_count;
++  int gpt_size;
+   int entry;
+   char buf[SECTOR_SIZE];
+   int bsd_part, pc_slice;
+@@ -766,7 +854,8 @@
+       int ret = next_partition (current_drive, dest_partition,
+                               &current_partition, &current_slice,
+                               &part_start, &part_length,
+-                              &part_offset, &entry, &ext_offset, buf);
++                               &part_offset, &entry, &ext_offset,
++                               &gpt_offset, &gpt_count, &gpt_size, buf);
+       bsd_part = (current_partition >> 8) & 0xFF;
+       pc_slice = current_partition >> 16;
+       return ret;
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/gpt.h grub-0.96-patched/stage2/gpt.h
+--- grub-0.96/stage2/gpt.h     1969-12-31 19:00:00.000000000 -0500
++++ grub-0.96-patched/stage2/gpt.h     2007-01-04 13:52:14.000000000 -0500
+@@ -0,0 +1,68 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2002,2005,2006   Free Software Foundation, Inc.
++ *
++ *  This program 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 2 of the License, or
++ *  (at your option) any later version.
++ *
++ *  This program 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 this program; if not, write to the Free Software
++ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef _GPT_H
++#define _GPT_H
++
++typedef signed char grub_int8_t;
++typedef signed short grub_int16_t;
++typedef signed int grub_int32_t;
++typedef signed long long int grub_int64_t;
++typedef unsigned char grub_uint8_t;
++typedef unsigned short grub_uint16_t;
++typedef unsigned int grub_uint32_t;
++typedef unsigned long long int grub_uint64_t;
++
++struct grub_gpt_header
++{
++  grub_uint64_t magic;
++  grub_uint32_t version;
++  grub_uint32_t headersize;
++  grub_uint32_t crc32;
++  grub_uint32_t unused1;
++  grub_uint64_t primary;
++  grub_uint64_t backup;
++  grub_uint64_t start;
++  grub_uint64_t end;
++  grub_uint8_t guid[16];
++  grub_uint64_t partitions;
++  grub_uint32_t maxpart;
++  grub_uint32_t partentry_size;
++  grub_uint32_t partentry_crc32;
++} __attribute__ ((packed));
++
++struct grub_gpt_partentry
++{
++  grub_uint64_t type1;
++  grub_uint64_t type2;
++  grub_uint8_t guid[16];
++  grub_uint64_t start;
++  grub_uint64_t end;
++  grub_uint8_t attrib;
++  char name[72];
++} __attribute__ ((packed));
++
++#define GPT_HEADER_MAGIC       0x5452415020494645UL
++
++#define        GPT_ENTRY_SECTOR(size,entry)                                    \
++       ((((entry) * (size) + 1) & ~(SECTOR_SIZE - 1)) >> SECTOR_BITS)
++#define        GPT_ENTRY_INDEX(size,entry)                                     \
++       ((((entry) * (size) + 1) & (SECTOR_SIZE - 1)) - 1)
++
++#endif /* _GPT_H */
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/pc_slice.h grub-0.96-patched/stage2/pc_slice.h
+--- grub-0.96/stage2/pc_slice.h        2003-07-09 07:45:53.000000000 -0400
++++ grub-0.96-patched/stage2/pc_slice.h        2007-01-04 13:52:14.000000000 -0500
+@@ -115,6 +115,7 @@
+ #define PC_SLICE_TYPE_LINUX_EXTENDED  0x85
+ #define PC_SLICE_TYPE_VSTAFS          0x9e
+ #define PC_SLICE_TYPE_DELL_UTIL               0xde
++#define PC_SLICE_TYPE_GPT              0xee
+ #define PC_SLICE_TYPE_LINUX_RAID      0xfd
+ 
+ 
+diff -ruBbd --unidirectional-new-file grub-0.96/stage2/shared.h grub-0.96-patched/stage2/shared.h
+--- grub-0.96/stage2/shared.h  2004-06-19 12:40:09.000000000 -0400
++++ grub-0.96-patched/stage2/shared.h  2007-01-04 13:52:15.000000000 -0500
+@@ -934,7 +934,9 @@
+                   unsigned long *partition, int *type,
+                   unsigned long *start, unsigned long *len,
+                   unsigned long *offset, int *entry,
+-                  unsigned long *ext_offset, char *buf);
++                   unsigned long *ext_offset,
++                   unsigned long *gpt_offset, int *gpt_count,
++                   int *gpt_size, char *buf);
+ 
+ /* Sets device to the one represented by the SAVED_* parameters. */
+ int make_saved_active (void);
diff --git a/sys-boot/grub/grub-0.97-r4.ebuild b/sys-boot/grub/grub-0.97-r4.ebuild
new file mode 100644 (file)
index 0000000..bdde1c9
--- /dev/null
@@ -0,0 +1,164 @@
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/grub-0.97-r4.ebuild,v 1.1 2008/02/25 01:44:37 robbat2 Exp $
+
+inherit mount-boot eutils flag-o-matic toolchain-funcs autotools
+
+PATCHVER="1.4"
+DESCRIPTION="GNU GRUB Legacy boot loader"
+HOMEPAGE="http://www.gnu.org/software/grub/"
+SRC_URI="mirror://gentoo/${P}.tar.gz
+       ftp://alpha.gnu.org/gnu/${PN}/${P}.tar.gz
+       mirror://gentoo/splash.xpm.gz
+       mirror://gentoo/${P}-patches-${PATCHVER}.tar.bz2"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~amd64 ~x86 ~x86-fbsd"
+IUSE="static netboot custom-cflags"
+
+DEPEND=">=sys-libs/ncurses-5.2-r5"
+PROVIDE="virtual/bootloader"
+
+src_unpack() {
+       unpack ${A}
+       cd "${S}"
+
+       # patch breaks booting for some people #111885
+       rm "${WORKDIR}"/patch/400_*
+
+       epatch "${FILESDIR}"/grub-0.97-gpt.patch
+
+       if [[ -n ${PATCHVER} ]] ; then
+               EPATCH_SUFFIX="patch"
+               epatch "${WORKDIR}"/patch
+               eautoreconf
+       fi
+}
+
+src_compile() {
+       filter-flags -fPIE #168834
+
+       use amd64 && multilib_toolchain_setup x86
+
+       unset BLOCK_SIZE #73499
+
+       ### i686-specific code in the boot loader is a bad idea; disabling to ensure
+       ### at least some compatibility if the hard drive is moved to an older or
+       ### incompatible system.
+
+       # grub-0.95 added -fno-stack-protector detection, to disable ssp for stage2,
+       # but the objcopy's (faulty) test fails if -fstack-protector is default.
+       # create a cache telling configure that objcopy is ok, and add -C to econf
+       # to make use of the cache.
+       #
+       # CFLAGS has to be undefined running econf, else -fno-stack-protector detection fails.
+       # STAGE2_CFLAGS is not allowed to be used on emake command-line, it overwrites
+       # -fno-stack-protector detected by configure, removed from netboot's emake.
+       use custom-cflags || unset CFLAGS
+
+       export grub_cv_prog_objcopy_absolute=yes #79734
+       use static && append-ldflags -static
+
+       # build the net-bootable grub first, but only if "netboot" is set
+       if use netboot ; then
+               econf \
+               --libdir=/lib \
+               --datadir=/usr/lib/grub \
+               --exec-prefix=/ \
+               --disable-auto-linux-mem-opt \
+               --enable-diskless \
+               --enable-{3c{5{03,07,09,29,95},90x},cs89x0,davicom,depca,eepro{,100}} \
+               --enable-{epic100,exos205,ni5210,lance,ne2100,ni{50,65}10,natsemi} \
+               --enable-{ne,ns8390,wd,otulip,rtl8139,sis900,sk-g16,smc9000,tiara} \
+               --enable-{tulip,via-rhine,w89c840} || die "netboot econf failed"
+
+               emake w89c840_o_CFLAGS="-O" || die "making netboot stuff"
+
+               mv -f stage2/{nbgrub,pxegrub} "${S}"/
+               mv -f stage2/stage2 stage2/stage2.netboot
+
+               make clean || die "make clean failed"
+       fi
+
+       # Now build the regular grub
+       # Note that FFS and UFS2 support are broken for now - stage1_5 files too big
+       econf \
+               --libdir=/lib \
+               --datadir=/usr/lib/grub \
+               --exec-prefix=/ \
+               --disable-auto-linux-mem-opt || die "econf failed"
+       emake || die "making regular stuff"
+}
+
+src_test() {
+       # non-default block size also give false pass/fails.
+       unset BLOCK_SIZE
+       make check || die "make check failed"
+}
+
+src_install() {
+       make DESTDIR="${D}" install || die
+       if use netboot ; then
+               exeinto /usr/lib/grub/${CHOST}
+               doexe nbgrub pxegrub stage2/stage2.netboot || die "netboot install"
+       fi
+
+       insinto /boot/grub
+       doins "${DISTDIR}"/splash.xpm.gz
+       newins docs/menu.lst grub.conf.sample
+
+       dodoc AUTHORS BUGS ChangeLog NEWS README THANKS TODO
+       newdoc docs/menu.lst grub.conf.sample
+}
+
+setup_boot_dir() {
+       local dir="${1}"
+
+       [[ ! -e ${dir} ]] && die "${dir} does not exist!"
+       [[ ! -e ${dir}/grub ]] && mkdir "${dir}/grub"
+
+       # change menu.lst to grub.conf
+       if [[ ! -e ${dir}/grub/grub.conf ]] && [[ -e ${dir}/grub/menu.lst ]] ; then
+               mv -f "${dir}"/grub/menu.lst "${dir}"/grub/grub.conf
+               ewarn
+               ewarn "*** IMPORTANT NOTE: menu.lst has been renamed to grub.conf"
+               ewarn
+       fi
+
+       if [[ ! -e ${dir}/grub/menu.lst ]]; then
+       einfo "Linking from new grub.conf name to menu.lst"
+               ln -snf grub.conf "${dir}"/grub/menu.lst
+       fi
+
+       [[ -e ${dir}/grub/stage2 ]] && mv "${dir}"/grub/stage2{,.old}
+
+       einfo "Copying files from /lib/grub and /usr/lib/grub to "${dir}""
+       for x in /lib*/grub/*/* /usr/lib*/grub/*/* ; do
+               [[ -f ${x} ]] && cp -p ${x} "${dir}"/grub/
+       done
+
+       if [[ -e ${dir}/grub/grub.conf ]] ; then
+               egrep \
+                       -v '^[[:space:]]*(#|$|default|fallback|initrd|password|splashimage|timeout|title)' \
+                       "${dir}"/grub/grub.conf | \
+               /sbin/grub --batch \
+                       --device-map="${dir}"/grub/device.map \
+                       > /dev/null
+       fi
+}
+
+pkg_postinst() {
+       [[ ${ROOT} != "/" ]] && return 0
+       [[ -n ${DONT_MOUNT_BOOT} ]] && return 0
+       setup_boot_dir /boot
+       einfo "To install grub files to another device (like a usb stick), just run:"
+       einfo "   emerge --config =${PF}"
+}
+
+pkg_config() {
+       local dir
+       einfo "Enter the directory where you want to setup grub:"
+       read dir
+       setup_boot_dir ${dir}
+}