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 #include +/* --- BEGIN ADDED ------------------------ */ +#include +typedef struct gpt_hdr gpt_hdr; +typedef struct gpt_ent gpt_ent; + +// For EFI_GUID +#include +#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 --------------------------- */