All pastes #1311998 Raw Edit

alain.diff

public text v1 · immutable
#1311998 ·published 2009-01-18 22:18 UTC
rendered paste body
diff -Naur src/i386/boot0/boot0.s src.new/i386/boot0/boot0.s
--- src/i386/boot0/boot0.s	2009-01-18 07:47:21.000000000 +0100
+++ src.new/i386/boot0/boot0.s	2009-01-18 22:54:03.000000000 +0100
@@ -93,7 +93,8 @@
 kAppleGUID	     EQU  0xACEC4365	; last 4 bytes of Apple type GUIDs. 
 
 ; /* --- BEGIN ADDED ------------------------ */
-kEFISYSGUID	     EQU  0xC93EC93B    ; first 4 bytes of EFI System Partition Type GUID.
+;kEFISYSGUID	     EQU  0xC93EC93B    ; first 4 bytes of EFI System Partition Type GUID.
+kEFISYSGUID	     EQU  0x3BC93EC9    ; first 4 bytes of EFI System Partition Type GUID.
 ; efi system C12A7328-F81F-11D2-BA4B-00A0C93EC93B
 ;/* --- END ADDED --------------------------- */
 
@@ -422,8 +423,8 @@
 
 ; /* --- BEGIN ADDED ------------------------ */
 ; turbo - also try efi system partition
-;    cmp     eax,kEFISYSGUID
-;    je      .gpt_ok
+    cmp     eax,kEFISYSGUID
+    jne      .gpt_continue
 ; /* --- END ADDED --------------------------- */
 ; /* --- BEGIN COMMENTED --------------------- */
 ;    cmp	    eax, kAppleGUID				; check current GUID Partition for Apple's GUID type
diff -Naur src/i386/boot2/options.c src.new/i386/boot2/options.c
--- src/i386/boot2/options.c	2009-01-18 17:31:19.000000000 +0100
+++ src.new/i386/boot2/options.c	2009-01-18 21:29:35.000000000 +0100
@@ -35,7 +35,10 @@
 
 enum {
     kMenuTopRow    = 5,
-    kMenuMaxItems  = 10,
+/* --- BEGIN ADDED ------------------------ */
+    // kMenuMaxItems  = 10,
+    kMenuMaxItems  = 6,
+/* --- END ADDED --------------------------- */    
     kScreenLastRow = 24
 };
 
@@ -515,22 +518,42 @@
             // Default to F8.
             optionKey = 0x4200;
         }
+/* --- BEGIN ADDED ------------------------ */
+        // key = countdown(prompt, kMenuTopRow, timeout);
 
-        key = countdown(prompt, kMenuTopRow, timeout);
+        // If the timeout is zero then it must have been set above due to the
+        // early catch of F8 which means the user wants to set boot options
+        // which we ought to interpret as meaning he wants to boot the CD.
+        if(timeout != 0)
+            key = countdown(prompt, kMenuTopRow, timeout);
+        else
+            key = optionKey;
+/* --- END ADDED --------------------------- */        
         if (cnt)
             free(prompt);
 
         clearScreenRows( kMenuTopRow, kMenuTopRow + 2 );
-
-        if (key == 0) {
+/* --- BEGIN ADDED ------------------------ */
+        // if (key == 0) {
+        if ( (key == 'h' || key == 'H') ) {
+/* --- END ADDED --------------------------- */
             // Boot from hard disk.
             // Scan the original device 0x80.
 
             BVRef hd_bvr = selectBootVolume(scanBootVolumes(0x80, 0));
-            if ( hd_bvr->flags & kBVFlagNativeBoot ) {
+/* --- BEGIN ADDED ------------------------ */            
+            // if ( hd_bvr->flags & kBVFlagNativeBoot ) {
+            if ( hd_bvr != NULL && hd_bvr->flags & kBVFlagNativeBoot ) {
+/* --- END ADDED --------------------------- */            
                 gBootVolume = hd_bvr;
+/* --- BEGIN ADDED ------------------------ */
+                setRootVolume(hd_bvr);
+/* --- END ADDED --------------------------- */
                 gBIOSDev = hd_bvr->biosdev;
-                initKernBootStruct( gBIOSDev );
+/* --- BEGIN ADDED ------------------------ */                
+                // initKernBootStruct( gBIOSDev );
+                // FIXME: This skips the boot menu.. do we want to do that?
+/* --- END ADDED --------------------------- */                
                 goto done;
             }
         } else  {
@@ -635,6 +658,11 @@
                 break;
 
             case kEscapeKey:
+/* --- BEGIN ADDED ------------------------ */
+                // Apple behavior: Leave gBootVolume as is which causes the default choice to be booted
+                // New behavior: Clear gBootVolume to restart the loop.
+                gBootVolume = NULL;
+/* --- END ADDED --------------------------- */            
                 clearBootArgs();
                 break;
 
@@ -761,15 +789,22 @@
 
             return 1;
         }
-
-        bootInfo->kernDev &= ~((B_UNITMASK << B_UNITSHIFT ) |
-                          (B_PARTITIONMASK << B_PARTITIONSHIFT));
-
-        bootInfo->kernDev |= MAKEKERNDEV(    0,
- 		         /* unit */      BIOS_DEV_UNIT(gBootVolume),
-                        /* partition */ gBootVolume->part_no );
-    }
-
+/* --- BEGIN ADDED ------------------------ */
+        // bootInfo->kernDev &= ~((B_UNITMASK << B_UNITSHIFT ) |
+        //                  (B_PARTITIONMASK << B_PARTITIONSHIFT));
+
+        // bootInfo->kernDev |= MAKEKERNDEV(    0,
+ 		         /* unit */  //    BIOS_DEV_UNIT(gBootVolume),
+                        /* partition */ // gBootVolume->part_no );
+        setRootVolume(gBootVolume);                
+/* --- END ADDED --------------------------- */
+    }
+/* --- BEGIN ADDED ------------------------ */
+    // If no boot volume fail immediately because we're just going to fail
+    // trying to load the config file anyway.
+    else
+        return -1;
+/* --- END ADDED --------------------------- */
     // Load config table specified by the user, or use the default.
 
     if (getValueForBootKey( cp, "config", &val, &cnt ) == FALSE) {
@@ -849,15 +884,15 @@
         strlcpy( gRootDevice, val, (cnt + 1));
     }
 
+/* ---- NOT COMMENTED IN V61 -------------------*/
     /*
      * Disabled to increase compatibility with some kernel versions when using EFI services.
-     *
+     */
     if (!processBootArgument(kPlatformKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gPlatformName)) {
         getPlatformName(gPlatformName);
         copyArgument(kPlatformKey, gPlatformName, strlen(gPlatformName), &argP, &cntRemaining);
     }
-    */
-
+/* ---- END NOT COMMENTED ----------------------*/
     if (!getValueForBootKey(cp, kSafeModeFlag, &val, &cnt) &&
         !getValueForBootKey(configKernelFlags, kSafeModeFlag, &val, &cnt)) {
         if (gBootMode & kBootModeSafe) {
@@ -987,4 +1022,83 @@
         free(buffer);
         setActiveDisplayPage(0);
     }
+/* --- BEGIN ADDED ------------------------ */
+}
+
+static inline int isHexDigit(char ch)
+{
+    return ('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'F') || ('a' <= ch && ch <= 'f');
+}
+
+// This is a very simplistic prompting scheme that just grabs two hex characters
+// Eventually we need to do something more user-friendly like display a menu
+// based off of the Multiboot device list
+int selectAlternateBootDevice(int bootdevice)
+{
+    int digitsI = 0;
+    char digits[3] = {0,0,0};
+    
+    // We've already printed the current boot device so user knows what it is
+    printf("Typical boot devices are 80 (First HD), 81 (Second HD)\n");
+    printf("Enter two-digit hexadecimal boot device [%02x]: ", bootdevice);
+    int key = 0;
+    do {
+        key = getc();
+        switch(key & kASCIIKeyMask)
+        {
+        case kBackspaceKey:
+            if(digitsI > 0)
+            {
+                int x, y, t;
+                getCursorPositionAndType(&x, &y, &t);
+                // Assume x is not 0;
+                x--;
+                setCursorPosition(x,y,0); // back up one char
+                // Overwrite with space without moving cursor position
+                putca(' ', 0x07, 1);
+                digitsI--;
+            }
+            else
+            {
+                // TODO: Beep or something
+            }
+            break;
+        case kReturnKey:
+            if(1)
+            {
+                digits[digitsI] = '\0';
+                char *end;
+                int newbootdevice = strtol(digits, &end, 16);
+                if(end == digits && *end == '\0') // User entered empty string
+                {
+                    printf("\nUsing default boot device %x\n", bootdevice);
+                    key = 0;
+                }
+                else if(end != digits && *end == '\0')
+                {
+                    bootdevice = newbootdevice;
+                    printf("\n");
+                    key = 0; // We gots da boot device
+                }
+                else
+                {
+                    printf("\nCouldn't parse. try again: ");
+                    digitsI = 0;
+                }
+            }
+            break;
+        default:
+            if( isHexDigit(key & kASCIIKeyMask) && digitsI < 2 )
+            {
+                putc(key & kASCIIKeyMask);
+                digits[digitsI++] = key & kASCIIKeyMask;
+            }
+            else
+            {
+                // TODO: Beep or something
+            }
+        };
+    } while(key != 0);
+    return bootdevice;
+/* --- END ADDED --------------------------- */
 }
diff -Naur src/i386/boot2/prompt.c src.new/i386/boot2/prompt.c
--- src/i386/boot2/prompt.c	2009-01-18 18:33:55.000000000 +0100
+++ src.new/i386/boot2/prompt.c	2009-01-18 18:27:07.000000000 +0100
@@ -29,7 +29,7 @@
 #include "vers.h"
 
 char bootBanner[] = "\nDarwin/x86 boot v" I386BOOT_VERSION "\n"
- //                   "Build date: " I386BOOT_BUILDDATE "\n"
+// Build date: " I386BOOT_BUILDDATE "\n"
                     "%dMB memory\n";
 
 char bootPrompt[] =
diff -Naur src/i386/libsaio/disk.c src.new/i386/libsaio/disk.c
--- src/i386/libsaio/disk.c	2009-01-18 17:01:20.000000000 +0100
+++ src.new/i386/libsaio/disk.c	2009-01-18 22:10:19.000000000 +0100
@@ -43,24 +43,43 @@
  * Copyright 1993 NeXT Computer, Inc.
  * All rights reserved.
  */
-
-#define UFS_SUPPORT 0
-
+/* --- BEGIN ADDED ------------------------ */
+// #define UFS_SUPPORT 0
+// Allow UFS_SUPPORT to be overridden with preprocessor option.
+#ifndef UFS_SUPPORT
+#define UFS_SUPPORT 1
+#endif
+/* --- END ADDED -------------------------- */
 #include "bootstruct.h"
 #include "libsaio.h"
 #include "fdisk.h"
-#include "guid.h"
+/* --- BEGIN REMOVED IN V61 ----------------- */
+// #include "guid.h"
+/* --- END REMOVED IN V61 ------------------- */
 #if UFS_SUPPORT
 #include "ufs.h"
 #endif
 #include "hfs.h"
 #include "ntfs.h"
-#include "ntfs_private.h"
+/* --- BEGIN REMOVED IN V61 ----------------- */
+// #include "ntfs_private.h"
+/* --- END REMOVED IN V61 ------------------- */
 #include "msdos.h"
 
 #include <limits.h>
 #include <IOKit/storage/IOApplePartitionScheme.h>
 
+/* --- BEGIN ADDED ------------------------ */
+#include <IOKit/storage/IOGUIDPartitionScheme.h>
+typedef struct gpt_hdr gpt_hdr;
+typedef struct gpt_ent gpt_ent;
+
+// For EFI_GUID
+#include <pexpert/i386/efi.h>
+#include "efi_tables.h"
+
+/* --- END ADDED -------------------------- */
+
 #define BPS              512     /* sector size of the device */
 #define CD_BPS           2048    /* CD-ROM block size */
 #define N_CACHE_SECS     (BIOS_LEN / BPS)  /* Must be a multiple of 4 for CD-ROMs */
@@ -441,6 +460,9 @@
                             FSGetFileBlock getBlockFunc,
                             FSGetUUID getUUIDFunc,
                             BVGetDescription getDescriptionFunc,
+/* --- BEGIN ADDED ------------------------ */
+                            BVFree bvFreeFunc,
+/* --- END ADDED -------------------------- */                              
                             int probe, int type )
 {
     BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
@@ -458,10 +480,13 @@
         bvr->fs_getfileblock= getBlockFunc;
         bvr->fs_getuuid     = getUUIDFunc;
         bvr->description    = getDescriptionFunc ?
-            getDescriptionFunc : getVolumeDescription;
-	bvr->type           = type;
-
-        if ( part->bootid & FDISK_ACTIVE )
+        getDescriptionFunc : getVolumeDescription;
+	      bvr->type           = type;
+/* --- BEGIN ADDED ------------------------ */
+        bvr->bv_free        = bvFreeFunc;
+/* --- END ADDED -------------------------- */ 	      
+	      
+	     if ( part->bootid & FDISK_ACTIVE )
             bvr->flags |= kBVFlagPrimary;
 
         // Probe the filesystem.
@@ -476,14 +501,18 @@
 
                 DEBUG_DISK(("%s: failed probe on dev %x part %d\n",
                             __FUNCTION__, biosdev, partno));
-
-                free(bvr);
+/* --- BEGIN ADDED ------------------------ */
+                // free(bvr);
+                (*bvr->bv_free)(bvr);
+/* --- END ADDED -------------------------- */                
                 bvr = NULL;
             }
-            if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
+/* --- BEGIN REMOVED IN V61 ----------------- */
+            /*if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
             {
             	bvr->flags |= kBVFlagBootableHFSPVol;
-            }
+            }*/
+/* --- END REMOVED IN V61 ------------------- */            
         }
         else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
         {
@@ -491,7 +520,10 @@
         }
         else
         {
-            free(bvr);
+/* --- BEGIN REMOVED IN V61 ----------------- */
+           //  free(bvr);
+           (*bvr->bv_free)(bvr);
+/* --- END REMOVED IN V61 ------------------- */            
             bvr = NULL;
         }
     }
@@ -508,6 +540,9 @@
                    FSGetFileBlock getBlockFunc,
                    FSGetUUID getUUIDFunc,
                    BVGetDescription getDescriptionFunc,
+/* --- BEGIN ADDED ------------------------ */
+                   BVFree bvFreeFunc,
+/* --- END ADDED -------------------------- */                   
                    int probe, int type )
 {
     BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
@@ -524,8 +559,12 @@
         bvr->fs_getfileblock= getBlockFunc;
         bvr->fs_getuuid     = getUUIDFunc;
         bvr->description    = getDescriptionFunc ?
-            getDescriptionFunc : getVolumeDescription;
-	bvr->type           = type;
+        getDescriptionFunc : getVolumeDescription;
+	      bvr->type           = type;
+/* --- BEGIN ADDED ------------------------ */
+        bvr->bv_free        = bvFreeFunc;
+/* --- END ADDED -------------------------- */ 	      
+	      
         strlcpy(bvr->name, part->dpme_name, DPISTRLEN);
         strlcpy(bvr->type_name, part->dpme_type, DPISTRLEN);
 
@@ -538,7 +577,10 @@
 
         if ( initFunc )
         {
-            bvr->flags |= kBVFlagNativeBoot | kBVFlagBootableHFSPVol;
+/* --- BEGIN ADDED ------------------------ */
+            // bvr->flags |= kBVFlagNativeBoot | kBVFlagBootableHFSPVol;
+            bvr->flags |= kBVFlagNativeBoot;
+/* --- END ADDED -------------------------- */            
 
             if ( probe && initFunc( bvr ) != 0 )
             {
@@ -547,7 +589,10 @@
                 DEBUG_DISK(("%s: failed probe on dev %x part %d\n",
                             __FUNCTION__, biosdev, partno));
 
-                free(bvr);
+/* --- BEGIN ADDED ------------------------ */
+                // free(bvr);
+                (*bvr->bv_free)(bvr);
+/* --- END ADDED -------------------------- */
                 bvr = NULL;
             }
         }
@@ -559,7 +604,10 @@
         */
         else
         {
-            free(bvr);
+/* --- BEGIN ADDED ------------------------ */
+            // free(bvr);
+            (*bvr->bv_free)(bvr);
+/* --- END ADDED -------------------------- */
             bvr = NULL;
         }
     }
@@ -568,9 +616,22 @@
 
 //==========================================================================
 
-static BVRef diskScanGUIDBootVolumes(int biosdev, int *countPtr)
+/* --- BEGIN ADDED ------------------------ */
+// static BVRef diskScanGUIDBootVolumes(int biosdev, int *countPtr)
+BVRef newGPTBVRef( int biosdev, int partno, unsigned int blkoff,
+                   const gpt_ent * part,
+                   FSInit initFunc, FSLoadFile loadFunc,
+                   FSReadFile readFunc,
+                   FSGetDirEntry getdirFunc,
+                   FSGetFileBlock getBlockFunc,
+                   FSGetUUID getUUIDFunc,
+                   BVGetDescription getDescriptionFunc,
+                   BVFree bvFreeFunc,
+                   int probe, int type )
+/* --- END ADDED -------------------------- */                   
 {
-	const struct fdisk_part		*part;
+/* --- BEGIN REMOVED IN V61 ----------------- */
+/*	const struct fdisk_part		*part;
 	struct DiskBVMap			*map = NULL;
 	int							error;
 	int							i;
@@ -584,16 +645,78 @@
 	const struct GUIDPartEntry	*guid_part;
 	static struct fdisk_part	*fake_fdisk_part;
 	const void					*part_bootsector;		// Buffer for NTFS signature check
-	const struct bootfile		*part_bootfile;			// NTFS boot sector structure
+	const struct bootfile		*part_bootfile;			// NTFS boot sector structure */
 	
     /* Initialize disk info */
-    if (getDriveInfo(biosdev, &di) != 0)
+    /* if (getDriveInfo(biosdev, &di) != 0)
+    
     {
 		return NULL;
+    } */
+/* --- END REMOVED IN V61 ------------------- */
+
+/* --- BEGIN ADDED ------------------------ */
+    BVRef bvr = (BVRef) malloc( sizeof(*bvr) );
+
+    if ( bvr )
+    {
+        bzero(bvr, sizeof(*bvr));
+
+        bvr->biosdev        = biosdev;
+        bvr->part_no        = partno;
+        bvr->part_boff      = blkoff;
+        bvr->fs_loadfile    = loadFunc;
+        bvr->fs_readfile    = readFunc;
+        bvr->fs_getdirentry = getdirFunc;
+        bvr->fs_getfileblock= getBlockFunc;
+        bvr->fs_getuuid     = getUUIDFunc;
+        bvr->description    = getDescriptionFunc ?
+            getDescriptionFunc : getVolumeDescription;
+	bvr->type           = type;
+        bvr->bv_free        = bvFreeFunc;
+        // FIXME: UCS-2 -> UTF-8 the name
+        strlcpy(bvr->name, "----", DPISTRLEN);
+        strlcpy(bvr->type_name, "GPT HFS+", DPISTRLEN);
+
+        /*
+        if ( part->bootid & FDISK_ACTIVE )
+            bvr->flags |= kBVFlagPrimary;
+        */
+
+        // Probe the filesystem.
+
+        if ( initFunc )
+        {
+            bvr->flags |= kBVFlagNativeBoot;
+
+            if ( probe && initFunc( bvr ) != 0 )
+            {
+                // filesystem probe failed.
+
+                DEBUG_DISK(("%s: failed probe on dev %x part %d\n",
+                            __FUNCTION__, biosdev, partno));
+
+                (*bvr->bv_free)(bvr);
+                bvr = NULL;
+            }
+        }
+        /*
+        else if ( readBootSector( biosdev, blkoff, (void *)0x7e00 ) == 0 )
+        {
+            bvr->flags |= kBVFlagForeignBoot;
+        }
+        */
+        else
+        {
+            (*bvr->bv_free)(bvr);
+            bvr = NULL;
+        }
     }
+/* --- END ADDED -------------------------- */
 
+/* --- BEGIN REMOVED IN V61 ----------------- */
 	/* Scan for Protective MBR partition type (0xEE). */
-	while (getNextFDiskPartition(biosdev, &partno, &part))
+	/* while (getNextFDiskPartition(biosdev, &partno, &part))
 	{
 		if (part->systid == GUID_TYPE_PMBR)
 		{
@@ -714,7 +837,11 @@
     return map ? map->bvr : NULL;
 
 error_exit:
-	return NULL;
+	return NULL; */
+/* --- END REMOVED IN V61 ------------------- */
+/* --- BEGIN ADDED ------------------------ */
+  return bvr;
+/* --- END ADDED -------------------------- */
 }
 
 //==========================================================================
@@ -733,12 +860,26 @@
     int                       partno  = -1;
     BVRef                     bvr;
     struct driveInfo          di;
-
+/* --- BEGIN ADDED ------------------------ */
+#if UFS_SUPPORT
+    BVRef                     booterUFS = NULL;
+#endif
+    int                       spc;
+    boot_drive_info_t         *dp;
+/* --- END ADDED -------------------------- */    
+    
     /* Initialize disk info */
     if (getDriveInfo(biosdev, &di) != 0) {
 	return NULL;
     }
-
+/* --- BEGIN ADDED ------------------------ */
+    dp = &di.di;
+    spc = (dp->params.phys_spt * dp->params.phys_heads);
+    if (spc == 0) {
+	  /* This is probably a CD-ROM; punt on the geometry. */
+	  spc = 1;
+    }
+/* --- END ADDED -------------------------- */
     do {
         // Create a new mapping.
 
@@ -761,6 +902,26 @@
 
                 switch ( part->systid )
                 {
+/* --- BEGIN ADDED ------------------------ */                
+#if UFS_SUPPORT
+                    case FDISK_UFS:
+                       bvr = newFDiskBVRef(
+                                      biosdev, partno,
+                                      part->relsect + UFS_FRONT_PORCH/BPS,
+                                      part,
+                                      UFSInitPartition,
+                                      UFSLoadFile,
+                                      UFSReadFile,
+                                      UFSGetDirEntry,
+                                      UFSGetFileBlock,
+                                      UFSGetUUID,
+                                      UFSGetDescription,
+                                      UFSFree,
+                                      0,
+				                              kBIOSDevTypeHardDrive);
+                        break;
+#endif
+/* --- BEGIN ADDED ------------------------ */                
                     case FDISK_HFS:
                         bvr = newFDiskBVRef(
                                       biosdev, partno,
@@ -773,9 +934,51 @@
                                       HFSGetFileBlock,
                                       HFSGetUUID,
                                       HFSGetDescription,
+/* --- BEGIN ADDED ------------------------ */
+                                      HFSFree,
+/* --- END ADDED --------------------------- */                                      
+                                      0,
+				                              kBIOSDevTypeHardDrive);
+                        break;
+/* --- BEGIN ADDED ------------------------ */
+                    // turbo - we want the booter type scanned also
+                    case FDISK_BOOTER:
+                        if (part->bootid & FDISK_ACTIVE)
+                        gBIOSBootVolume = newFDiskBVRef(
+                                      biosdev, partno,
+                                      part->relsect,
+                                      part,
+                                      HFSInitPartition,
+                                      HFSLoadFile,
+                                      HFSReadFile,
+                                      HFSGetDirEntry,
+                                      HFSGetFileBlock,
+                                      HFSGetUUID,
+                                      HFSGetDescription,
+                                      HFSFree,
                                       0,
 				      kBIOSDevTypeHardDrive);
                         break;
+#if 0==1
+//#if UFS_SUPPORT
+                    case FDISK_BOOTER:
+                        booterUFS = newFDiskBVRef(
+                                      biosdev, partno,
+                                      ((part->relsect + spc - 1) / spc) * spc,
+                                      part,
+                                      UFSInitPartition,
+                                      UFSLoadFile,
+                                      UFSReadFile,
+                                      UFSGetDirEntry,
+                                      UFSGetFileBlock,
+                                      UFSGetUUID,
+                                      UFSGetDescription,
+                                      UFSFree,
+                                      0,
+				      kBIOSDevTypeHardDrive);
+                        break;
+#endif
+/* --- END ADDED --------------------------- */
 
                    case FDISK_NTFS:
                         bvr = newFDiskBVRef(
@@ -784,8 +987,11 @@
                                       part,
                                       0, 0, 0, 0, 0, 0,
                                       NTFSGetDescription,
+/* --- BEGIN ADDED ------------------------ */
+                                      (BVFree)free,
+/* --- END ADDED --------------------------- */
                                       0,
-				      kBIOSDevTypeHardDrive);
+				                              kBIOSDevTypeHardDrive);
                         break;
                     
                     default:
@@ -793,7 +999,11 @@
                                       biosdev, partno,
                                       part->relsect,
                                       part,
-                                      0, 0, 0, 0, 0, 0, 0, 0,
+                                      0, 0, 0, 0, 0, 0, 0,
+/* --- BEGIN ADDED ------------------------ */
+                                      (BVFree)free,
+/* --- END ADDED --------------------------- */                                      
+                                      0,
 				      kBIOSDevTypeHardDrive);
                         break;
                 }
@@ -805,9 +1015,64 @@
                     map->bvrcnt++;
                 }
             }
+/* --- BEGIN ADDED ------------------------ */
+#if UFS_SUPPORT
+            // Booting from a CD with an UFS filesystem embedded
+            // in a booter partition.
+
+            if ( booterUFS )
+            {
+                if ( map->bvrcnt == 0 )
+                {
+                    map->bvr = booterUFS;
+                    map->bvrcnt++;
+                }
+                else free( booterUFS );
+            }
+#endif
+/* --- END ADDED --------------------------- */            
         }
     } while (0);
-
+/* --- BEGIN ADDED ------------------------ */
+    /*
+     * If no FDisk partition, then we will check for
+     * an Apple partition map elsewhere.
+     */
+#if UNUSED
+    if (map->bvrcnt == 0) {
+	static struct fdisk_part cdpart;
+	cdpart.systid = 0xCD;
+
+	/* Let's try assuming we are on a hybrid HFS/ISO9660 CD. */
+	bvr = newFDiskBVRef(
+			    biosdev, 0,
+			    0,
+			    &cdpart,
+			    HFSInitPartition,
+			    HFSLoadFile,
+                            HFSReadFile,
+			    HFSGetDirEntry,
+                            HFSGetFileBlock,
+                            HFSGetUUID,
+			    0,
+			    kBIOSDevTypeHardDrive);
+	bvr->next = map->bvr;
+	map->bvr = bvr;
+	map->bvrcnt++;
+    }
+#endif
+    // Actually this should always be true given the above code
+    if(map == gDiskBVMap)
+    {
+        // Don't leave a null map in the chain
+        if(map->bvrcnt == 0 && map->bvr == NULL)
+        {
+            gDiskBVMap = map->next;
+            free(map);
+            map = NULL;
+        }
+    }
+/* --- END ADDED --------------------------- */
     if (countPtr) *countPtr = map ? map->bvrcnt : 0;
 
     return map ? map->bvr : NULL;
@@ -887,6 +1152,9 @@
                                       HFSGetFileBlock,
                                       HFSGetUUID,
                                       HFSGetDescription,
+/* --- BEGIN ADDED ------------------------ */
+                                      HFSFree,
+/* --- END ADDED --------------------------- */
                                       0,
                                       kBIOSDevTypeHardDrive);
                     bvr->next = map->bvr;
@@ -896,7 +1164,7 @@
             }
         }
     } while (0);
-
+/* --- BEGIN ADDED ------------------------ */
     free(buffer);
 
     if (countPtr) *countPtr = map ? map->bvrcnt : 0;
@@ -906,6 +1174,222 @@
 
 //==========================================================================
 
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+static bool isPartitionUsed(gpt_ent * partition)
+{
+    //
+    // Ask whether the given partition is used.
+    //
+
+    return efi_guid_is_null((EFI_GUID const*)partition->ent_type) ? false : true;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+// HFS+ GUID in LE form
+EFI_GUID const GPT_HFS_GUID	= { 0x48465300, 0x0000, 0x11AA, { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } };
+
+/* --- BEGIN ADDED ------------------------ */
+
+// turbo - also our booter partition
+EFI_GUID const GPT_BOOT_GUID	= { 0x426F6F74, 0x0000, 0x11AA, { 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC } };
+// turbo - or an efi system partition
+EFI_GUID const GPT_EFISYS_GUID	= { 0xC12A7328, 0xF81F, 0x11D2, { 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B } };
+//C12A7328-F81F-11D2-BA4B-00A0C93EC93B
+
+/* --- END ADDED --------------------------- */
+
+static BVRef diskScanGPTBootVolumes( int biosdev, int * countPtr )
+{
+    struct DiskBVMap *        map = NULL;
+    void *buffer = malloc(BPS);
+    int error;
+    if ( error = readBytes( biosdev, /*secno*/0, 0, BPS, buffer ) != 0) {
+        verbose("Failed to read boot sector from BIOS device %02xh. Error=%d\n", biosdev, error);
+        goto scanErr;
+    }
+    struct REAL_disk_blk0 *fdiskMap = buffer;
+    if ( OSSwapLittleToHostInt16(fdiskMap->signature) != DISK_SIGNATURE )
+    {
+        verbose("Failed to find boot signature on BIOS device %02xh\n", biosdev);
+        goto scanErr;
+    }
+
+    int fdiskID = 0;
+    unsigned index;
+    for ( index = 0; index < FDISK_NPART; index++ )
+    {
+        if ( fdiskMap->parts[index].systid )
+        {
+            if ( fdiskMap->parts[index].systid == 0xEE )
+            {
+                // Fail if two 0xEE partitions are present which
+                // means the FDISK code will wind up parsing it.
+                if ( fdiskID )  goto scanErr;
+
+                fdiskID = index + 1;
+            }
+        }
+    }
+
+    if ( fdiskID == 0 )  goto scanErr;
+    verbose("Attempting to read GPT\n");
+
+    if(readBytes(biosdev, 1, 0, BPS, buffer) != 0)
+        goto scanErr;
+    
+    gpt_hdr *headerMap = buffer;
+
+    // Determine whether the partition header signature is present.
+
+    if ( memcmp(headerMap->hdr_sig, GPT_HDR_SIG, strlen(GPT_HDR_SIG)) )
+    {
+        goto scanErr;
+    }
+
+    // Determine whether the partition header size is valid.
+
+    UInt32 headerCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_self);
+    UInt32 headerSize  = OSSwapLittleToHostInt32(headerMap->hdr_size);
+
+    if ( headerSize < offsetof(gpt_hdr, padding) )
+    {
+        goto scanErr;
+    }
+
+    if ( headerSize > BPS )
+    {
+        goto scanErr;
+    }
+
+    // Determine whether the partition header checksum is valid.
+
+    headerMap->hdr_crc_self = 0;
+
+    if ( crc32(0, headerMap, headerSize) != headerCheck )
+    {
+        goto scanErr;
+    }
+
+    // Determine whether the partition entry size is valid.
+
+    UInt64                     gptBlock       = 0;
+    UInt32                     gptCheck       = 0;
+    UInt32                     gptCount       = 0;
+    UInt32                     gptID          = 0;
+    gpt_ent *                  gptMap         = 0;
+    UInt32                     gptSize        = 0;
+
+    gptBlock = OSSwapLittleToHostInt64(headerMap->hdr_lba_table);
+    gptCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_table);
+    gptCount = OSSwapLittleToHostInt32(headerMap->hdr_entries);
+    gptSize  = OSSwapLittleToHostInt32(headerMap->hdr_entsz);
+
+    if ( gptSize < sizeof(gpt_ent) )
+    {
+        goto scanErr;
+    }
+
+    // Allocate a buffer large enough to hold one map, rounded to a media block.
+    free(buffer);
+    buffer = NULL;
+
+    UInt32 bufferSize = IORound(gptCount * gptSize, BPS);
+    if(bufferSize == 0)
+        goto scanErr;
+    buffer = malloc(bufferSize);
+
+    if(readBytes(biosdev, gptBlock, 0, bufferSize, buffer) != 0)
+        goto scanErr;
+
+    verbose("Read GPT\n");
+
+    // Allocate a new map for this BIOS device and insert it into the chain
+    map = malloc(sizeof(*map));
+    map->biosdev = biosdev;
+    map->bvr = NULL;
+    map->bvrcnt = 0;
+    map->next = gDiskBVMap;
+    gDiskBVMap = map;
+
+    for(gptID = 1; gptID <= gptCount; ++gptID)
+    {
+        // size on disk can be larger than sizeof(gpt_ent)
+        gptMap = (gpt_ent *) ( buffer + ( (gptID - 1) * gptSize)  );
+
+        // NOTE: EFI_GUID's are in LE and we know we're on an x86.
+        // The IOGUIDPartitionScheme.cpp code uses byte-based UUIDs, we don't.
+
+        if(isPartitionUsed(gptMap))
+        {
+            char stringuuid[100];
+            efi_guid_unparse_upper((EFI_GUID*)gptMap->ent_type, stringuuid);
+            verbose("Reading GPT partition %d, type %s\n", gptID, stringuuid);
+            if(efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const*)gptMap->ent_type) == 0)
+            {
+                BVRef bvr = newGPTBVRef(biosdev,
+                                      gptID,
+                                      gptMap->ent_lba_start,
+                                      gptMap,
+                                      HFSInitPartition,
+                                      HFSLoadFile,
+                                      HFSReadFile,
+                                      HFSGetDirEntry,
+                                      HFSGetFileBlock,
+                                      HFSGetUUID,
+                                      HFSGetDescription,
+                                      HFSFree,
+                                      0,
+                                      kBIOSDevTypeHardDrive);
+                bvr->next = map->bvr;
+                map->bvr = bvr;
+                ++map->bvrcnt;
+            }
+
+            // turbo - save our booter partition
+            if ( (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ||
+                 (efi_guid_compare(&GPT_EFISYS_GUID, (EFI_GUID const*)gptMap->ent_type) == 0) ) {
+                  gBIOSBootVolume = newGPTBVRef(
+                                      biosdev, gptID,
+                                      gptMap->ent_lba_start,
+                                      gptMap,
+                                      HFSInitPartition,
+                                      HFSLoadFile,
+                                      HFSReadFile,
+                                      HFSGetDirEntry,
+                                      HFSGetFileBlock,
+                                      HFSGetUUID,
+                                      HFSGetDescription,
+                                      HFSFree,
+                                      0,
+				      kBIOSDevTypeHardDrive);
+            }
+        }
+    }
+scanErr:
+/* --- END ADDED --------------------------- */
+
+    free(buffer);
+/* --- BEGIN ADDED ------------------------ */
+    // if (countPtr) *countPtr = map ? map->bvrcnt : 0;
+    // return map ? map->bvr : NULL;
+    if(map)
+    {
+        if(countPtr) *countPtr = map->bvrcnt;
+
+        return map->bvr;
+    }
+    else
+    {
+        if(countPtr) *countPtr = 0;
+        return NULL;
+    }
+/* --- END ADDED --------------------------- */
+}
+
+//==========================================================================
+
 struct DiskBVMap* diskResetBootVolumes(int biosdev)
 {
     struct DiskBVMap *        map;
@@ -962,12 +1446,20 @@
     }
 
     if (map == NULL) {
-		bvr = diskScanGUIDBootVolumes(biosdev, &count);
+/* --- BEGIN ADDED ------------------------ */    
+		/* bvr = diskScanGUIDBootVolumes(biosdev, &count);
 		if (bvr == NULL) {
 			bvr = diskScanFDiskBootVolumes(biosdev, &count);
 			if (bvr == NULL) {
 				bvr = diskScanAPMBootVolumes(biosdev, &count);
-			}
+			}*/
+        bvr = diskScanGPTBootVolumes(biosdev, &count);
+        if (bvr == NULL) {
+            bvr = diskScanFDiskBootVolumes(biosdev, &count);
+        }
+        if (bvr == NULL) {
+            bvr = diskScanAPMBootVolumes(biosdev, &count);			
+/* --- END ADDED --------------------------- */		
 		}
     } else {
         bvr = map->bvr;
diff -Naur src/i386/libsaio/fake_efi.c src.new/i386/libsaio/fake_efi.c
--- src/i386/libsaio/fake_efi.c	2009-01-18 17:33:16.000000000 +0100
+++ src.new/i386/libsaio/fake_efi.c	2009-01-18 22:35:21.000000000 +0100
@@ -579,7 +579,7 @@
         " outb	%%al,$0x42	\n\t"
         " movb	%%dh,%%al	\n\t"
         " outb	%%al,$0x42"
-        : : "d"(value) /*: no clobber */ /*);
+        : : "d"(value) */ /*: no clobber */ /*);
 }*/
 
 /* Returns the number of times the loop ran before the PIT2 signaled */
@@ -591,7 +591,7 @@
         ++count;
         __asm__ volatile(
             "inb	$0x61,%0"
-        : "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber *//*);
+        : "=q"(nmi_sc_val) */ /*:*/ /* no input */ /*:*/ /* no clobber *//*);
      } while( (nmi_sc_val & 0x20) == 0);
     return count;
 } */
@@ -601,8 +601,7 @@
 
 // DFE: These two constants come from Linux except CLOCK_TICK_RATE replaced with CLKNUM
 // #define CALIBRATE_TIME_MSEC 30 /* 30 msecs */
-// #define CALIBRATE_LATCH	\
-//	((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
+// #define CALIBRATE_LATCH ((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
 
 /*
  * Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer
diff -Naur src/i386/libsaio/fdisk.h src.new/i386/libsaio/fdisk.h
--- src/i386/libsaio/fdisk.h	2007-11-19 00:40:40.000000000 +0100
+++ src.new/i386/libsaio/fdisk.h	2009-01-18 22:18:50.000000000 +0100
@@ -66,7 +66,10 @@
     unsigned char    endcyl;    /* High 2 bits are in endsect */
     unsigned long    relsect;   /* partion physical offset on disk */
     unsigned long    numsect;   /* number of sectors in partition */
-};
+/* --- BEGIN ADDED ------------------------ */
+// };
+} __attribute__((packed));
+/* --- END ADDED --------------------------- */
 
 /*
  * Format of boot block.
@@ -77,4 +80,12 @@
     unsigned short   signature;
 };
 
+/* --- BEGIN ADDED ------------------------ */
+struct REAL_disk_blk0 {
+    unsigned char    bootcode[DISK_BOOTSZ];
+    struct fdisk_part    parts[FDISK_NPART];
+    unsigned short   signature;
+} __attribute__((packed));
+/* --- END ADDED --------------------------- */
+
 #endif /* !__LIBSAIO_FDISK_H */
diff -Naur src/i386/libsaio/hfs.h src.new/i386/libsaio/hfs.h
--- src/i386/libsaio/hfs.h	2007-11-19 00:40:40.000000000 +0100
+++ src.new/i386/libsaio/hfs.h	2009-01-18 22:13:41.000000000 +0100
@@ -29,3 +29,6 @@
 extern void HFSGetDescription(CICell ih, char *str, long strMaxLen);
 extern long HFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock);
 extern long HFSGetUUID(CICell ih, char *uuidStr);
+/* --- BEGIN ADDED ------------------------ */
+extern void HFSFree(CICell ih);
+/* --- END ADDED --------------------------- */
diff -Naur src/i386/libsaio/ufs.h src.new/i386/libsaio/ufs.h
--- src/i386/libsaio/ufs.h	2007-11-19 00:40:40.000000000 +0100
+++ src.new/i386/libsaio/ufs.h	2009-01-18 22:12:13.000000000 +0100
@@ -29,4 +29,6 @@
 extern void UFSGetDescription(CICell ih, char *str, long strMaxLen);
 extern long UFSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock);
 extern long UFSGetUUID(CICell ih, char *uuidStr);
-
+/* --- BEGIN ADDED ------------------------ */
+extern void UFSFree(CICell ih);
+/* --- END ADDED --------------------------- */