On 30.01.2012 03:37, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
Hello, all. It was a Robert's idea of having grub-install to install all available (as in: the ones which were make install'ed) ports in a single grub-install w/o having to keep and run one grub-install per port.
I've tried to write such a thing. I have  met some problems in practice:
- I wanted also to integrate mactelbless in the same time. Unfortunately Apple uses the same pointer for both i386 and x86_64 efi. So hfs(+) partitions can hold only either 32-bit or 64-bit EFI binary. We could use "FAT Binary" to workaround this but not all macs support this. - If one of platform specific installs fail the script doesn't install other platforms. - When modifying nvram on EFI where to point it to? ESP or HFS? This is easy: HFS if it's a mac and ESP otherwise. Or just always ESP. - The same problem for ieee1275. While distinguishing between mac and non-mac is easy (check vendor string), I don't know how to distinguish the ones using PreP partition and the ones using a file on a FAT fs. I would appreciate any input both on these specific problems and the idea in general. Perhaps it's better to abandon it and have something easier like auto-detect firmware and use it as default and specify it manually if you need a different install. The attached patch is just a small illustration to discuss about. It doesn't work
This has an advantage of making the disk bootable in various ways including ability to move it from one computer to another. The first problem is the files collision. To resolve this the modification will be to load modules from $prefix/$cpu-$platform/$modname.mod. Also 2 new script constants will be defined: $cpu and $platform. The problem then is that different firmwares require different kind of arrangements in order to be bootable. i386-pc requires 55AA signature, some code in MBR and embedding zone. A dummy msdos active partition is required on some systems.
*-efi require files on ESP and some nvram entries
i386-qemu, i386-coreboot, i386-qemu_mips and loongsoon-firmware are firmware ports and we don't use grub-install for those but grub-mkstandalone.
i386-multiboot just has to be readable by whatever is a coreboot payload.
mipsel-loongson has to be on ext2 msdos partition.
sparc64 requires SUN partition map and the code in sector 1
Powerpc (Apple) requires a file on HFS and nvram modification
PowerPC (IBM) uses PreP partition
ARC uses a special entry in the dvh partition table
I have no idea what i386-ieee1275 requires but I guess it's a fat partition with special file + nvram modification.

So I propose following strategy: grub-install does the following platform-specific installations: - if /boot/efi is on fat, copy grub to /boot/efi/efi/$boot_id/grub[ia32|x64|ia64].efi (replace $boot_id and grub with boot if --removable is specified) and update nvram if no --removable is specified and currently running EFI version matches the installed one. - if /boot/mac is on HFS or HFS+, create there a structure recognized by both PPC and Intel macs and update nvram if architecture matches
- If /boot/ext2 is on ext*, put mipsel-loongson and i386-multiboot there.
- If /boot/olpc is on fat, install i386-ieee1275 there and update nvram if architecture matches. - For every argument that is an msdos or gpt disk, install i386-pc bootsector.
- For every argument that is a sun disk, install sun bootsector.
- For every argument that is a dvh disk, install mips-arc.
- For every argument that is a prep partition install powerpc-ieee1275

While the copying to partitions is harmless and updating nvram is done only if architecture and platform matches, the disk operations may be harmful. While none of the current 4 configuration usually come in contradictory combinations, it's possible to purposedly create a disk of multiple types and it will confuse this logic. Also if we throw e.g. hppa into the mix which requires just a signature on bytes 0-1 and some info in 0xf4-0xff then we can't know if msdos disk is for BIOS or hppa install. So we need a way to specify them more precisely. PreP and ARC came in only after 1.99 so we can make them accept only the new way whatever it will be. In case of old way we can easily distinguish sparc64-ieee1275 and i386-pc with e.g. uname -i. I propose either of: --device-bios=/dev/xyz --device-sun=/dev/xyz --device-arc=/dev/xyz --device-prep=/dev/xyz
Or: bios:/dev/xyz sun:/dev/xyz arc:/dev/xyz prep:/dev/xyz

Also it may happen that installation of some port is undesirable. So we need options
--install-only=...
--exclude=...
Any further ideas?



--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

=== modified file 'Makefile.util.def'
--- Makefile.util.def	2012-01-29 13:28:01 +0000
+++ Makefile.util.def	2012-02-01 17:43:10 +0000
@@ -309,39 +309,51 @@
 };
 
 program = {
-  name = grub-setup;
-  installdir = sbin;
-  mansection = 8;
-  common = util/grub-setup.c;
-  common = util/lvm.c;
-  common = grub-core/lib/reed_solomon.c;
-
-  sparc64_ieee1275 = util/ieee1275/ofpath.c;
-
-  ldadd = libgrubmods.a;
-  ldadd = libgrubkern.a;
-  ldadd = libgrubgcry.a;
-  ldadd = grub-core/gnulib/libgnu.a;
-  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
-
-  enable = i386_pc;
-  enable = sparc64_ieee1275;
+  name = grub-bios-setup;
+  installdir = sbin;
+  mansection = 8;
+  common = util/grub-setup.c;
+  common = util/lvm.c;
+  common = grub-core/lib/reed_solomon.c;
+
+  ldadd = libgrubmods.a;
+  ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
+  ldadd = grub-core/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
+  cppflags = '-DGRUB_SETUP_BIOS=1';
+};
+
+program = {
+  name = grub-sparc64-setup;
+  installdir = sbin;
+  mansection = 8;
+  common = util/grub-setup.c;
+  common = util/lvm.c;
+  common = grub-core/lib/reed_solomon.c;
+
+  common = util/ieee1275/ofpath.c;
+
+  ldadd = libgrubmods.a;
+  ldadd = libgrubkern.a;
+  ldadd = libgrubgcry.a;
+  ldadd = grub-core/gnulib/libgnu.a;
+  ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
+  cppflags = '-DGRUB_SETUP_SPARC64=1';
 };
 
 program = {
   name = grub-ofpathname;
   installdir = sbin;
   mansection = 8;
-  ieee1275 = util/ieee1275/grub-ofpathname.c;
-  ieee1275 = util/ieee1275/ofpath.c;
+  common = util/ieee1275/grub-ofpathname.c;
+  common = util/ieee1275/ofpath.c;
 
   ldadd = libgrubmods.a;
   ldadd = libgrubgcry.a;
   ldadd = libgrubkern.a;
   ldadd = grub-core/gnulib/libgnu.a;
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBGEOM)';
-
-  enable = sparc64_ieee1275;
 };
 
 program = {
@@ -461,7 +473,6 @@
   name = grub-install;
 
   common = util/grub-install.in;
-  enable = noemu;
 };
 
 script = {

=== modified file 'configure.ac'
--- configure.ac	2012-01-22 15:43:14 +0000
+++ configure.ac	2012-02-01 17:49:57 +0000
@@ -187,9 +187,6 @@
 AC_SUBST(host_os)
 AC_SUBST(host_kernel)
 
-AC_SUBST(target_cpu)
-AC_SUBST(platform)
-
 # Define default variables
 case "$host_os" in
   netbsd* | openbsd*)

=== modified file 'util/grub-install.in'
--- util/grub-install.in	2012-01-27 12:12:00 +0000
+++ util/grub-install.in	2012-02-01 20:09:51 +0000
@@ -29,16 +29,13 @@
 PACKAGE_NAME=@PACKAGE_NAME@
 PACKAGE_TARNAME=@PACKAGE_TARNAME@
 PACKAGE_VERSION=@PACKAGE_VERSION@
-target_cpu=@target_cpu@
-platform=@platform@
-host_os=@host_os@
-pkglibdir="${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`"
 datadir="@datadir@"
 localedir="@datadir@/locale"
 
 self="`basename $0`"
 
-grub_setup="${sbindir}/`echo grub-setup | sed ${transform}`"
+grub_setup_bios="${sbindir}/`echo grub-setup-bios | sed ${transform}`"
+grub_setup_sparc64="${sbindir}/`echo grub-setup-sparc64 | sed ${transform}`"
 grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`"
 grub_mkdevicemap="${sbindir}/`echo grub-mkdevicemap | sed ${transform}`"
 grub_probe="${sbindir}/`echo grub-probe | sed ${transform}`"
@@ -61,6 +58,10 @@
 removable=no
 efi_quiet=
 
+plaforms="i386-pc i386-efi i386-qemu i386-coreboot i386-multiboot \
+i386-ieee1275 x86_64-efi mipsel-loongson sparc64-ieee1275 \
+powerpc-ieee1275 mips-arc ia64-efi mips-qemu_mips mipsel-qemu_mips"
+
 # Get GRUB_DISTRIBUTOR.
 if test -f "${sysconfdir}/default/grub" ; then
     . "${sysconfdir}/default/grub"
@@ -71,14 +72,6 @@
     bootloader_id=grub
 fi
 
-if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
-    disk_module=biosdisk
-elif [ "${platform}" = "ieee1275" ] || [ "${platform}" = "efi" ] ; then
-    disk_module=
-else
-    disk_module=native
-fi
-
 # Usage: usage
 # Print the usage.
 usage () {
@@ -150,6 +143,10 @@
 }
 
 allow_floppy=""
+bios_devices=""
+sparc64_devices=""
+prep_devices=""
+arc_devices=""
 
 # Check the arguments.
 while test $# -gt 0
@@ -170,6 +167,11 @@
     --modules=*)
 	modules=`echo "$option" | sed 's/--modules=//'` ;;
 
+    --platforms)
+	platforms=`argument $option "$@"`; shift;;
+    --platforms=*)
+	platforms=`echo "$option" | sed 's/--platforms=//'` ;;
+
 # Accept and ignore for compatibility
     --font)
         shift;;
@@ -188,9 +190,37 @@
 	bootdir="`echo "$option" | sed 's/--boot-directory=//'`" ;;
 
     --grub-setup)
-	grub_setup="`argument "$option" "$@"`"; shift;;
-    --grub-setup=*)
-	grub_setup="`echo "$option" | sed 's/--grub-setup=//'`" ;;
+	echo "WARNING: please use --grub-setup-<platform> option"
+        case x`uname -m` in
+	    xsparc64)
+		grub_setup_sparc64="${option}";;
+	    xi?86 | xx86_64)
+		grub_setup_bios="${option}";;
+	    *)
+		echo "Unknown platform"
+		exit 1
+	esac
+	shift;;
+    --grub-setup-bios=*)
+	echo "WARNING: please use --grub-setup-<platform> option"
+        case x`uname -m` in
+	    xsparc64)
+		grub_setup_sparc64="`echo "$option" | sed 's/--grub-setup=//'`";;
+	    xi?86 | xx86_64)
+		grub_setup_bios="`echo "$option" | sed 's/--grub-setup=//'`";;
+	    *)
+		echo "Unknown platform"
+		exit 1
+	esac
+	;;
+    --grub-setup-bios)
+	grub_setup_bios="`argument "$option" "$@"`"; shift;;
+    --grub-setup-bios=*)
+	grub_setup_bios="`echo "$option" | sed 's/--grub-setup-bios=//'`" ;;
+    --grub-setup-sparc64)
+	grub_setup_sparc64="`argument "$option" "$@"`"; shift;;
+    --grub-setup-sparc64=*)
+	grub_setup_sparc64="`echo "$option" | sed 's/--grub-setup-sparc64=//'`" ;;
 
     --bootloader-id)
 	bootloader_id="`argument $option "$@"`"; shift;;
@@ -255,32 +285,34 @@
 	usage
 	exit 1
 	;;
+    bios:*)
+	    bios_devices="$bios_devices `echo "$option" | sed 's/bios://'`"
+	    ;;
+    sparc64:*)
+	    sparc64_devices="$sparc64_devices `echo "$option" | sed 's/sparc64://'`"
+	    ;;
+    prep:*)
+	    prep_devices="$prep_devices `echo "$option" | sed 's/prep://'`"
+	    ;;
+    arc:*)
+	    arc_devices="$arc_devices `echo "$option" | sed 's/arc://'`"
+	    ;;
     *)
-	if test "x$install_device" != x; then
-	    echo "More than one install_devices?" 1>&2
-	    usage
-	    exit 1
-	fi
-	install_device="${option}" ;;
+	echo "WARNING: please prefix the install device with platform name"
+        case x`uname -m` in
+	    xsparc64)
+		sparc64_devices="$sparc64_devices ${option}";;
+	    xi?86 | xx86_64)
+		bios_devices="$bios_devices ${option}";;
+	    *)
+		echo "Unknown platform"
+		exit 1
+	esac
     esac
 done
 
 . "${datadir}/@PACKAGE@/grub-mkconfig_lib"
 
-if test "x$install_device" = x && ([ "${target_cpu}-${platform}" = "i386-pc" ] \
-    || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ]); then
-    echo "install_device not specified." 1>&2
-    usage
-    exit 1
-fi
-
-if ! ([ "${target_cpu}-${platform}" = "i386-pc" ] \
-    || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] \
-    || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ] \
-    || [ "${target_cpu}-${platform}" = "mips-arc" ]); then
-    install_device=
-fi
-
 # If the debugging feature is enabled, print commands.
 setup_verbose=
 if test x"$debug" = xyes; then
@@ -302,18 +334,7 @@
 grubdir="`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'`"
 device_map="${grubdir}/device.map"
 
-
 # Check if GRUB is installed.
-if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then
-    set $grub_setup dummy
-    if test -f "$1"; then
-        :
-    else
-        echo "$1: Not found." 1>&2
-        exit 1
-    fi
-fi
-
 set "$grub_mkimage" dummy
 if test -f "$1"; then
     :
@@ -322,110 +343,95 @@
     exit 1
 fi
 
-set "$grub_mkdevicemap" dummy
-if test -f "$1"; then
-    :
-else
-    echo "$1: Not found." 1>&2
-    exit 1
-fi
-
-if [ x"$platform" = xefi ]; then
-    # Find the EFI System Partition.
-    efidir=
-    if test -d "${bootdir}/efi"; then
-	install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}/efi"`"
-        # Is it a mount point?
-	if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}"`"; then
-	    efidir="${bootdir}/efi"
-	fi
-    elif test -d "${bootdir}/EFI"; then
-	install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}/EFI"`"
-        # Is it a mount point?
-	if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}"`"; then
-	    efidir="${bootdir}/EFI"
-	fi
-    elif test -n "$rootdir" && test "x$rootdir" != "x/"; then
+set "$grub_setup_bios" dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+set "$grub_setup_sparc64" dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+# Find the EFI System Partition.
+efidir=
+if test -d "${bootdir}/efi"; then
+    efi_device="`"$grub_probe" --target=device --device-map= "${bootdir}/efi"`"
+        # Is it a mount point?
+    if test "x$efi_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then
+	efidir="${bootdir}/efi"
+    fi
+elif test -d "${bootdir}/EFI"; then
+    efi_device="`"$grub_probe" --target=device --device-map= "${bootdir}/EFI"`"
+        # Is it a mount point?
+    if test "x$efi_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then
+	efidir="${bootdir}/EFI"
+    fi
+elif test -n "$rootdir" && test "x$rootdir" != "x/"; then
         # The EFI System Partition may have been given directly using
         # --root-directory.
-	install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${rootdir}"`"
-        # Is it a mount point?
-	if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${rootdir}/.."`"; then
-	    efidir="${rootdir}"
-	fi
-    fi
-    
-    if test -n "$efidir"; then
-	efi_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${efidir}"`
-	if test "x$efi_fs" = xfat; then :; else
-	    echo "${efidir} doesn't look like an EFI partition." 1>&2
-	    efidir=
-	fi
-    fi
-    
-    if test -n "$efidir"; then
-        # The EFI specification requires that an EFI System Partition must
-        # contain an "EFI" subdirectory, and that OS loaders are stored in
-        # subdirectories below EFI.  Vendors are expected to pick names that do
-        # not collide with other vendors.  To minimise collisions, we use the
-        # name of our distributor if possible.
-	efi_distributor="$bootloader_id"
-	if test $removable = yes; then
-      	   # The specification makes stricter requirements of removable
-	   # devices, in order that only one image can be automatically loaded
-	   # from them.  The image must always reside under /EFI/BOOT, and it
-	   # must have a specific file name depending on the architecture.
-	    efi_distributor=BOOT
-	    case "$target_cpu" in
-		i386)
-		    efi_file=BOOTIA32.EFI ;;
-		x86_64)
-		    efi_file=BOOTX64.EFI ;;
-	    # GRUB does not yet support these architectures, but they're defined
-	    # by the specification so we include them here to ease future
-	    # expansion.
-		ia64)
-		    efi_file=BOOTIA64.EFI ;;
-	    esac
-	else
-	    # It is convenient for each architecture to have a different
-	    # efi_file, so that different versions can be installed in parallel.
-	    case "$target_cpu" in
-		i386)
-		    efi_file=grubia32.efi ;;
-		x86_64)
-		    efi_file=grubx64.efi ;;
-	 # GRUB does not yet support these architectures, but they're defined
- 	 # by the specification so we include them here to ease future
-	 # expansion.
-		ia64)
-		    efi_file=grubia64.efi ;;
-		*)
-		    efi_file=grub.efi ;;
-	    esac
-	   # TODO: We should also use efibootmgr, if available, to add a Boot
-	   # entry for ourselves.
-	fi
-	efidir="$efidir/EFI/$efi_distributor"
-	mkdir -p "$efidir" || exit 1
-    else
-        # We don't know what's going on.  Fall back to traditional
-        # (non-specification-compliant) behaviour.
-	efidir="$grubdir"
-	efi_distributor=
-	efi_file=grub.efi
-    fi
-fi
-
-# Create the GRUB directory if it is not present.
-mkdir -p "$grubdir" || exit 1
+    efi_device="`"$grub_probe" --target=device --device-map= "${rootdir}"`"
+        # Is it a mount point?
+    if test "x$efi_device" != "x`"$grub_probe" --target=device --device-map= "${rootdir}/.."`"; then
+	efidir="${rootdir}"
+    fi
+fi
+
+if test -n "$efidir"; then
+    efi_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${efidir}"`
+    if test "x$efi_fs" = xfat; then :; else
+	echo "${efidir} doesn't look like an EFI partition." 1>&2
+	efidir=
+    fi
+fi
+
+# Find the EFI System Partition.
+hfsdir=
+if test -d "${bootdir}/hfs"; then
+    hfs_device="`"$grub_probe" --target=device --device-map= "${bootdir}/efi"`"
+        # Is it a mount point?
+    if test "x$hfs_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then
+	hfsdir="${bootdir}/hfs"
+    fi
+fi
+
+if test -n "$hfsdir"; then
+    hfs_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${hfsdir}"`
+    if test "x$hfs_fs" = xhfs || test "x$hfs_fs" = xhfsplus; then :; else
+	echo "${hfsdir} doesn't look like an HFS partition." 1>&2
+	hfsdir=
+    fi
+fi
+
+# Find the EFI System Partition.
+fatdir=
+if test -d "${bootdir}/ofw"; then
+    fat_device="`"$grub_probe" --target=device --device-map= "${bootdir}/efi"`"
+        # Is it a mount point?
+    if test "x$fat_device" != "x`"$grub_probe" --target=device --device-map= "${bootdir}"`"; then
+	fatdir="${bootdir}/fat"
+    fi
+fi
+
+if test -n "$fatdir"; then
+    fat_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${fatdir}"`
+    if test "x$fat_fs" = xfat; then :; else
+	echo "${fatdir} doesn't look like a FAT partition." 1>&2
+	hfsdir=
+    fi
+fi
 
 # If --recheck is specified, remove the device map, if present.
 if test $recheck = yes; then
     rm -f "$device_map"
 fi
 
-# Create the device map file if it is not present.
 if test -f "$device_map"; then
     # Make sure that there is no duplicated entry.
     tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' "$device_map" \
@@ -438,22 +444,11 @@
     device_map=
 fi
 
-# Copy the GRUB images to the GRUB directory.
 for file in "${grubdir}"/*.mod "${grubdir}"/*.lst "${grubdir}"/*.img "${grubdir}"/efiemu??.o; do
     if test -f "$file" && [ "`basename $file`" != menu.lst ]; then
 	rm -f "$file" || exit 1
     fi
 done
-for file in "${pkglibdir}"/*.mod "${pkglibdir}"/*.lst; do
-    cp -f "$file" "${grubdir}" || exit 1
-done
-if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then
-    for file in "${pkglibdir}"/*.img "${pkglibdir}"/efiemu??.o; do
-	if test -f "$file"; then
-	    cp -f "$file" "${grubdir}" || exit 1
-	fi
-    done
-fi
 
 # Copy gettext files
 mkdir -p "${grubdir}"/locale/
@@ -498,85 +493,101 @@
 # Device abstraction module, if any (lvm, raid).
 devabstraction_module="`"$grub_probe" --device-map="${device_map}" --target=abstraction --device "${grub_device}"`"
 
-if [ "x$disk_module" = xata ]; then
-    disk_module=pata
-fi
-
-if [ "x$disk_module" = xnative ]; then
-    disk_module="pata ahci ohci"
-    if [ "x$target_cpu" = "xi386" ] || [ "x$target_cpu" = "xx86_64" ]; then
-	disk_module="$disk_module uhci"
-    fi
-    disk_module="$disk_module usbms"
-fi
-
-# The order in this list is critical.  Be careful when modifying it.
-modules="$modules $disk_module"
-modules="$modules $fs_module $partmap_module $devabstraction_module"
-
 relative_grubdir="`"$grub_mkrelpath" "${grubdir}"`" || exit 1
 if [ "x${relative_grubdir}" = "x" ] ; then
     relative_grubdir=/
 fi
 
-prefix_drive=
-config_opt=
-
-rm -f "${grubdir}/load.cfg"
-
-if [ "x${debug_image}" != x ]; then
-    echo "set debug='${debug_image}'" >> "${grubdir}/load.cfg"
-    config_opt="-c ${grubdir}/load.cfg "
-fi
-
-if [ "x${devabstraction_module}" = "x" ] ; then
-    if [ x"${install_device}" != x ]; then
-      if echo "${install_device}" | grep -qx "(.*)" ; then
-        install_drive="${install_device}"
-      else
-        install_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${install_device}"`" || exit 1
-      fi
-      install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
-    fi
-    grub_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"`" || exit 1
-
-    # Strip partition number
-    grub_partition="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\3/'`"
-    grub_drive="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
-    if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]); then
-        # generic method (used on coreboot and ata mod)
-        uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`"
-        if [ "x${uuid}" = "x" ] ; then
-          if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; then
-             echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
-          elif [ "$disk_module" = ata ]; then
-             echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
-          else
-             echo "UUID needed with cross-disk installs, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
-          fi
-             
-          exit 1
-        fi
-
-	if [ x"$disk_module" != x ] && [ x"$disk_module" != xbiosdisk ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
-	elif [ x"$platform" = xpc ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=bios_hints --device "${grub_device}"`"
-	elif [ x"$platform" = xefi ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=efi_hints --device "${grub_device}"`"
-	elif [ x"$platform" = xieee1275 ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device "${grub_device}"`"
-	elif [ x"$platform" = xloongson ] || [ x"$platform" = xqemu ] || [ x"$platform" = xcoreboot ] || [ x"$platform" = xmultiboot ] || [ x"$platform" = xqemu-mips ]; then
-            hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
-	else
-            echo "No hints available for your platform. Expect reduced performance"
-	    hints=
-        fi
-        echo "search.fs_uuid ${uuid} root $hints " >> "${grubdir}/load.cfg"
-	echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg"
-	config_opt="-c ${grubdir}/load.cfg "
-        modules="$modules search_fs_uuid"
+grub_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"`" || exit 1
+
+# Strip partition number
+grub_partition="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\3/'`"
+grub_drive="`echo "${grub_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
+
+uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`"
+
+handle_generic_install () {
+    current_platform="$1"
+    pkglibdir="${libdir}/`echo ${PACKAGE_TARNAME}/${current_platform} | sed ${transform}`"
+    if [ x"$disk_module" != x"" ]; then
+	current_disk_module="$disk_module";
     else
+	case x"$current_platform" in
+	    xi386-pc)
+		current_disk_module=biosdisk;;
+	    *-efi | *-ieee1275)
+		current_disk_module= ;;
+	    *)
+		current_disk_module=native ;;
+	esac
+    fi
+
+    if [ "${current_platform}" = "i386-pc" ] && [ "${bios_devices}" = "" ]; then
+	echo "Skipping BIOS due to missing install device"
+    fi
+
+    if [ "${current_platform}" = "sparc64-ieee1275" ] \
+	&& [ "${sparc64_devices}" = "" ]; then
+	echo "Skipping sparc64 due to missing install device"
+    fi
+
+    # Create the GRUB directory if it is not present.
+    mkdir -p "$grubdir/${current_platform}" || exit 1
+
+    # Copy the GRUB images to the GRUB directory.
+    for file in "${grubdir}/${current_platform}"/*.mod "${grubdir}/${current_platform}"/*.lst "${grubdir}/${current_platform}"/*.img "${grubdir}/${current_platform}"/efiemu??.o; do
+	if test -f "$file"; then
+	    rm -f "$file" || exit 1
+	fi
+    done
+
+    for file in "${pkglibdir}"/*.mod "${pkglibdir}"/*.lst "${pkglibdir}"/*.img "${pkglibdir}"/efiemu??.o; do
+	if test -f "$file"; then
+	    cp -f "$file" "${grubdir}/${current_platform}" || exit 1
+	fi
+    done
+
+    if [ "x$current_disk_module" = xata ]; then
+	current_disk_module=pata
+    fi
+
+    if [ "x$current_disk_module" = xnative ]; then
+	current_disk_module="pata ahci ohci ehci"
+	case "x$current_platrofm" in
+	    xi386-* | xx86_64-*)
+		current_disk_module="$current_disk_module uhci";;
+	esac
+	current_disk_module="$current_disk_module usbms"
+    fi
+
+    # The order in this list is critical.  Be careful when modifying it.
+    current_modules="$modules $disk_module"
+    current_modules="$current_modules $fs_module $partmap_module $devabstraction_module"
+
+    prefix_drive=
+    config_opt=
+
+    rm -f "${grubdir}/${current_platform}/load.cfg"
+
+    if [ "x${debug_image}" != x ]; then
+	echo "set debug='${debug_image}'" >> "${grubdir}/${current_platform}/load.cfg"
+	config_opt="-c ${grubdir}/${current_platform}/load.cfg "
+    fi
+
+    case "${current_platform}" in
+	sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;;
+	mipsel-loongson) mkimage_target=mipsel-loongson-elf ;;
+	*) mkimage_target="${target_cpu}-${platform}" ;;
+    esac
+
+    case "${current_platform}" in
+	i386-efi | x86_64-efi) imgext=efi ;;
+	mipsel-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 | powerpc-ieee1275) imgext=elf ;;
+        *) imgext=img ;;
+    esac
+
+    if [ "x${devabstraction_module}" = "x" ] ; then
+
         # we need to hardcode the partition number in the core image's prefix.
 	if [ x"$grub_partition" = x ]; then
             prefix_drive="()"
@@ -584,125 +595,160 @@
             # Comma is already there
             prefix_drive="($grub_partition)"
 	fi
-    fi
-else
-    if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then
-	for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do
-	    echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg"
-	done
-	config_opt="-c ${grubdir}/load.cfg "
-    fi
-
-    prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1
-fi
-
-case "${target_cpu}-${platform}" in
-    sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;;
-    mipsel-loongson) mkimage_target=mipsel-loongson-elf ;;
-    *) mkimage_target="${target_cpu}-${platform}" ;;
-esac
-
-case "${target_cpu}-${platform}" in
-    i386-efi | x86_64-efi) imgext=efi ;;
-    mipsel-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 \
-	| powerpc-ieee1275) imgext=elf ;;
-    *) imgext=img ;;
-esac
-
-
-"$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $modules || exit 1
+
+	"$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/core-samedisk.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $current_modules || exit 1
+
+	if [ x"$uuid" != x ]; then
+	    if [ x"$current_disk_module" != x ] && [ x"$current_disk_module" != xbiosdisk ]; then
+		hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`"
+	    else
+		case "$current_platform" in 
+		    i386-pc)
+			hints="`"$grub_probe" --device-map="${device_map}" --target=bios_hints --device "${grub_device}"`";;
+		    *-efi)
+			hints="`"$grub_probe" --device-map="${device_map}" --target=efi_hints --device "${grub_device}"`";;
+		    *-ieee1275)
+			hints="`"$grub_probe" --device-map="${device_map}" --target=ieee1275_hints --device "${grub_device}"`";;
+		    *-loongson | *-qemu | *-coreboot | *-multiboot | *-qemu-mips)
+			hints="`"$grub_probe" --device-map="${device_map}" --target=baremetal_hints --device "${grub_device}"`";;
+		    *)
+			echo "No hints available for your platform. Expect reduced performance";;
+		esac
+	    fi
+            echo "search.fs_uuid ${uuid} root $hints " >> "${grubdir}/${current_platform}/load.cfg"
+	    echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/${current_platform}/load.cfg"
+	    config_opt="-c ${grubdir}/${current_platform}/load.cfg "
+            current_modules="$current_modules search_fs_uuid"
+	    "$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/core-crossdisk.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $current_modules || exit 1
+	fi
+    else
+	if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then
+	    for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do
+		echo "cryptomount -u $uuid" >> "${grubdir}/${current_platform}/load.cfg"
+	    done
+	    config_opt="-c ${grubdir}/${current_platform}/load.cfg "
+	fi
+	prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1
+	"$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/${current_platform}/core-crossdisk.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $current_modules || exit 1
+    fi
 
 # Backward-compatibility kludges
-if [ "${target_cpu}-${platform}" = "mipsel-loongson" ]; then
-    cp "${grubdir}/core.${imgext}" "${bootdir}"/grub.elf
-elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then
-    cp "${grubdir}/core.${imgext}" "${grubdir}/grub"
-elif [ "${target_cpu}-${platform}" = "i386-efi" ] || [ "${target_cpu}-${platform}" = "x86_64-efi" ]; then
-    "$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/grub.efi" --prefix="" $modules || exit 1
-fi
-
-
-# Perform the platform-dependent install
-if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then
-    # Now perform the installation.
-    "$grub_setup" ${allow_floppy} ${setup_verbose} ${setup_force} --directory="${grubdir}" \
-	--device-map="${device_map}" "${install_device}" || exit 1
-elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then
-    if [ x"$update_nvram" = xyes ]; then
-	ofpathname="`which ofpathname`"
-	nvsetenv="`which nvsetenv`"
-	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 $grub_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`"
-	partno="`echo $grub_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
-	boot_device="$ofpath:$partno,"`"$grub_mkrelpath" "${grubdir}/core.${imgext}" | sed 's,/,\\\\,g'`
-
-        # If a install device is defined, copy the core.elf to PReP partition. 
-	if  [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ] \
-	    && [ -n "${install_device}" ]; then
-            if [ "$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t msdos_parttype)" != "41" ]; then
-		echo "The chosen partition is not a PReP partition."
-		exit 1
-            fi
-
-            if [ "$(file -s "${install_device}" -b | awk '{ print $1 }')" = ELF ] || [ $(cmp /dev/zero "${install_device}" &>/dev/null) ]; then
-            # Change boot device to the harddisk root
-		boot_device="$ofpath"
-		dd if="${grubdir}/core.${imgext}" of="${install_device}" status=noxfer || {
-		    echo "Failed to copy Grub to the PReP partition."
-		    exit 1
-		}
-            else
-		echo "The PReP partition is not empty. If you are sure you want to use it, run dd to clear it:"
-		echo "  dd if=/dev/zero of=${install_device}"
-		exit 1
-            fi
-	fi
-
-	"$nvsetenv" boot-device "$boot_device" || {
-	    echo "$nvsetenv failed."
-	    echo "You will have to set boot-device manually.  At the Open Firmware prompt, type:"
-	    echo "  setenv boot-device $boot_device"
-	    exit 1
-	}
+    case "$current_platform" in
+	mipsel-loongson)
+	    cp "${grubdir}/${current_platform}/core-crossdisk.${imgext}" "${bootdir}"/grub.elf
+	    ;;
+	i386-ieee1275 | powerpc-ieee1275)
+	    cp "${grubdir}/${current_platform}/core-crossdisk.${imgext}" "${grubdir}/grub"
+	    ;;
+	i386-efi)
+	    "$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/grubia32.efi" --prefix="" $current_modules || exit 1;;
+	x86_64-efi)
+	    "$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/grubx64.efi" --prefix="" $current_modules || exit 1;;
+    esac
+}
+
+get_core () {
+  install_device="$1"
+  install_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${install_device}"`" || exit 1
+  install_drive="`echo "${install_drive}" | sed -e 's/^(\(\([^,\\\\]\|\\\\\\\\\|\\\\,\)*\)\(\(,[a-zA-Z0-9]*\)*\))$/\1/'`"
+  if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ]; then
+      if [ "x${uuid}" = "x" ] ; then
+	  if [ "$disk_module" = ata ]; then
+	      echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+	  else
+	      echo "UUID needed with cross-disk installs, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+	  fi
+	  exit 1
+      fi
+      core=core-crossdisk
+  else
+      core=core-samedisk
+  fi
+}
+
+handle_efi () {
+    current_platform="$1"
+    imgext=efi
+    if test -n "$efidir"; then
+        # The EFI specification requires that an EFI System Partition must
+        # contain an "EFI" subdirectory, and that OS loaders are stored in
+        # subdirectories below EFI.  Vendors are expected to pick names that do
+        # not collide with other vendors.  To minimise collisions, we use the
+        # name of our distributor if possible.
+	efi_distributor="$bootloader_id"
+	if test $removable = yes; then
+      	   # The specification makes stricter requirements of removable
+	   # devices, in order that only one image can be automatically loaded
+	   # from them.  The image must always reside under /EFI/BOOT, and it
+	   # must have a specific file name depending on the architecture.
+	    efi_distributor=BOOT
+	    case "$current_platform" in
+		i386-efi)
+		    efi_file=BOOTIA32.EFI ;;
+		x86_64-efi)
+		    efi_file=BOOTX64.EFI ;;
+		ia64-efi)
+		    efi_file=BOOTIA64.EFI ;;
+	    esac
+	else
+	    # It is convenient for each architecture to have a different
+	    # efi_file, so that different versions can be installed in parallel.
+	    case "$current_platform" in
+		i386-efi)
+		    efi_file=grubia32.efi ;;
+		x86_64-efi)
+		    efi_file=grubx64.efi ;;
+		ia64-efi)
+		    efi_file=grubia64.efi ;;
+		*)
+		    efi_file=grub.efi ;;
+	    esac
+	   # TODO: We should also use efibootmgr, if available, to add a Boot
+	   # entry for ourselves.
+	fi
+	current_efidir="$efidir/EFI/$efi_distributor"
+	mkdir -p "$current_efidir" || exit 1
+    else
+        # We don't know what's going on.  Fall back to traditional
+        # (non-specification-compliant) behaviour.
+	current_efidir="$grubdir/$current_platform"
+	efi_distributor=
+	efi_file=grub.efi
     fi
-elif [ x"${target_cpu}-${platform}" = xmips-arc ]; then
-    dvhtool -d "${install_device}" --unix-to-vh "{grubdir}/core.${imgext}" grub
-    echo "You will have to set SystemPartition and OSLoader manually."
-elif [ x"$platform" = xefi ]; then
-    cp "${grubdir}/core.${imgext}" "${efidir}/${efi_file}"
+
+    get_core "$hfs_device"
+    hfscore="$core"
+    mkdir -p "${hfsdir}/System/Library/CoreServices"
+    cp "${grubdir}/$current_platform/$core.efi" "${hfsdir}/System/Library/CoreServices/boot.efi"
+    touch "${hfsdir}/mach_kernel"
+    cat > "${hfsdir}/System/Library/CoreServices/SystemVersion.plist" <<EOF
+<plist version="1.0">
+<dict>
+        <key>ProductBuildVersion</key>
+        <string></string>
+        <key>ProductName</key>
+        <string>${bootloader_id}</string>
+        <key>ProductVersion</key>
+        <string>${PACKAGE_NAME} ${PACKAGE_VERSION}</string>
+</dict>
+</plist>
+EOF
+    "$grub_mactelbless" "${hfsdir}/System/Library/CoreServices/boot.efi"
+
+    get_core "$efi_device"
+    cp "${grubdir}/$current_platform/$core.efi" "${efidir}/${efi_file}"
     # For old macs. Suggested by Peter Jones.
-    if [ x$target_cpu = xi386 ]; then
-	cp "${grubdir}/core.${imgext}" "${efidir}/boot.efi"
+    if [ x$current_platform = xi386-efi ]; then
+	cp "${grubdir}/$current_platform/$core.efi" "${efidir}/boot.efi"
     fi
 
     # Try to make this image bootable using the EFI Boot Manager, if available.
     efibootmgr="`which efibootmgr`"
     if test "$removable" = no && test -n "$efi_distributor" && \
-	test -n "$efibootmgr"; then
+	test -n "$efibootmgr" && test "${current_platform/-efi/}" = "`uname -m`"; then
         # On Linux, we need the efivars kernel modules.
-	case "$host_os" in
-	    linux*)
+	case "`uname -s`" in
+	    Linux* | linux*)
 		modprobe -q efivars 2>/dev/null || true ;;
 	esac
 
@@ -728,9 +774,132 @@
 		-L "$bootloader_id" -l "\\EFI\\$efi_distributor\\$efi_file"
 	fi
     fi
-else
-    echo "WARNING: no platform-specific install was performed"
+}
+
+handle_ieee1275 () {
+    current_platform="$1"
+
+    target_core=
+    if test -n "$fatdir"; then
+	get_core "${fat_device}"
+	cp "${grubdir}/$current_platform/$core.elf" "$fatdir/core.elf"
+	target_core="$fatdir/core.elf"
+    fi
+    
+    if test -n "$hfsdir"; then
+	get_core "${hfs_device}"
+	cp "${grubdir}/$current_platform/$core.elf" "$hfsdir/core.elf"
+	if is_apple; then
+	    target_core="$hfsdir/core.elf"
+	fi
+    fi
+    
+    if [ x"$update_nvram" = xyes ]; then
+	ofpathname="`which ofpathname`"
+	nvsetenv="`which nvsetenv`"
+	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
+
+        # If a install device is defined, copy the core.elf to PReP partition. 
+	if  [ "${current_platform}" = "powerpc-ieee1275" ] && \
+	    [ "$prep_devices" != "" ]; then
+	    for prep in $prep_devices; do
+		if [ "$("${grub_probe}" -m "${device_map}" -d "${prep}" -t msdos_parttype)" != "41" ]; then
+		    echo "The chosen partition is not a PReP partition."
+		    exit 1
+		fi
+
+            if [ "$(file -s "${prep}" -b | awk '{ print $1 }')" = ELF ] || [ $(cmp /dev/zero "${prep}" &>/dev/null) ]; then
+            # Change boot device to the harddisk root
+		boot_device="$ofpath"
+		dd if="${grubdir}/core.${imgext}" of="${install_device}" status=noxfer || {
+		    echo "Failed to copy Grub to the PReP partition."
+		    exit 1
+		}
+            else
+		echo "The PReP partition is not empty. If you are sure you want to use it, run dd to clear it:"
+		echo "  dd if=/dev/zero of=${prep}"
+		exit 1
+            fi
+	    dev="`echo "$prep" | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`"
+	    boot_device="`$ofpathname $dev`" || {
+		echo "Couldn't find Open Firmware device tree path for $dev."
+		echo "You will have to set boot-device manually."
+		exit 1
+	    }
+	else
+            # Get the Open Firmware device tree path translation.
+	    target_device=`"$grub_probe" -t device "$target_core"`
+	    dev="`echo $target_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`"
+	    partno="`echo $target_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
+	    boot_device="$ofpath:$partno,"`"$grub_mkrelpath" "${target_core}" | sed 's,/,\\\\,g'`
+	fi
+
+	"$nvsetenv" boot-device "$boot_device" || {
+	    echo "$nvsetenv failed."
+	    echo "You will have to set boot-device manually.  At the Open Firmware prompt, type:"
+	    echo "  setenv boot-device $boot_device"
+	    exit 1
+	}
+    fi
 fi
+}
+
+# Perform the platform-dependent install
+for platform in $platforms; do
+    # Perform the platform-independent install
+    handle_generic_install "$platform"
+    case "$platform" in
+	i386-pc)
+	    for dev in "$bios_devices"; do
+		get_core "$dev"
+		"$grub_setup_bios" ${allow_floppy} ${setup_verbose} ${setup_force} --directory="${grubdir}/i386-pc" \
+      --core-image="$core.img" --device-map="${device_map}" "${dev}" || exit 1
+	    done;;
+	sparc64-ieee1275)
+	    for dev in "$sparc64_devices"; do
+		get_core "$dev"
+		"$grub_setup_sparc64" ${allow_floppy} ${setup_verbose} ${setup_force} --directory="${grubdir}/sparc64-ieee1275" \
+      --core-image="$core.img" --device-map="${device_map}" "${dev}" || exit 1
+	    done;;
+	*-ieee1275)
+	    handle_ieee1275 "$platform";;
+	*-efi)
+	    handle_efi "$platform";;
+	*-arc)
+	    if [ "x${uuid}" = "x" ] ; then
+		echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+		exit 1
+	    fi
+	    for dev in "$arc_devices"; do
+		dvhtool -d "${install_device}" --unix-to-vh "{grubdir}/core-crossdisk.${imgext}" grub
+	    done
+	    echo "You will have to set SystemPartition and OSLoader manually."
+		
+    ;;
+	*)
+	    echo "WARNING: no platform-specific install was performed";;
+    esac
+done
 
 echo "Installation finished. No error reported."
 

=== modified file 'util/grub-setup.c'
--- util/grub-setup.c	2012-01-29 13:28:01 +0000
+++ util/grub-setup.c	2012-02-01 17:44:50 +0000
@@ -33,7 +33,7 @@
 #include <grub/term.h>
 #include <grub/i18n.h>
 #include <grub/util/lvm.h>
-#ifdef GRUB_MACHINE_IEEE1275
+#ifdef GRUB_SETUP_SPARC64
 #include <grub/util/ofpath.h>
 #endif
 
@@ -77,14 +77,14 @@
 #define DEFAULT_BOOT_FILE	"boot.img"
 #define DEFAULT_CORE_FILE	"core.img"
 
-#ifdef GRUB_MACHINE_SPARC64
+#ifdef GRUB_SETUP_SPARC64
 #define grub_target_to_host16(x)	grub_be_to_cpu16(x)
 #define grub_target_to_host32(x)	grub_be_to_cpu32(x)
 #define grub_target_to_host64(x)	grub_be_to_cpu64(x)
 #define grub_host_to_target16(x)	grub_cpu_to_be16(x)
 #define grub_host_to_target32(x)	grub_cpu_to_be32(x)
 #define grub_host_to_target64(x)	grub_cpu_to_be64(x)
-#elif defined (GRUB_MACHINE_PCBIOS)
+#elif defined (GRUB_SETUP_BIOS)
 #define grub_target_to_host16(x)	grub_le_to_cpu16(x)
 #define grub_target_to_host32(x)	grub_le_to_cpu32(x)
 #define grub_target_to_host64(x)	grub_le_to_cpu64(x)
@@ -99,7 +99,7 @@
 write_rootdev (char *core_img, grub_device_t root_dev,
 	       char *boot_img, grub_uint64_t first_sector)
 {
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
   {
     grub_uint8_t *boot_drive;
     grub_disk_addr_t *kernel_sector;
@@ -113,7 +113,7 @@
     *kernel_sector = grub_cpu_to_le64 (first_sector);
   }
 #endif
-#ifdef GRUB_MACHINE_IEEE1275
+#ifdef GRUB_SETUP_SPARC64
   {
     grub_disk_addr_t *kernel_byte;
     kernel_byte = (grub_disk_addr_t *) (boot_img
@@ -124,7 +124,7 @@
 #endif
 }
 
-#ifdef GRUB_MACHINE_IEEE1275
+#ifdef GRUB_SETUP_SPARC64
 #define BOOT_SECTOR 1
 #else
 #define BOOT_SECTOR 0
@@ -145,7 +145,7 @@
   char *tmp_img;
   int i;
   grub_disk_addr_t first_sector;
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
   grub_uint16_t current_segment
     = GRUB_BOOT_MACHINE_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
 #endif
@@ -192,7 +192,7 @@
 	{
 	  block->start = grub_host_to_target64 (sector);
 	  block->len = grub_host_to_target16 (1);
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
 	  block->segment = grub_host_to_target16 (current_segment);
 #endif
 
@@ -202,7 +202,7 @@
 	}
 
       last_length = length;
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
       current_segment += GRUB_DISK_SECTOR_SIZE >> 4;
 #endif
     }
@@ -222,7 +222,7 @@
 		  >> GRUB_DISK_SECTOR_BITS);
   if (core_size < GRUB_DISK_SECTOR_SIZE)
     grub_util_error (_("the size of `%s' is too small"), core_path);
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
   if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE)
     grub_util_error (_("the size of `%s' is too large"), core_path);
 #endif
@@ -250,14 +250,14 @@
   if (grub_env_set ("root", root) != GRUB_ERR_NONE)
     grub_util_error ("%s", _(grub_errmsg));
 
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
   /* Read the original sector from the disk.  */
   tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE);
   if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img))
     grub_util_error ("%s", _(grub_errmsg));
 #endif
 
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
   {
     grub_uint16_t *boot_drive_check;
     boot_drive_check = (grub_uint16_t *) (boot_img
@@ -276,7 +276,7 @@
   }
 #endif
 
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
   {
     grub_partition_map_t dest_partmap = NULL;
     grub_partition_t container = dest_dev->disk->partition;
@@ -331,7 +331,7 @@
 
     is_ldm = grub_util_is_ldm (dest_dev->disk);
 
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
     if (fs_probe)
       {
 	if (!fs && !dest_partmap)
@@ -502,7 +502,7 @@
 
 unable_to_embed:
 
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
   if (dest_dev->disk->id != root_dev->disk->id
       || dest_dev->disk->dev->id != root_dev->disk->dev->id)
     grub_util_error (_("embedding is not possible, but this is required for "
@@ -603,7 +603,7 @@
     {
       block->start = 0;
       block->len = 0;
-#ifdef GRUB_MACHINE_PCBIOS
+#ifdef GRUB_SETUP_BIOS
       block->segment = 0;
 #endif
 
@@ -630,7 +630,7 @@
       != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE)
     grub_util_error (_("failed to read the rest sectors of the core image"));
 
-#ifdef GRUB_MACHINE_IEEE1275
+#ifdef GRUB_SETUP_SPARC64
   {
     char *boot_devpath;
     boot_devpath = (char *) (boot_img
@@ -889,7 +889,7 @@
       exit(1);
     }
 
-#ifdef GRUB_MACHINE_IEEE1275
+#ifdef GRUB_SETUP_SPARC64
   arguments.force = 1;
 #endif
 

=== modified file 'util/powerpc/ieee1275/grub-mkrescue.in'
--- util/powerpc/ieee1275/grub-mkrescue.in	2010-10-18 20:50:01 +0000
+++ util/powerpc/ieee1275/grub-mkrescue.in	2012-02-01 17:50:30 +0000
@@ -27,9 +27,7 @@
 PACKAGE_NAME=@PACKAGE_NAME@
 PACKAGE_TARNAME=@PACKAGE_TARNAME@
 PACKAGE_VERSION=@PACKAGE_VERSION@
-target_cpu=@target_cpu@
-platform=@platform@
-pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
+pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/powerpc-ieee1275 | sed ${transform}`
 
 self=`basename $0`
 

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to