diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 9d33f3a..7189953 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -207,25 +207,31 @@ class BootLoader(object):
     can_update = False
     image_label_attr = "label"
 
+    disklabel_types = []
+
     # requirements for bootloader stage1 devices
     stage1_device_types = []
-    stage1_device_raid_levels = []
-    stage1_device_format_types = []
-    stage1_device_disklabel_types = []
-    stage1_device_mountpoints = []
-    stage1_device_min_size = None
-    stage1_device_max_size = None
+    stage1_raid_levels = []
+    stage1_raid_metadata = []
+    stage1_raid_member_types = []
+    stage1_format_types = []
+    stage1_mountpoints = []
+
+    stage2_is_valid_stage1 = False
 
     # for UI use, eg: "mdarray": N_("RAID Device")
     target_descriptions = {}
 
     # requirements for stage2 devices
     stage2_device_types = []
-    stage2_device_raid_levels = []
-    stage2_device_format_types = ["ext4", "ext3", "ext2"]
-    stage2_device_mountpoints = ["/boot", "/"]
-    stage2_device_min_size = 50
-    stage2_device_max_size = None
+    stage2_raid_levels = []
+    stage2_raid_metadata = []
+    stage2_raid_member_types = []
+    stage2_format_types = ["ext4", "ext3", "ext2"]
+    stage2_mountpoints = ["/boot", "/"]
+    stage2_encryption_support = False
+    stage2_bootable = False
+
     non_linux_format_types = []
 
     # this is so stupid...
@@ -285,8 +291,8 @@ class BootLoader(object):
 
     @stage1_device.setter
     def stage1_device(self, device):
-        if device and not self._is_valid_stage1_device(device):
-            raise ValueError("%s is not a valid stage1 device" % device.name)
+        #if device and not self._is_valid_stage1_device(device):
+        #    raise ValueError("%s is not a valid stage1 device" % device.name)
 
         log.debug("new bootloader stage1 device: %s" % getattr(device,
                                                                "name", None))
@@ -412,6 +418,50 @@ class BootLoader(object):
             self.chain_images.append(BootLoaderImage(device=device))
 
     #
+    # constraint checking for target devices
+    #
+    def _is_valid_md(self, device, device_types=None, raid_levels=None,
+                     metadata=None, member_types=None):
+        ret = True
+        if raid_levels and device.level not in raid_levels:
+            ret = False
+
+        if metadata and device.metadataVersion not in metadata:
+            ret = False
+
+        if member_types:
+            for member in device.devices:
+                if not self._device_type_match(member, member_types):
+                    ret = False
+
+        return ret
+
+    def _is_valid_disklabel(self, device, disklabel_types=None):
+        ret = True
+        if self.disklabel_types:
+            for disk in device.disks:
+                label_type = disk.format.labelType
+                if label_type not in self.disklabel_types:
+                    ret = False
+
+        return ret
+
+    def _is_valid_format(self, device, format_types=None, mountpoints=None):
+        ret = True
+        if format_types and device.format.type not in format_types:
+            ret = False
+
+    def _is_valid_size(self, device):
+        ret = True
+        if device.format.minSize and device.size < device.format.minSize:
+            ret = False
+
+        if device.format.maxSize and device.size > device.format.maxSize:
+            ret = False
+
+        return ret
+
+    #
     # target/stage1 device access
     #
     def _device_type_index(self, device, types):
@@ -436,21 +486,22 @@ class BootLoader(object):
         if idx is None:
             raise ValueError("'%s' not a valid stage1 type" % device.type)
 
+        # this looks unnecessarily complicated, but it handles the various
+        # device types that we treat as disks
         return self.target_descriptions[self.stage1_device_types[idx]]
 
     def set_preferred_stage1_type(self, preferred):
         """ Set a preferred type of stage1 device.
 
             XXX should this reorder the list or remove everything else? """
-        if preferred == "mbr":
-            preferred = "disk"
-
-        try:
-            index = self.stage1_device_types.index(preferred)
-        except ValueError:
-            raise ValueError("'%s' not a valid stage1 device type" % preferred)
+        if preferred != "partition":
+            # it's either "mbr", which is already default, or it's invalid
+            return
 
-        self.stage1_device_types.insert(0, self.stage1_device_types.pop(index))
+        # partition means "use the stage2 device for a stage1 device"
+        if self.stage2_is_valid_stage1:
+            # FIXME: note that stage2 is preferable as stage1
+            pass
 
     def _is_valid_stage1_device(self, device):
         """ Return True if the device is a valid stage1 target device.
@@ -461,38 +512,37 @@ class BootLoader(object):
             a special device. Some examples of these special devices are EFI
             system partitions on EFI machines, PReP boot partitions on
             iSeries, and Apple bootstrap partitions on Mac. """
+        self.problems = []
+
+        if self.stage2_is_valid_stage1 and device == self.stage2_device:
+            return True
+
         if not self._device_type_match(device, self.stage1_device_types):
+            self.problems.append(_(""))
             return False
 
-        if (self.stage1_device_min_size is not None and
-            device.size < self.stage1_device_min_size):
+        if not self._is_valid_disklabel(device,
+                                        disklabel_types=self.disklabel_types):
             return False
 
-        if (self.stage1_device_max_size is not None and
-            device.size > self.stage1_device_max_size):
+        if not self._is_valid_size(device):
             return False
 
-        if not getattr(device, "bootable", True) or \
-           (hasattr(device, "partedPartition") and
-            not device.partedPartition.active):
+        if not self._is_valid_md(device, device_types=self.stage1_device_types,
+                                 raid_levels=self.stage1_raid_levels,
+                                 metadata=self.stage1_raid_metadata,
+                                 member_types=self.stage1_raid_member_types):
             return False
 
-        if getattr(device.format, "label", None) == "ANACONDA":
+        if not getattr(device, "bootable", True):
             return False
 
-        if self.stage1_device_format_types and \
-           device.format.type not in self.stage1_device_format_types:
+        if getattr(device.format, "label", None) == "ANACONDA":
             return False
 
-        if self.stage1_device_disklabel_types:
-            for disk in device.disks:
-                label_type = disk.format.labelType
-                if label_type not in self.stage1_device_disklabel_types:
-                    return False
-
-        if self.stage1_device_mountpoints and \
-           hasattr(device.format, "mountpoint") and \
-           device.format.mountpoint not in self.stage1_device_mountpoints:
+        if not self._is_valid_format(device,
+                                     format_types=self.stage1_format_types,
+                                     mountpoints=self.stage1_mountpoints):
             return False
 
         return True
@@ -540,33 +590,35 @@ class BootLoader(object):
         if not self._device_type_match(device, self.stage2_device_types):
             return False
 
-        if device.type == "mdarray" and \
-           device.level not in self.stage2_device_raid_levels:
-            # TODO: also check metadata version, as ridiculous as that is
+        if not self._is_valid_disklabel(device,
+                                        disklabel_types=self.disklabel_types):
             return False
 
-        if not self.stage1_devices:
-            # XXX is this really a dealbreaker?
+        if not self._is_valid_size(device):
             return False
 
-        # FIXME: the windows boot block part belongs in GRUB
-        if hasattr(device, "partedPartition") and \
-           (not device.bootable or not device.partedPartition.active) and \
-           not has_windows_boot_block(device):
+        if not self._is_valid_md(device, device_types=self.stage2_device_types,
+                                 raid_levels=self.stage2_raid_levels,
+                                 metadata=self.stage2_raid_metadata,
+                                 member_types=self.stage2_raid_member_types):
             return False
 
-        format_types = []
-        if linux:
-            format_types = self.stage2_device_format_types
-            mountpoint = getattr(device.format, "mountpoint", None)
-            if self.stage2_device_mountpoints and \
-               mountpoint not in self.stage2_device_mountpoints:
-                return False
+        if not getattr(device, "bootable", True):
+            # this may not make sense when windows installations are present
+            return False
 
-        if non_linux:
-            format_types.extend(self.non_linux_format_types)
+        if (not
+            (linux and
+             self._is_valid_format(device,
+                                   format_types=self.stage2_format_types,
+                                   mountpoints=self.stage2_mountpoints))
+            or
+            (non_linux and
+             self._is_valid_format(device,
+                                   format_types=self.non_linux_format_types))):
+            return False
 
-        return device.format.type in format_types
+        return True
 
     @property
     def bootable_chain_devices(self):
@@ -828,12 +880,14 @@ class GRUB(BootLoader):
     can_update = True
 
     # list of strings representing options for bootloader target device types
-    stage1_device_types = ["disk", "partition", "mdarray"]
-    stage1_device_raid_levels = [mdraid.RAID1]
-    stage1_device_format_types = []
-    stage1_device_format_mountpoints = ["/boot", "/"]
+    stage1_device_types = ["disk"]
+    stage1_raid_levels = []
+    stage1_format_types = []
+    stage1_mountpoints = []
     stage1_device_disklabel_types = ["msdos", "gpt"]    # gpt?
 
+    stage2_is_valid_stage1 = True
+
     # XXX account for disklabel type since mbr means nothing on gpt
     target_descriptions = {"disk": N_("Master Boot Record"),
                            "partition": N_("First sector of boot partition"),
@@ -841,7 +895,7 @@ class GRUB(BootLoader):
 
     # list of strings representing options for boot device types
     stage2_device_types = ["partition", "mdarray"]
-    stage2_device_raid_levels = [mdraid.RAID1]
+    stage2_raid_levels = [mdraid.RAID1]
 
     # XXX hpfs, if reported by blkid/udev, will end up with a type of None
     non_linux_format_types = ["vfat", "ntfs", "hpfs"]
@@ -1160,14 +1214,15 @@ class EFIGRUB(GRUB):
     can_dual_boot = False
     _config_dir = "efi/EFI/redhat"
 
+    disklabel_types = ["gpt"]
+
     # stage1 device types
     stage1_device_types = ["partition", "mdarray"]
     stage1_device_raid_levels = [mdraid.RAID1]
     stage1_device_format_types = ["efi"]
     stage1_device_mountpoints = ["/boot/efi"]
-    stage1_device_disklabel_types = ["gpt"]
-    stage1_device_min_size = 50
-    stage1_device_max_size = 256
+
+    stage2_is_valid_stage1 = False
 
     target_descriptions = {"partition": N_("EFI System Partition"),
                            "mdarray": N_("RAID Device")}
@@ -1287,31 +1342,35 @@ class GRUB2(GRUB):
     can_dual_boot = True
     can_update = True
 
-    # requirements for bootloader stage1 devices
-    stage1_device_types = ["disk", "partition", "mdarray"]
-    stage1_device_raid_levels = [mdraid.RAID1]
-    stage1_device_format_types = []
-    stage1_device_disklabel_types = ["msdos", "gpt"]
-    stage1_device_mountpoints = ["/boot", "/"]
-
-    # for UI use, eg: "mdarray": N_("RAID Device")
-    target_descriptions = {"msdos": N_("Master Boot Record"),
-                           "partition": N_("First sector of boot partition"),
-                           "mdarray": N_("RAID Device")}
-
-    # these are disklabel-specific descriptions for stage1 targets
-    partition_descriptions = {"msdos": N_("First sector of boot partition"),
-                              "gpt": N_("BIOS boot partition")}
+    disklabel_types = ["gpt", "msdos"]
 
     # requirements for boot devices
     stage2_device_types = ["partition", "mdarray", "lvmlv"]
-    stage2_device_raid_levels = [mdraid.RAID4, mdraid.RAID1, mdraid.RAID4,
-                               mdraid.RAID5, mdraid.RAID6, mdraid.RAID10]
-    stage2_device_format_types = ["ext4", "ext3", "ext2"]
-    stage2_device_mountpoints = ["/boot", "/"]
-    stage2_device_min_size = 50
-    stage2_device_max_size = None
-    non_linux_format_types = []
+    stage2_raid_levels = [mdraid.RAID0, mdraid.RAID1, mdraid.RAID4,
+                          mdraid.RAID5, mdraid.RAID6, mdraid.RAID10]
+
+    # XXX we probably need special handling for raid stage1 w/ gpt disklabel
+    #     since it's unlikely there'll be a bios boot partition on each disk
+
+    #
+    # constraints for target devices
+    #
+    def _is_valid_(self, device):
+        ret = False
+    def _is_valid_stage1_device(self, device):
+        ret = super(GRUB2, self)._is_valid_stage1_device(device)
+
+        # check that a bios boot partition is present if the stage1 device
+        # is a gpt-labeled disk
+        if device.isDisk and getattr(device.format, "labelType", None) == "gpt":
+            partitions = [p for p in self.storage.partitions
+                          if p.disk == device]
+            for p in partitions:
+                if p.format.type == "biosboot":
+                    ret = True
+                    break
+
+        return ret
 
     #
     # grub-related conveniences
@@ -1458,13 +1517,13 @@ class Yaboot(YabootSILOBase):
     packages = ["yaboot"]
 
     # requirements for bootloader stage1 devices
-    stage1_device_types = ["partition", "mdarray"]
-    stage1_device_raid_levels = [mdraid.RAID1]
-    stage1_device_format_types = ["appleboot", "prepboot"]
+    stage1_device_types = ["partition"]
+    stage1_format_types = ["appleboot", "prepboot"]
 
     # stage2 device requirements
     stage2_device_types = ["partition", "mdarray"]
     stage2_device_raid_levels = [mdraid.RAID1]
+
     non_linux_format_types = ["hfs", "hfs+"]
 
     def __init__(self, storage):
@@ -1550,10 +1609,9 @@ class Yaboot(YabootSILOBase):
 class IPSeriesYaboot(Yaboot):
     prog = "mkofboot"
 
-    stage1_device_format_types = ["prepboot"]
-    stage1_device_disklabel_types = ["msdos"]
-    stage1_device_min_size = 4
-    stage1_device_max_size = 10
+    disklabel_types = ["msdos"]
+
+    stage1_format_types = ["prepboot"]
 
     target_descriptions = {"partition": N_("PReP Boot Partition"),
                            "mdarray": N_("RAID Device")}
@@ -1569,12 +1627,11 @@ class IPSeriesYaboot(Yaboot):
 
 class MacYaboot(Yaboot):
     prog = "mkofboot"
-
     can_dual_boot = True
-    stage1_device_format_types = ["appleboot"]
-    stage1_device_disklabel_types = ["mac"]
-    stage1_device_min_size = 800.00 / 1024.00
-    stage1_device_max_size = 1
+
+    disklabel_types = ["mac"]
+
+    stage1_format_types = ["appleboot"]
 
     target_descriptions = {"partition": N_("Apple Bootstrap Partition"),
                            "mdarray": N_("RAID Device")}
@@ -1598,18 +1655,18 @@ class ZIPL(BootLoader):
     name = "ZIPL"
     config_file = "/etc/zipl.conf"
     packages = ["zipl"]
+    packages = ["s390utils"]    # is this bootloader or platform?
+    image_label_attr = "short_label"
+    preserve_args = ["cio_ignore"]
+
+    disklabel_types = ["msdos", "dasd"]
 
     # stage1 device requirements
-    stage1_device_types = ["disk", "partition"]
-    stage1_device_disklabel_types = ["msdos", "dasd"]
+    stage1_device_types = ["disk"]
 
     # stage2 device requirements
     stage2_device_types = ["partition", "mdarray", "lvmlv"]
-    stage2_device_raid_levels = [mdraid.RAID1]
-
-    packages = ["s390utils"]    # is this bootloader or platform?
-    image_label_attr = "short_label"
-    preserve_args = ["cio_ignore"]
+    stage2_raid_levels = [mdraid.RAID1]
 
     #
     # configuration
@@ -1676,9 +1733,10 @@ class SILO(YabootSILOBase):
     _config_file = "silo.conf"
     message_file = "/etc/silo.message"
 
+    disklabel_types = ["sun"]
+
     # stage1 device requirements
-    stage1_device_types = ["partition"]
-    stage1_device_disklabel_types = ["sun"]
+    stage1_device_types = ["disk"]
 
     # stage2 device requirements
     stage2_device_types = ["partition"]
diff --git a/pyanaconda/dispatch.py b/pyanaconda/dispatch.py
index 092d31f..3fbaa6a 100644
--- a/pyanaconda/dispatch.py
+++ b/pyanaconda/dispatch.py
@@ -72,11 +72,11 @@ installSteps = [
     ("filtertype", ),
     ("filter", ),
     ("storageinit", storageInitialize, ),
-    ("findrootparts", findRootParts, ),
+#    ("findrootparts", findRootParts, ),
     ("findinstall", ),
-    ("network", ),
-    ("timezone", ),
-    ("accounts", ),
+#    ("network", ),
+#    ("timezone", ),
+#    ("accounts", ),
     ("setuptime", setupTimezone, ),
     ("parttype", ),
     ("cleardiskssel", ),
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index a004ae0..f94aefb 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -806,9 +806,14 @@ def get_sysfs_path_by_name(dev_node, class_name="block"):
         (e.g. /sys/class/block/vda2). This also has to work for device nodes
         that are in a subdirectory of /dev like '/dev/cciss/c0d0p1'.
      """
-    dev_name = os.path.basename(dev_node)
-    if dev_node.startswith("/dev/"):
-        dev_name = dev_node[5:].replace("/", "!")
+    dev_name = dev_node
+    if dev_name.startswith("/dev/"):
+        dev_name = dev_node[5:]
+
+    if dev_name.startswith("mapper/"):
+        dev_name = dev_node[7:]
+
+    dev_name = dev_name.replace("/", "!")
     sysfs_class_dir = "/sys/class/%s" % class_name
     dev_path = os.path.join(sysfs_class_dir, dev_name)
     if os.path.exists(dev_path):
diff --git a/pyanaconda/iw/bootloader_main_gui.py b/pyanaconda/iw/bootloader_main_gui.py
index 29d88cc..a7dbcbb 100644
--- a/pyanaconda/iw/bootloader_main_gui.py
+++ b/pyanaconda/iw/bootloader_main_gui.py
@@ -108,7 +108,8 @@ class MainBootloaderWindow(InstallWindow):
             # stage2's type isn't valid as stage1, so don't offer "boot".
             pass
         else:
-            choices["boot"] = (stage2, stage2_desc)
+            if stage2 != stage1:
+                choices["boot"] = (stage2, stage2_desc)
 
         for t in ("mbr", "boot"):
             if not choices.has_key(t):
diff --git a/pyanaconda/iw/lvm_dialog_gui.py b/pyanaconda/iw/lvm_dialog_gui.py
index 9a96d89..1391524 100644
--- a/pyanaconda/iw/lvm_dialog_gui.py
+++ b/pyanaconda/iw/lvm_dialog_gui.py
@@ -446,7 +446,7 @@ class VolumeGroupEditor:
             # File system type lables & combo
             newfstypelabel = createAlignedLabel(_("_File System Type:"))
             newfstypeCombo = createFSTypeMenu(format, fstypechangeCB,mountCombo,
-                    ignorefs = ["mdmember", "lvmpv", "efi", "prepboot", "appleboot"])
+                    ignorefs = ["mdmember", "lvmpv", "efi", "prepboot", "appleboot", "biosboot"])
             newfstypelabel.set_mnemonic_widget(newfstypeCombo)
 
             # Logical Volume name label & entry
@@ -503,7 +503,7 @@ class VolumeGroupEditor:
             # it latter with two arguments, row and mainttable.
             cpefsos = lambda table, row: createPreExistFSOptionSection(templv,
                     maintable, row, mountCombo, self.storage,
-                    ignorefs = ["software RAID", "physical volume (LVM)", "vfat"],
+                    ignorefs = ["software RAID", "physical volume (LVM)", "vfat", "biosboot"],
                     luksdev=templuks)
 
 
diff --git a/pyanaconda/iw/raid_dialog_gui.py b/pyanaconda/iw/raid_dialog_gui.py
index 35f23f9..429b05f 100644
--- a/pyanaconda/iw/raid_dialog_gui.py
+++ b/pyanaconda/iw/raid_dialog_gui.py
@@ -463,7 +463,7 @@ class RaidEditor:
             self.fstypeCombo = createFSTypeMenu(format,
                                                 fstypechangeCB,
                                                 self.mountCombo,
-                                                ignorefs = ["mdmember", "efi", "prepboot", "appleboot"])
+                                                ignorefs = ["mdmember", "efi", "prepboot", "appleboot", "biosboot"])
 	    lbl.set_mnemonic_widget(self.fstypeCombo)
             maintable.attach(self.fstypeCombo, 1, 2, row, row + 1)
             row += 1
diff --git a/pyanaconda/platform.py b/pyanaconda/platform.py
index 6a57b34..50637bf 100644
--- a/pyanaconda/platform.py
+++ b/pyanaconda/platform.py
@@ -19,6 +19,7 @@
 #
 # Authors: Chris Lumens <clumens@redhat.com>
 #
+import parted
 
 from pyanaconda import bootloader
 
@@ -62,7 +63,7 @@ class Platform(object):
     @property
     def bootFSTypes(self):
         """A list of all valid filesystem types for the boot partition."""
-        return self.bootloader.stage2_device_format_types
+        return self.bootloader.stage2_format_types
 
     @property
     def defaultBootFSType(self):
@@ -72,23 +73,38 @@ class Platform(object):
     @property
     def diskLabelTypes(self):
         """A list of valid disklabel types for this architecture."""
-        return self.bootloader.stage1_device_disklabel_types
+        return self.bootloader.disklabel_types
 
     @property
     def defaultDiskLabelType(self):
         """The default disklabel type for this architecture."""
         return self.diskLabelTypes[0]
 
-    def diskLabelType(self, device_type):
-        """The default disklabel type for the specified device type."""
-        return self.defaultDiskLabelType
+    def requiredDiskLabelType(self, device_type):
+        return None
+
+    def bestDiskLabelType(self, device):
+        """The best disklabel type for the specified device."""
+        # if there's a required type for this device type, use that
+        labelType = self.requiredDiskLabelType(device.partedDevice.type)
+        if not labelType:
+            # otherwise, use the first supported type for this platform
+            # that is large enough to address the whole device
+            labelType = self.defaultDiskLabelType
+            for lt in self.diskLabelTypes:
+                l = parted.freshDisk(device=device.partedDevice, ty=lt)
+                if l.maxPartitionStartSector < device.partedDevice.length:
+                    labelType = lt
+                    break
+
+        return labelType
 
     def checkDiskLabel(self, req):
         """Check the disk containing req for the correct disklabel type.
 
            Return a list of error strings if incorrect disklabels are found."""
         errors = []
-        if not self.bootloader.stage1_device_disklabel_types:
+        if not self.bootloader.disklabel_types:
             return errors
 
         for disk in req.disks:
@@ -110,18 +126,18 @@ class Platform(object):
         if not req:
             return [_("You have not created a bootable partition.")]
 
-        # TODO: reimplement BootLoader._device_is_bootable(req, linux=True)
-        #       such that it returns a list of error strings instead of
-        #       True/False
-
         if req.type not in self.bootloader.stage2_device_types:
             errors.append(_("The /boot filesystem cannot be on devices of "
                             "type %s") % req.type)
+
+        constraint = self.bootloader.stage2_device_constraint
+        if not constraint.satisfied(req):
+            errors.append(_("The /boot filesystem %s") % constraint.problems)
         elif req.type == "mdarray":
             raid_levels = self.bootloader.stage2_device_raid_levels
             if req.level not in raid_levels:
                 levels = ",".join(["RAID%d" % l for l in raid_levels])
-                errors.append(_("RAID sets containing the /boot filesystem "
+                errors.append(_("RAID sets containing the /boot filesystem %s")
                                 "must have one of the following raid levels: "
                                 "%s.") % levels)
 
@@ -136,7 +152,7 @@ class Platform(object):
         # things like boot on vfat.
         if not req.format.bootable or \
            req.format.type not in self.bootFSTypes:
-            errors.append(_("The /boot filesystem cannot be of type %s.") % req.format.type)
+            errors.append(_("The /boot filesystem cannot be of type %s.") % req
 
         if req.encrypted:
             # Handle /boot that is, or depends on devices that are, encrypted
@@ -154,7 +170,13 @@ class Platform(object):
         if not req:
             return [_("you have not created a bootloader stage1 target device")]
 
-        return self.checkDiskLabel(req)
+        errors = []
+        if not self.bootloader._is_valid_stage1_device(req):
+            errors.append("The bootloader target device cannot be on devices "
+                          "of type %s" % req.type)
+
+        errors.extend(self.checkDiskLabel(req))
+        return errors
 
     @property
     def minimumSector(self, disk):
@@ -187,6 +209,23 @@ class Platform(object):
 class X86(Platform):
     _bootloaderClass = bootloader.GRUB2
 
+    def setDefaultPartitioning(self):
+        """Return the default platform-specific partitioning information."""
+        from storage.partspec import PartSpec
+        ret = Platform.setDefaultPartitioning(self)
+        ret.append(PartSpec(fstype="biosboot", size=1,
+                            weight=self.weight(fstype="biosboot")))
+        return ret
+
+    def weight(self, fstype=None, mountpoint=None):
+        score = Platform.weight(self, fstype=fstype, mountpoint=mountpoint)
+        if score:
+            return score
+        elif fstype == "biosboot":
+            return 5000
+        else:
+            return 0
+
 class EFI(Platform):
     _bootloaderClass = bootloader.EFIGRUB
 
@@ -291,12 +330,12 @@ class S390(Platform):
                          weight=self.weight(mountpoint="/boot"), asVol=True,
                          singlePV=True)]
 
-    def diskLabelType(self, device_type):
-        """The default disklabel type for the specified device type."""
+    def requiredDiskLabelType(self, device_type):
+        """Required disklabel type for the specified device type."""
         if device_type == "dasd":
             return "dasd"
 
-        return self.defaultDiskLabelType
+        return super(S390, self).requiredDiskLabelType(device_type)
 
 class Sparc(Platform):
     _bootloaderClass = bootloader.SILO
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py
index 6d0933d..3cab92a 100644
--- a/pyanaconda/storage/__init__.py
+++ b/pyanaconda/storage/__init__.py
@@ -193,11 +193,16 @@ def storageComplete(anaconda):
         disks = (anaconda.bootloader.stage1_device.disks
                  + anaconda.bootloader.stage2_device.disks)
         if [d for d in disks if getattr(d.format, "labelType", None) == "gpt"]:
-            warning = _("\n\n<b>WARNING:</b>\n"
-                        "You are using a GPT bootdisk on a non-EFI "
-                        "system. This may not work, depending on your "
-                        "BIOS's support for booting from GPT disks.")
-            log.warning("Using a GPT bootdisk on non-EFI system")
+            # if this is a BIOS x86 system and they have a bios boot partition
+            # things should be fine, so don't warn
+            if not isinstance(anaconda.platform, platform.X86) or \
+               not hasattr(anaconda.bootloader, "gpt_constraint"):
+                # is this even possible anymore?
+                warning = _("\n\n<b>WARNING:</b>\n"
+                            "You are using a GPT bootdisk on a non-EFI "
+                            "system. This may not work, depending on your "
+                            "BIOS's support for booting from GPT disks.")
+                log.warning("Using a GPT bootdisk on non-EFI system")
 
     # Prevent users from installing on s390x with (a) no /boot volume, (b) the
     # root volume on LVM, and (c) the root volume not restricted to a single
diff --git a/pyanaconda/storage/devices.py b/pyanaconda/storage/devices.py
index d450a26..e6907bb 100644
--- a/pyanaconda/storage/devices.py
+++ b/pyanaconda/storage/devices.py
@@ -725,7 +725,9 @@ class StorageDevice(Device):
 
         if self.originalFormat.exists:
             self.originalFormat.teardown()
+
         self.format.cacheMajorminor()
+
         if self.format.exists:
             self.format.teardown()
         udev_settle()
@@ -1145,6 +1147,10 @@ class PartitionDevice(StorageDevice):
                 # the only way to identify a PPC PReP Boot partition is to
                 # check the partition type/flags, so do it here.
                 self.format = getFormat("prepboot", device=self.path, exists=True)
+            elif self.getFlag(parted.PARTITION_BIOS_GRUB):
+                # the only way to identify a BIOS Boot partition is to
+                # check the partition type/flags, so do it here.
+                self.format = getFormat("biosboot", device=self.path, exists=True)
         else:
             # XXX It might be worthwhile to create a shit-simple
             #     PartitionRequest class and pass one to this constructor
diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py
index 72da38c..bc7d248 100644
--- a/pyanaconda/storage/devicetree.py
+++ b/pyanaconda/storage/devicetree.py
@@ -39,6 +39,7 @@ import devicelibs.mpath
 import devicelibs.loop
 from udev import *
 from pyanaconda import iutil
+from pyanaconda import platform
 from pyanaconda import tsort
 from pyanaconda.anaconda_log import log_method_call, log_method_return
 import parted
@@ -168,6 +169,8 @@ class DeviceTree(object):
         self.iscsi = iscsi
         self.dasd = dasd
 
+        self.platform = platform.getPlatform(None)
+
         self.diskImages = {}
         images = getattr(conf, "diskImages", {})
         if images:
@@ -1097,15 +1100,20 @@ class DeviceTree(object):
             initcb = lambda: self.intf.questionInitializeDisk(bypath,
                                                               description,
                                                               device.size)
+
+        labelType = self.platform.bestDiskLabelType(device)
+
         try:
             format = getFormat("disklabel",
                                device=device.path,
+                               labelType=labelType,
                                exists=not initlabel)
         except InvalidDiskLabelError:
             # if we have a cb function use it. else we ignore the device.
             if initcb is not None and initcb():
                 format = getFormat("disklabel",
                                    device=device.path,
+                                   labelType=labelType,
                                    exists=False)
             else:
                 self._removeDevice(device)
diff --git a/pyanaconda/storage/formats/__init__.py b/pyanaconda/storage/formats/__init__.py
index 9336c89..c1f8b88 100644
--- a/pyanaconda/storage/formats/__init__.py
+++ b/pyanaconda/storage/formats/__init__.py
@@ -408,6 +408,11 @@ class DeviceFormat(object):
     def majorminor(self):
         """A string suitable for using as a pseudo-unique ID in kickstart."""
         if not self._majorminor:
+            if not os.path.exists(self.device):
+                log.info("can't collect majorminor for non-existent device %s"
+                            % self.device)
+                return self._majorminor
+
             # If this is a device-mapper device, we have to get the DM node and
             # build the sysfs path from that.
             try:
diff --git a/pyanaconda/storage/formats/disklabel.py b/pyanaconda/storage/formats/disklabel.py
index e986b5e..7db64df 100644
--- a/pyanaconda/storage/formats/disklabel.py
+++ b/pyanaconda/storage/formats/disklabel.py
@@ -26,7 +26,6 @@ import copy
 from pyanaconda.anaconda_log import log_method_call
 import parted
 import _ped
-from pyanaconda import platform
 from ..errors import *
 from ..udev import udev_settle
 from . import DeviceFormat, register_device_format
@@ -50,6 +49,7 @@ class DiskLabel(DeviceFormat):
 
             Keyword Arguments:
 
+                labelType -- type of disklabel to create
                 device -- path to the underlying device
                 exists -- indicates whether this is an existing format
 
@@ -57,6 +57,12 @@ class DiskLabel(DeviceFormat):
         log_method_call(self, *args, **kwargs)
         DeviceFormat.__init__(self, *args, **kwargs)
 
+        if not self.exists:
+            self._labelType = kwargs.get("labelType")
+
+            if not self._labelType:
+                raise ValueError("must specify type for new disklabel")
+
         self._size = None
 
         self._partedDevice = None
@@ -119,10 +125,8 @@ class DiskLabel(DeviceFormat):
 
     def freshPartedDisk(self):
         """ Return a new, empty parted.Disk instance for this device. """
-        log_method_call(self, device=self.device)
-        platf = platform.getPlatform(None)
-        labelType = platf.diskLabelType(self.partedDevice.type)
-        return parted.freshDisk(device=self.partedDevice, ty=labelType)
+        log_method_call(self, device=self.device, labelType=self._labelType)
+        return parted.freshDisk(device=self.partedDevice, ty=self._labelType)
 
     @property
     def partedDisk(self):
@@ -140,6 +144,8 @@ class DiskLabel(DeviceFormat):
                     # same as if the device had no label (cause it really
                     # doesn't).
                     raise InvalidDiskLabelError()
+
+                self._labelType = self._partedDisk.type
             else:
                 self._partedDisk = self.freshPartedDisk()
 
diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py
index bddca32..0e8cb36 100644
--- a/pyanaconda/storage/partitioning.py
+++ b/pyanaconda/storage/partitioning.py
@@ -91,13 +91,25 @@ def _schedulePartitions(storage, disks):
         if request.asVol:
             continue
 
+        log.info("request: %s" % request)
         if request.fstype is None:
             request.fstype = storage.defaultFSType
         elif request.fstype in ("prepboot", "efi") and \
-                storage.platform.bootDevice:
+                storage.platform.bootLoaderDevice:
             # there should never be a need for more than one of these
             # partitions, so skip them.
+            log.info("skipping unneeded stage1 request")
             continue
+        elif request.fstype == "biosboot":
+            boot_disk = storage.platform.bootloader.stage1_drive
+            if boot_disk.format.labelType != "gpt":
+                # biosboot is only needed for gpt disklabels on non-efi x86
+                log.info("skipping bios boot request for msdos disklabel")
+                continue
+            elif storage.platform.bootloader.gpt_constraint.satisfied(boot_disk):
+                # there's already a bios boot partition on the gpt boot disk
+                log.info("skipping bios boot request since boot disk has one")
+                continue
 
         # This is a little unfortunate but let the backend dictate the rootfstype
         # so that things like live installs can do the right thing
@@ -354,7 +366,7 @@ def clearPartitions(storage, bootloader=None):
         # not much to do
         return
 
-    if not hasattr(storage.platform, "diskLabelType"):
+    if not hasattr(storage.platform, "diskLabelTypes"):
         raise StorageError("can't clear partitions without platform data")
 
     # we are only interested in partitions that physically exist
@@ -399,7 +411,9 @@ def clearPartitions(storage, bootloader=None):
                     devices.remove(leaf)
 
             destroy_action = ActionDestroyFormat(disk)
-            newLabel = getFormat("disklabel", device=disk.path)
+            labelType = storage.platform.bestDiskLabelType(disk)
+            newLabel = getFormat("disklabel", device=disk.path,
+                                 labelType=labelType)
             create_action = ActionCreateFormat(disk, format=newLabel)
             storage.devicetree.registerAction(destroy_action)
             storage.devicetree.registerAction(create_action)
@@ -429,7 +443,7 @@ def clearPartitions(storage, bootloader=None):
         if filter(lambda p: p.dependsOn(disk), storage.protectedDevices):
             continue
 
-        nativeLabelType = storage.platform.diskLabelType(disk.partedDevice.type)
+        nativeLabelType = storage.platform.bestDiskLabelType(disk)
         if disk.format.labelType == nativeLabelType:
             continue
 
@@ -444,7 +458,8 @@ def clearPartitions(storage, bootloader=None):
                     storage.devicetree._removeDevice(part, moddisk=False)
 
         destroy_action = ActionDestroyFormat(disk)
-        newLabel = getFormat("disklabel", device=disk.path)
+        newLabel = getFormat("disklabel", device=disk.path,
+                             labelType=nativeLabelType)
         create_action = ActionCreateFormat(disk, format=newLabel)
         storage.devicetree.registerAction(destroy_action)
         storage.devicetree.registerAction(create_action)
@@ -822,7 +837,7 @@ def doPartitioning(storage, bootloader=None):
             bootloader - BootLoader instance
 
     """
-    if not hasattr(storage.platform, "diskLabelType"):
+    if not hasattr(storage.platform, "diskLabelTypes"):
         raise StorageError("can't allocate partitions without platform data")
 
     disks = storage.partitioned
