Hi, All

I am glad that I have finally made the grub2 multiboot for ppc working. It is based on Hollis' earlier work (http://lists.gnu.org/archive/html/grub-devel/2005-06/msg00049.html) . Hollis' hello world example works for my building environment and system, which is Mandrake Linux (2.6.11) on Power Mac G4. A patch is attached for grub 1.92 release. The patch also includes the util/powerpc/ieee1275/grub-install.in file, which is missed in 1.92 release (but in cvs checkout). I have trouble to create the patch by cvs diff, so to apply it, you may have to use "patch -p1" under the grub2 folder. 

grub2 is really great and it is very easy to write a module that loads a kernel and jump to it for run.

As in x86 and sparc, the multiboot strap is basically not the real kernel, but a loader to load ramdisk and initializer of system before exitto unix module. Here comes several choices about the system initialization:

1. should the multiboot strap trust the multiboot_info passed from grub? x86 multiboot only use the cmdline of it and multiboot is changing as from grub developers.  If use it, it may save some coding efforts.

2. if multiboot strap collect system information by itself, should it use GRUB ieee1275 functions or Solaris's own code(mainly in psm/promif/ieee1275, but would have to port to ppc). Using Grub2's code saves efforts to port Solaris code.

3. grub2 network is not available (Marco planned to work on it on Feb as posted from grub wiki), shall we port the solaris network stack (src/stand/lib) for grub or wait?

4. Finally, should the boot strap be independent from Grub? so that it can be loaded by other loaders, such as yaboot?

5. Does a user allowed to get back to open firmware prompt (like sparc Stop + A key), or grub prompt after system is up? this feature may be used for file system synchronization or core dumping after system hang. (this does not matter in current stage, doe it :)

In summary, what is the role the grub should play in booing and system initialization, only as a loader, or a loader and system utilities that help system booting and other purpose? In Solaris x86, I only found the cmdline of multiboot_info is used by the multiboot strap.

Thanks for reading through this and hope that some of them are important and worthwhile to discuss.
Noah Yan




diff -r -u -p -N grub-1.92/conf/powerpc-ieee1275.rmk grub-1.92ppcmtb/conf/powerpc-ieee1275.rmk
--- grub-1.92/conf/powerpc-ieee1275.rmk	2005-12-25 10:00:34.000000000 -0600
+++ grub-1.92ppcmtb/conf/powerpc-ieee1275.rmk	2005-12-30 09:02:06.000000000 -0600
@@ -86,7 +86,9 @@ pkgdata_MODULES = halt.mod \
 	linux.mod \
 	normal.mod \
 	reboot.mod \
-	suspend.mod
+	suspend.mod \
+	_multiboot.mod \
+	multiboot.mod
 
 # For _linux.mod.
 _linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
@@ -117,4 +119,12 @@ reboot_mod_CFLAGS = $(COMMON_CFLAGS)
 halt_mod_SOURCES = commands/ieee1275/halt.c
 halt_mod_CFLAGS = $(COMMON_CFLAGS)
 
+# For _mulitboot.mod
+_multiboot_mod_SOURCES = loader/powerpc/ieee1275/multiboot.c
+_multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+
+# For multiboot.mod
+multiboot_mod_SOURCES = loader/powerpc/ieee1275/multiboot_normal.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+
 include $(srcdir)/conf/common.mk
diff -r -u -p -N grub-1.92/include/grub/powerpc/ieee1275/loader.h grub-1.92ppcmtb/include/grub/powerpc/ieee1275/loader.h
--- grub-1.92/include/grub/powerpc/ieee1275/loader.h	2005-01-31 15:44:35.000000000 -0600
+++ grub-1.92ppcmtb/include/grub/powerpc/ieee1275/loader.h	2005-12-30 09:02:06.000000000 -0600
@@ -30,4 +30,8 @@ void grub_linux_fini (void);
 void grub_linux_normal_init (void);
 void grub_linux_normal_fini (void);
 
+/* for multiboot powerpc */
+void grub_rescue_cmd_multiboot (int argc, char *argv[]);
+void grub_rescue_cmd_module (int argc, char *argv[]);
+
 #endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff -r -u -p -N grub-1.92/loader/powerpc/ieee1275/multiboot.c grub-1.92ppcmtb/loader/powerpc/ieee1275/multiboot.c
--- grub-1.92/loader/powerpc/ieee1275/multiboot.c	1969-12-31 18:00:00.000000000 -0600
+++ grub-1.92ppcmtb/loader/powerpc/ieee1275/multiboot.c	2005-12-30 09:02:06.000000000 -0600
@@ -0,0 +1,397 @@
+/* multiboot.c - boot a multiboot OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005  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.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/dl.h>
+#include <grub/machine/multiboot.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/elf.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/rescue.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+static grub_dl_t my_mod;
+static struct grub_multiboot_info *mbi;
+static grub_addr_t entry;
+
+typedef void (*kernel_entry_t) (struct grub_multiboot_info *, unsigned long,
+                               void *);
+
+static grub_err_t
+grub_multiboot_boot (void)
+{
+  kernel_entry_t kernel;
+
+  grub_dprintf ("loader", "Jumping to entry point: 0x%x\n", entry);
+
+  kernel = (kernel_entry_t) entry;
+  kernel (mbi, GRUB_MB_MAGIC2, grub_ieee1275_entry_fn);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_multiboot_unload (void)
+{
+  if (mbi)
+    {
+      unsigned int i;
+      for (i = 0; i < mbi->mods_count; i++)
+       {
+         grub_free ((void *)
+                    ((struct grub_mod_list *) mbi->mods_addr)[i].mod_start);
+         grub_free ((void *)
+                    ((struct grub_mod_list *) mbi->mods_addr)[i].cmdline);
+       }
+      grub_free ((void *) mbi->mods_addr);
+      grub_free ((void *) mbi->cmdline);
+      grub_free (mbi);
+    }
+
+
+  mbi = 0;
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_ieee1275_mbi_memory (struct grub_multiboot_info *info)
+{
+  grub_ieee1275_phandle_t memory;
+  struct grub_ieee1275_mem_region regions[4]; /* XXX Don't hardcode me.  */
+  int i;
+
+  /* XXX Examine all memory nodes, not just the first.  */
+  if (-1 == grub_ieee1275_finddevice ("/memory", &memory))
+    return;
+
+  if (0 != grub_ieee1275_get_property (memory, "reg", &regions, sizeof regions, 0))
+    return;
+
+  info->mem_lower = 0;
+  info->mem_upper = 0;
+
+  for (i = 0; i < 4; i++)
+    info->mem_lower += regions[i].size;
+
+  grub_dprintf ("loader", "multiboot.mem_lower = 0x%x\n", info->mem_lower);
+
+  info->flags |= GRUB_MB_INFO_MEMORY;
+}
+
+static void
+grub_ieee1275_mbi_cmdline (struct grub_multiboot_info *info, int argc, char *argv[])
+{
+  char *cmdline;
+  char *p;
+  int i;
+  int len;
+
+  for (i = 0, len = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+
+  cmdline = p = grub_malloc (len);
+  if (!cmdline)
+    return;
+
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  *(--p) = '\0';
+
+  info->cmdline = (grub_uint32_t) cmdline;
+  grub_dprintf ("loader", "multiboot.cmdline = 0x%x\n", info->cmdline);
+
+  info->flags |= GRUB_MB_INFO_CMDLINE;
+}
+
+void
+grub_rescue_cmd_multiboot (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  char buffer[GRUB_MB_SEARCH];
+  struct grub_multiboot_header *header;
+  grub_ssize_t len;
+  grub_size_t size;
+  int i;
+  Elf32_Ehdr *ehdr;
+
+  grub_dl_ref (my_mod);
+
+  grub_loader_unset();
+    
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (!file)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
+      goto fail;
+    }
+
+  len = grub_file_read (file, buffer, GRUB_MB_SEARCH);
+  if (len < 32)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "File too small");
+      goto fail;
+    }
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 12 bytes and aligned on a 4-byte boundary.  */
+  for (header = (struct grub_multiboot_header *) buffer; 
+       ((char *) header <= buffer + len - 12) || (header = 0);
+       header = (struct grub_multiboot_header *) ((char *)header + 4))
+    {
+      if (header->magic == GRUB_MB_MAGIC 
+         && !(header->magic + header->flags + header->checksum))
+         break;
+    }
+  
+  if (header == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No multiboot header found");
+      goto fail;
+    }
+
+  if (header->flags & GRUB_MB_UNSUPPORTED)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS, "Unsupported flag: 0x%x", header->flags);
+      goto fail;
+    }
+
+  ehdr = (Elf32_Ehdr *) buffer;
+
+  if (grub_dl_check_header (ehdr, sizeof(*ehdr)))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS, "No valid ELF header found");
+      goto fail;
+    }
+
+  if (ehdr->e_type != ET_EXEC)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+      goto fail;
+    }
+
+  /* FIXME: Should we support program headers at strange locations?  */
+  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_MB_SEARCH)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS, "Program header at a too high offset");
+      goto fail;
+    }
+
+  /* Determine the amount of memory that is required.  */
+  /* XXX discontiguous segments */
+  size = 0;
+  for (i = 0; i < ehdr->e_phnum; i++)
+    {
+      Elf32_Phdr *phdr;
+      phdr = (Elf32_Phdr *) (buffer + ehdr->e_phoff + i * ehdr->e_phentsize);
+
+      size += phdr->p_memsz;
+    }
+  if (-1 == grub_claimmap (ehdr->e_entry, size))
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%x bytes at 0x%x\n",
+                 size, ehdr->e_entry);
+      goto fail;
+    }
+
+  entry = ehdr->e_entry;
+
+  /* Load every loadable segment in memory.  */
+  for (i = 0; i < ehdr->e_phnum; i++)
+    {
+      Elf32_Phdr *phdr;
+      phdr = (Elf32_Phdr *) (buffer + ehdr->e_phoff + i * ehdr->e_phentsize);
+
+      if (phdr->p_type == PT_LOAD)
+       {
+         if (grub_file_seek (file, phdr->p_offset) == -1)
+           {
+             grub_error (GRUB_ERR_BAD_OS, "Invalid offset in program header");
+             goto fail;
+           }
+
+         grub_dprintf ("loader", "Loading segment %d at 0x%x, size 0x%x\n", i,
+                       phdr->p_paddr, phdr->p_filesz);
+
+         if (grub_file_read (file, (void *) phdr->p_paddr, phdr->p_filesz) 
+             != (grub_ssize_t) phdr->p_filesz)
+           {
+             grub_error (GRUB_ERR_BAD_OS, "Couldn't read segment from file");
+             goto fail;
+           }
+
+         if (phdr->p_filesz < phdr->p_memsz)
+           grub_memset ((char *) phdr->p_paddr + phdr->p_filesz, 0, 
+                        phdr->p_memsz - phdr->p_filesz);
+       }
+    }
+
+  mbi = grub_malloc (sizeof (struct grub_multiboot_info));
+  if (!mbi)
+    goto fail;
+
+  mbi->flags = 0;
+
+  grub_ieee1275_mbi_memory (mbi);
+  grub_ieee1275_mbi_cmdline (mbi, argc, argv);
+
+  mbi->flags |= GRUB_MB_INFO_BOOT_LOADER_NAME;
+  mbi->boot_loader_name = (grub_uint32_t) grub_strdup (PACKAGE_STRING);
+
+  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload);
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (mbi);
+      grub_dl_unref (my_mod);
+    }
+}
+
+void
+grub_rescue_cmd_module  (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size, len = 0;
+  char *module = 0, *cmdline = 0, *p;
+  int i;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+
+  if (!mbi)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the multiboot kernel first");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (!file)
+    goto fail;
+
+  size = grub_file_size (file);
+  module = grub_memalign (GRUB_MB_MOD_ALIGN, size);
+  if (!module)
+    goto fail;
+
+  grub_dprintf ("loader", "Loading module %s at %p, size 0x%x\n", argv[0],
+               module, size);
+
+  if (grub_file_read (file, module, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+  
+  for (i = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+  
+  cmdline = p = grub_malloc (len);
+  if (!cmdline)
+    goto fail;
+  
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+  
+  /* Remove the space after the last word.  */
+  *(--p) = '\0';
+
+  if (mbi->flags & GRUB_MB_INFO_MODS)
+    {
+      struct grub_mod_list *modlist = (struct grub_mod_list *) mbi->mods_addr;
+
+      modlist = grub_realloc (modlist, (mbi->mods_count + 1) * sizeof (struct grub_mod_list));
+
+      if (!modlist)
+       goto fail;
+      mbi->mods_addr = (grub_uint32_t) modlist;
+      modlist += mbi->mods_count;
+      modlist->mod_start = (grub_uint32_t) module;
+      modlist->mod_end = (grub_uint32_t) module + size;
+      modlist->cmdline = (grub_uint32_t) cmdline;
+      modlist->pad = 0;
+      mbi->mods_count++;
+    }
+  else
+    {
+      struct grub_mod_list *modlist = grub_malloc (sizeof (struct grub_mod_list));
+      if (!modlist)
+       goto fail;
+      modlist->mod_start = (grub_uint32_t) module;
+      modlist->mod_end = (grub_uint32_t) module + size;
+      modlist->cmdline = (grub_uint32_t) cmdline;
+      modlist->pad = 0;
+      mbi->mods_count = 1;
+      mbi->mods_addr = (grub_uint32_t) modlist;
+      mbi->flags |= GRUB_MB_INFO_MODS;
+    }
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (module);
+      grub_free (cmdline);
+    }
+}
+
+
+GRUB_MOD_INIT(multiboot)
+{
+  grub_rescue_register_command ("multiboot", grub_rescue_cmd_multiboot,
+                               "load a multiboot kernel");
+  grub_rescue_register_command ("module", grub_rescue_cmd_module,
+                               "load a multiboot module");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(multiboot)
+{
+  grub_rescue_unregister_command ("multiboot");
+  grub_rescue_unregister_command ("module");
+}
+
diff -r -u -p -N grub-1.92/loader/powerpc/ieee1275/multiboot_normal.c grub-1.92ppcmtb/loader/powerpc/ieee1275/multiboot_normal.c
--- grub-1.92/loader/powerpc/ieee1275/multiboot_normal.c	1969-12-31 18:00:00.000000000 -0600
+++ grub-1.92ppcmtb/loader/powerpc/ieee1275/multiboot_normal.c	2005-12-30 09:02:06.000000000 -0600
@@ -0,0 +1,65 @@
+// loader/powerpc/ieee1275/multiboot_normal.c  2005-06-23 21:15:03.000000000 
+/* multiboot_normal.c - boot another boot loader */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004  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.
+ */
+
+#include <grub/machine/loader.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+
+static grub_err_t
+grub_normal_cmd_multiboot (struct grub_arg_list *state __attribute__ 
+((unused)),
+                          int argc, char **args)
+{
+  grub_rescue_cmd_multiboot (argc, args);
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)),
+                       int argc, char **args)
+{
+  grub_rescue_cmd_module (argc, args);
+  return grub_errno;
+}
+
+GRUB_MOD_INIT(multiboot_normal)
+{
+  (void) mod; /* To stop warning.  */
+  grub_register_command ("multiboot", grub_normal_cmd_multiboot,
+                        GRUB_COMMAND_FLAG_BOTH | 
+			GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+                        "multiboot FILE [ARGS...]",
+                        "Load a multiboot kernel", 0);
+  
+  grub_register_command ("module", grub_normal_cmd_module,
+                        GRUB_COMMAND_FLAG_BOTH | 
+			GRUB_COMMAND_FLAG_NO_ARG_PARSE,
+                        "module FILE [ARGS...]",
+                        "Load a multiboot module", 0);
+}
+
+GRUB_MOD_FINI(multiboot_normal)
+{
+  grub_unregister_command ("multiboot");
+  grub_unregister_command ("module");
+}
diff -r -u -p -N grub-1.92/util/powerpc/ieee1275/grub-install.in grub-1.92ppcmtb/util/powerpc/ieee1275/grub-install.in
--- grub-1.92/util/powerpc/ieee1275/grub-install.in	1969-12-31 18:00:00.000000000 -0600
+++ grub-1.92ppcmtb/util/powerpc/ieee1275/grub-install.in	2005-12-30 09:21:43.000000000 -0600
@@ -0,0 +1,189 @@
+#! /bin/sh
+
+# Install GRUB on your drive.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
+#
+# This file 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., 51 Franklin St - Suite 330, Boston, MA 02110, USA.
+
+# This script uses `ofpathname', which is downloadable from
+# http://ppc64-utils.ozlabs.org .
+
+# Initialize some variables.
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
+pkgdatadir=${datadir}/${PACKAGE_TARNAME}/${host_cpu}-${host_vendor}
+
+grub_mkimage=${sbindir}/grub-mkimage
+rootdir=
+grub_prefix=/boot/grub
+modules=
+
+install_device=
+debug=no
+update_nvram=yes
+
+ofpathname=/usr/sbin/ofpathname
+nvsetenv=/sbin/nvsetenv
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-install [OPTION] [install_device]
+Install GRUB on your drive.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --modules=MODULES       pre-load specified modules MODULES
+  --root-directory=DIR    install GRUB images under the directory DIR
+                          instead of the root directory
+  --grub-mkimage=FILE     use FILE as grub-mkimage
+  --no-nvram              don't update the boot-device NVRAM variable
+
+grub-install copies GRUB images into the DIR/boot directory specfied by
+--root-directory, and uses nvsetenv to set the Open Firmware boot-device
+variable.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
+	exit 0 ;;
+    --modules=*)
+	modules=`echo "$option" | sed 's/--modules=//'` ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    --grub-mkimage=*)
+	grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+    --no-nvram)
+	update_nvram=no ;;
+    # This is an undocumented feature...
+    --debug)
+	debug=yes ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$install_device" != x; then
+	    echo "More than one install_devices?" 1>&2
+	    usage
+	    exit 1
+	fi
+	install_device="${option}" ;;
+    esac
+done
+
+# If the debugging feature is enabled, print commands.
+if test $debug = yes; then
+    set -x
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+bootdir=${rootdir}/boot
+grubdir=${bootdir}/grub
+
+set $grub_mkimage dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+# Find the partition at the right mount point.
+install_device=`awk '$2 == '"\"$grubdir\""' { print $1 }' < /proc/mounts`
+if test "x$install_device" = x; then
+    echo "$grubdir must be a mount point."
+    exit 1
+fi
+# XXX warn on firmware-unreadable filesystems?
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# Copy the GRUB images to the GRUB directory.
+for file in ${grubdir}/*.mod ${grubdir}/*.lst ; do
+    if test -f $file; then
+	rm -f $file || exit 1
+    fi
+done
+for file in ${pkgdatadir}/*.mod ${pkgdatadir}/*.lst ; do
+    cp -f $file ${grubdir} || exit 1
+done
+
+# Create the core image with all modules, unless user specified a subset.
+# XXX probe for partition map and filesystem?
+if test "x$modules" = x; then
+    modules="$pkgdatadir"/*.mod
+fi
+
+# Now perform the installation.
+"$grub_mkimage" --output=${grubdir}/grub $modules || exit 1
+
+if test $update_nvram = yes; then
+    set $ofpathname dummy
+    if test -f "$1"; then
+	:
+    else
+	echo "$1: Not found." 1>&2
+	exit 1
+    fi
+
+    set $nvsetenv dummy
+    if test -f "$1"; then
+	:
+    else
+	echo "$1: Not found." 1>&2
+	exit 1
+    fi
+
+    # Get the Open Firmware device tree path translation.
+    dev=`echo $install_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`
+    partno=`echo $install_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'`
+    ofpath=`$ofpathname $dev` || {
+	echo "Couldn't find Open Firmware device tree path for $dev."
+	echo "You will have to set boot-device manually."
+	exit 1
+    }
+
+    # Point boot-device at the new grub install
+    "$nvsetenv" boot-device "$ofpath:$partno,"'\grub' || {
+	echo "$nvsetenv failed."
+	echo "You will have to set boot-device manually."
+	exit 1
+    }
+fi
+
+# Bye.
+exit 0
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to