Index: branches/cparm/CHANGES =================================================================== --- branches/cparm/CHANGES (revision 1723) +++ branches/cparm/CHANGES (revision 1724) @@ -1,8 +1,14 @@ -- Added an option to the check Oem revision of aml files (by adler32 of unique machine id or adler32 of motherboard model), can be useful with multiple machines (a command line tool able to patch the aml files will be available soon) +- Added Haiku support (credit to scorpius) +- Added EXFAT (FAT64) support (credit to dmazar) +- Added JrCs fixes (see trunk v1716 v1719) +- Gui can now detect the darwin version of each volumes +- Applied some underthehood fixes and enhancements + +- Added an option to the check Oem revision of aml files, can be useful with multiple machines (a command line tool able to patch the aml files will be available soon) - Improved smbios support for some Intel Xeon models - BETA : Sync'd ati engine with the trunk -- Small security fix +- Small security fixes - Added a mechanism to strip the madt table - Ported the serial number randomizer to smbiosgetters, Warning: smbiosgetters (and also the Gui module) still don't work when built with Xcode4. Index: branches/cparm/i386/libsaio/exfat.c =================================================================== --- branches/cparm/i386/libsaio/exfat.c (revision 0) +++ branches/cparm/i386/libsaio/exfat.c (revision 1724) @@ -0,0 +1,267 @@ + +/* + * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2004 Apple Computer, Inc. All Rights Reserved. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * dmazar, 14/7/2011 + * support for EXFAT volume label reading + * EXFAT info from: http://www.ntfs.com/exfat-overview.htm + * + * EXFAT shares partition type with NTFS (0x7) and easiest way of + * adding it was through ntfs.c module. All functions here are called + * from similar ntfs.c funcs as fallback (if not NTFS, maybe it's EXFAT). + */ + +#include "libsaio.h" +#include "sl.h" + +#ifndef DEBUG_EXFAT +#define DEBUG_EXFAT 0 +#endif + +#if DEBUG_EXFAT +#define DBG(x...) printf(x) +#define PAUSE() getc() +#else +#define DBG(x...) +#define PAUSE() +#endif + +#define EXFAT_BBID "EXFAT " +#define EXFAT_BBIDLEN 8 + +#define MAX_BLOCK_SIZE 4096 +#define MAX_CLUSTER_SIZE 32 * 1024 * 1024 + +#define ERROR -1 + + +/* + * boot sector of the partition + * http://www.ntfs.com/exfat-boot-sector.htm + */ +struct exfatbootfile { + u_int8_t reserved1[3]; /* JumpBoot: 0xEB7690 */ + u_int8_t bf_sysid[8]; /* FileSystemName: 'EXFAT ' */ + u_int8_t reserved2[53]; /* MustBeZero */ + u_int64_t bf_prtoff; /* PartitionOffset: In sectors; if 0, shall be ignored */ + u_int64_t bf_vollen; /* VolumeLength: Size of exFAT volume in sectors */ + u_int32_t bf_fatoff; /* FatOffset: In sectors */ + u_int32_t bf_fatlen; /* FatLength: In sectors. May exceed the required space in order to align the second FAT */ + u_int32_t bf_cloff; /* ClusterHeapOffset: In sectors. */ + u_int32_t bf_clcnt; /* ClusterCount: 2^32-11 is the maximum number of clusters could be described. */ + u_int32_t bf_rdircl; /* RootDirectoryCluster. */ + u_int32_t bf_volsn; /* VolumeSerialNumber. */ + u_int16_t bf_fsrev; /* FileSystemRevision: as MAJOR.minor, major revision is high byte, minor is low byte; currently 01.00. */ + u_int16_t bf_volflags; /* VolumeFlags. */ + u_int8_t bf_bpss; /* BytesPerSectorShift: Power of 2. Minimum 9 (512 bytes per sector), maximum 12 (4096 bytes per sector) */ + u_int8_t bf_spcs; /* SectorsPerClusterShift: Power of 2. Minimum 0 (1 sector per cluster), maximum 25 – BytesPerSectorShift, so max cluster size is 32 MB */ + u_int8_t bf_nfats; /* NumberOfFats: 2 is for TexFAT only */ + u_int8_t bf_drvs; /* DriveSelect: Extended INT 13h drive number; typically 0x80 */ + u_int8_t bf_pused; /* PercentInUse: 0..100 – percentage of allocated clusters rounded down to the integer 0xFF – percentage is not available */ + u_int8_t reserved3[7]; /* Reserved */ + u_int8_t bootcode[390]; /* BootCode */ + u_int16_t bf_bsig; /* BootSignature: 0xAA55 */ +}; + +struct direntry_label { + u_int8_t type; /* EntryType: 0x83 (or 0x03 if label is empty) */ + u_int8_t llen; /* CharacterCount: Length in Unicode characters (max 11) */ + u_int16_t label[11]; /* VolumeLabel: Unicode characters (max 11) */ + u_int8_t reserved1[8]; /* Reserved */ +}; + + +/** + * Reads volume label into str. + * Reads boot sector, performs dome checking, loads root dir + * and parses volume label. + */ +void +EXFATGetDescription(CICell ih, char *str, long strMaxLen) +{ + struct exfatbootfile *boot; + u_int32_t bytesPerSector = 0; + u_int32_t sectorsPerCluster = 0; + long long rdirOffset = 0; + char *buf = NULL; + struct direntry_label *dire = NULL; + int loopControl = 0; + + DBG("EXFAT: start %x:%x\n", ih->biosdev, ih->part_no); + + buf = (char *)malloc(MAX_BLOCK_SIZE); + if (buf == 0) + { + goto error; + } + + /* + * Read the boot sector, check signatures, and do some minimal + * sanity checking. NOTE: the size of the read below is intended + * to be a multiple of all supported block sizes, so we don't + * have to determine or change the device's block size. + */ + Seek(ih, 0); + Read(ih, (long)buf, MAX_BLOCK_SIZE); + + // take our boot structure + boot = (struct exfatbootfile *) buf; + + /* + * The first three bytes are an Intel x86 jump instruction. I assume it + * can be the same forms as DOS FAT: + * 0xE9 0x?? 0x?? + * 0xEC 0x?? 0x90 + * where 0x?? means any byte value is OK. + */ + if (boot->reserved1[0] != 0xE9 + && (boot->reserved1[0] != 0xEB || boot->reserved1[2] != 0x90)) + { + goto error; + } + + // Check the "EXFAT " signature. + if (memcmp((const char *)boot->bf_sysid, EXFAT_BBID, EXFAT_BBIDLEN) != 0) + { + goto error; + } + + /* + * Make sure the bytes per sector and sectors per cluster are + * powers of two, and within reasonable ranges. + */ + bytesPerSector = 1 << boot->bf_bpss; /* Just one byte; no swapping needed */ + DBG("EXFAT: bpss=%d, bytesPerSector=%d\n", boot->bf_bpss, bytesPerSector); + if (boot->bf_bpss < 9 || boot->bf_bpss > 12) + { + DBG("EXFAT: invalid bytes per sector shift(%d)\n", boot->bf_bpss); + goto error; + } + + sectorsPerCluster = 1 << boot->bf_spcs; /* Just one byte; no swapping needed */ + DBG("EXFAT: spcs=%d, sectorsPerCluster=%d\n", boot->bf_spcs, sectorsPerCluster); + if (boot->bf_spcs > (25 - boot->bf_bpss)) + { + DBG("EXFAT: invalid sectors per cluster shift (%d)\n", boot->bf_spcs); + goto error; + } + + // calculate root dir cluster offset + rdirOffset = boot->bf_cloff + (boot->bf_rdircl - 2) * sectorsPerCluster; + DBG("EXFAT: rdirOffset=%d\n", rdirOffset); + + // load MAX_BLOCK_SIZE bytes of root dir + Seek(ih, rdirOffset * bytesPerSector); + Read(ih, (long)buf, MAX_BLOCK_SIZE); + DBG("buf 0 1 2 = %x %x %x\n", 0x00ff & buf[0], 0x00ff & buf[1], 0x00ff & buf[2]); + + str[0] = '\0'; + + /* + * Search for volume label dir entry (type 0x83), convert from unicode and put to str. + * Set loopControl var to avoid searching outside of buf. + */ + loopControl = MAX_BLOCK_SIZE / sizeof(struct direntry_label); + dire = (struct direntry_label *)buf; + while (loopControl && dire->type && dire->type != 0x83) + { + dire++; + loopControl--; + } + if (dire->type == 0x83 && dire->llen > 0 && dire->llen <= 11) + { + utf_encodestr( dire->label, (int)dire->llen, (u_int8_t *)str, strMaxLen, OSLittleEndian ); + } + DBG("EXFAT: label=%s\n", str); + + free(buf); + PAUSE(); + return; + + error: + if (buf) free(buf); + DBG("EXFAT: error\n"); + PAUSE(); + return; +} + +/** + * Sets UUID to uuidStr. + * Reads the boot sector, does some checking, generates UUID + * (like the one you get on Windows???) + */ +long EXFATGetUUID(CICell ih, char *uuidStr) +{ + struct exfatbootfile *boot; + void *buf = malloc(MAX_BLOCK_SIZE); + if ( !buf ) + return -1; + + /* + * Read the boot sector, check signatures, and do some minimal + * sanity checking. NOTE: the size of the read below is intended + * to be a multiple of all supported block sizes, so we don't + * have to determine or change the device's block size. + */ + Seek(ih, 0); + Read(ih, (long)buf, MAX_BLOCK_SIZE); + + boot = (struct exfatbootfile *) buf; + + /* + * Check the "EXFAT " signature. + */ + if (memcmp((const char *)boot->bf_sysid, EXFAT_BBID, EXFAT_BBIDLEN) != 0) + return -1; + + // Check for non-null volume serial number + if( !boot->bf_volsn ) + return -1; + + // Use UUID like the one you get on Windows + sprintf(uuidStr, "%04X-%04X", (unsigned short)(boot->bf_volsn >> 16) & 0xFFFF, + (unsigned short)boot->bf_volsn & 0xFFFF); + + DBG("EXFATGetUUID: %x:%x = %s\n", ih->biosdev, ih->part_no, uuidStr); + return 0; +} + +/** + * Returns true if given buffer is the boot rec of the EXFAT volume. + */ +bool EXFATProbe(const void * buffer) +{ + bool result = false; + + // boot sector structure + const struct exfatbootfile * boot = buffer; + + // Looking for EXFAT signature. + if (memcmp((const char *)boot->bf_sysid, EXFAT_BBID, EXFAT_BBIDLEN) == 0) + result = true; + + DBG("EXFATProbe: %d\n", result ? 1 : 0); + return result; +} Index: branches/cparm/i386/libsaio/bootstruct.c =================================================================== --- branches/cparm/i386/libsaio/bootstruct.c (revision 1723) +++ branches/cparm/i386/libsaio/bootstruct.c (revision 1724) @@ -34,8 +34,11 @@ * Initialize the structure of parameters passed to * the kernel by the booter. */ -boot_args_legacy *bootArgsLegacy; -boot_args *bootArgs; +boot_args_Legacy *bootArgsLegacy; +boot_args_common *bootArgs; +boot_args_107 *bootArgs107; +/* ... */ + PrivateBootInfo_t *bootInfo; Node *gMemoryMapNode; @@ -47,12 +50,12 @@ if ( !init_done ) { - bootArgs = (boot_args *)malloc(sizeof(boot_args)); + bootArgs = (boot_args_common *)malloc(sizeof(boot_args_common)); bootInfo = (PrivateBootInfo_t *)malloc(sizeof(PrivateBootInfo_t)); if (bootArgs == 0 || bootInfo == 0) stop("Couldn't allocate boot info\n"); - bzero(bootArgs, sizeof(boot_args)); + bzero(bootArgs, sizeof(boot_args_common)); bzero(bootInfo, sizeof(PrivateBootInfo_t)); // Get system memory map. Also update the size of the @@ -106,26 +109,96 @@ } +#define AllocateKernelMemoryForBootArgs(Ver) \ +{ \ + bootArgs##Ver = (boot_args_##Ver *)AllocateKernelMemory(sizeof(boot_args_##Ver));\ +} +#define CopyCommonBootArgsHeader(Ver) \ +{ \ + bootArgs##Ver->Revision = bootArgs->Header.Revision ;\ + bootArgs##Ver->Version = bootArgs->Header.Version ;\ +} + +// For 10.6, 10.5 and 10.4 please use :Legacy:, for 10.7 use :107: +#define CopyCommonBootArgs(Ver) \ +{ \ + bcopy(bootArgs->CommandLine, bootArgs##Ver->CommandLine, BOOT_LINE_LENGTH);\ + bootArgs##Ver->MemoryMap = bootArgs->MemoryMap ;\ + bootArgs##Ver->MemoryMapSize = bootArgs->MemoryMapSize ;\ + bootArgs##Ver->MemoryMapDescriptorSize = bootArgs->MemoryMapDescriptorSize ;\ + bootArgs##Ver->MemoryMapDescriptorVersion = bootArgs->MemoryMapDescriptorVersion ;\ + bootArgs##Ver->Video = bootArgs->Video ;\ + bootArgs##Ver->deviceTreeP = bootArgs->deviceTreeP ;\ + bootArgs##Ver->deviceTreeLength = bootArgs->deviceTreeLength ;\ + bootArgs##Ver->kaddr = bootArgs->kaddr ;\ + bootArgs##Ver->ksize = bootArgs->ksize ;\ + bootArgs##Ver->efiRuntimeServicesPageStart = bootArgs->efiRuntimeServicesPageStart ;\ + bootArgs##Ver->efiRuntimeServicesPageCount = bootArgs->efiRuntimeServicesPageCount ;\ + bootArgs##Ver->efiSystemTable = bootArgs->efiSystemTable ;\ + bootArgs##Ver->efiMode = bootArgs->efiMode ;\ + bootArgs##Ver->performanceDataStart = bootArgs->performanceDataStart ;\ + bootArgs##Ver->performanceDataSize = bootArgs->performanceDataSize ;\ + bootArgs##Ver->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart ;\ +} + +#define init_boot_args(Ver) \ +{ \ + AllocateKernelMemoryForBootArgs(Ver);\ + CopyCommonBootArgsHeader(Ver);\ + CopyCommonBootArgs(Ver);\ +} + /* Copy boot args after kernel and record address. */ void -reserveKernBootStruct(void) +reserveKern107BootStruct(void) { - void *oldAddr = bootArgs; + //bootArgs107 = (boot_args_107 *)AllocateKernelMemory(sizeof(boot_args_107)); - bootArgs = (boot_args *)AllocateKernelMemory(sizeof(boot_args)); - bcopy(oldAddr, bootArgs, sizeof(boot_args)); - + /* Common Darwin boot arguments */ + /* + bootArgs107->Revision = bootArgs->Header.Revision ; + bootArgs107->Version = bootArgs->Header.Version ; + bcopy(bootArgs->CommandLine, bootArgs107->CommandLine, BOOT_LINE_LENGTH); + bootArgs107->MemoryMap = bootArgs->MemoryMap ; + bootArgs107->MemoryMapSize = bootArgs->MemoryMapSize ; + bootArgs107->MemoryMapDescriptorSize = bootArgs->MemoryMapDescriptorSize ; + bootArgs107->MemoryMapDescriptorVersion = bootArgs->MemoryMapDescriptorVersion ; + bootArgs107->Video = bootArgs->Video ; + bootArgs107->deviceTreeP = bootArgs->deviceTreeP ; + bootArgs107->deviceTreeLength = bootArgs->deviceTreeLength ; + bootArgs107->kaddr = bootArgs->kaddr ; + bootArgs107->ksize = bootArgs->ksize ; + bootArgs107->efiRuntimeServicesPageStart = bootArgs->efiRuntimeServicesPageStart ; + bootArgs107->efiRuntimeServicesPageCount = bootArgs->efiRuntimeServicesPageCount ; + bootArgs107->efiSystemTable = bootArgs->efiSystemTable ; + bootArgs107->efiMode = bootArgs->efiMode ; + bootArgs107->performanceDataStart = bootArgs->performanceDataStart ; + bootArgs107->performanceDataSize = bootArgs->performanceDataSize ; + bootArgs107->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart ; + */ + + init_boot_args(107); + + /* Darwin 10.7 specific boot arguments */ + bootArgs107->keyStoreDataStart = bootArgs->keyStoreDataStart ; + bootArgs107->keyStoreDataSize = bootArgs->keyStoreDataSize ; + bootArgs107->bootMemStart = bootArgs->bootMemStart ; + bootArgs107->bootMemSize = bootArgs->bootMemSize ; + bootArgs107->PhysicalMemorySize = bootArgs->PhysicalMemorySize ; + bootArgs107->FSBFrequency = bootArgs->FSBFrequency ; + bootArgs107->debugMode = bootArgs->debugMode; + } void reserveKernLegacyBootStruct(void) { - bootArgsLegacy = (boot_args_legacy *)AllocateKernelMemory(sizeof(boot_args_legacy)); - - bootArgsLegacy->Revision = bootArgs->Revision ; - bootArgsLegacy->Version = bootArgs->Version ; + //bootArgsLegacy = (boot_args_legacy *)AllocateKernelMemory(sizeof(boot_args_legacy)); + /* + bootArgsLegacy->Revision = bootArgs->Header.Revision ; + bootArgsLegacy->Version = bootArgs->Header.Version ; bcopy(bootArgs->CommandLine, bootArgsLegacy->CommandLine, BOOT_LINE_LENGTH); bootArgsLegacy->MemoryMap = bootArgs->MemoryMap ; bootArgsLegacy->MemoryMapSize = bootArgs->MemoryMapSize ; @@ -143,8 +216,9 @@ bootArgsLegacy->performanceDataStart = bootArgs->performanceDataStart ; bootArgsLegacy->performanceDataSize = bootArgs->performanceDataSize ; bootArgsLegacy->efiRuntimeServicesVirtualPageStart = bootArgs->efiRuntimeServicesVirtualPageStart ; - +*/ + init_boot_args(Legacy); } void @@ -265,8 +339,6 @@ DT__FlattenDeviceTree((void **)&addr, &size); bootArgs->deviceTreeP = (uint32_t)addr; bootArgs->deviceTreeLength = size; - } + } - - } Index: branches/cparm/i386/libsaio/exfat.h =================================================================== --- branches/cparm/i386/libsaio/exfat.h (revision 0) +++ branches/cparm/i386/libsaio/exfat.h (revision 1724) @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 2.0 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * dmazar, 14/7/2011 + * support for EXFAT volume label reading + * + */ + +extern void EXFATGetDescription(CICell ih, char *str, long strMaxLen); +extern bool EXFATProbe (const void *buf); +extern long EXFATGetUUID(CICell ih, char *uuidStr); + Index: branches/cparm/i386/libsaio/bootstruct.h =================================================================== --- branches/cparm/i386/libsaio/bootstruct.h (revision 1723) +++ branches/cparm/i386/libsaio/bootstruct.h (revision 1724) @@ -32,9 +32,15 @@ /*! Kernel boot args global also used by booter for its own data. */ -extern boot_args *bootArgs; +extern boot_args_common *bootArgs; + +/*! + Boot args passed to the kernel. + */ +extern boot_args_Legacy *bootArgsLegacy; +extern boot_args_107 *bootArgs107; + extern Node *gMemoryMapNode; -extern boot_args_legacy *bootArgsLegacy; #define VGA_TEXT_MODE 0 Index: branches/cparm/i386/libsaio/bootLion.h =================================================================== --- branches/cparm/i386/libsaio/bootLion.h (revision 1723) +++ branches/cparm/i386/libsaio/bootLion.h (revision 1724) @@ -110,7 +110,7 @@ #define kBootArgsEfiMode32 32 #define kBootArgsEfiMode64 64 -typedef struct boot_args_legacy { +typedef struct boot_args_Legacy { uint16_t Revision; /* Revision of boot_args structure */ uint16_t Version; /* Version of boot_args structure */ @@ -141,7 +141,7 @@ uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */ uint32_t __reserved3[2]; -} boot_args_legacy; +} boot_args_Legacy; typedef struct boot_args { uint16_t Revision; /* Revision of boot_args structure */ @@ -184,9 +184,57 @@ uint64_t FSBFrequency; uint32_t __reserved4[734]; -} boot_args; +} boot_args_107; -extern char assert_boot_args_size_is_4096[sizeof(boot_args) == 4096 ? 1 : -1]; +typedef struct boot_args_header { + uint16_t Revision; /* Revision of boot_args structure */ + uint16_t Version; /* Version of boot_args structure */ +} boot_args_header; +typedef struct boot_args_10x { + boot_args_header Header; + + Boot_Video Video; /* Video Information */ + + uint32_t MemoryMap; /* Physical address of memory map */ + uint32_t MemoryMapSize; + uint32_t MemoryMapDescriptorSize; + uint32_t MemoryMapDescriptorVersion; + + uint8_t debugMode; /* Bit field with behavior changes */ + uint8_t efiMode; /* 32 = 32-bit, 64 = 64-bit */ + + + uint32_t deviceTreeP; /* Physical address of flattened device tree */ + uint32_t deviceTreeLength; /* Length of flattened tree */ + + char CommandLine[BOOT_LINE_LENGTH]; /* Passed in command line */ + + + uint32_t keyStoreDataStart; /* physical address of key store data */ + uint32_t keyStoreDataSize; + uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */ + uint32_t efiRuntimeServicesPageCount; + uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */ + + uint32_t efiSystemTable; /* physical address of system table in runtime area */ + uint64_t FSBFrequency; + + uint32_t performanceDataSize; + uint32_t performanceDataStart; /* physical address of log */ + + uint32_t kaddr; /* Physical address of beginning of kernel text */ + uint32_t ksize; /* Size of combined kernel text+data+efi */ + + uint64_t bootMemStart; + uint64_t bootMemSize; + uint64_t PhysicalMemorySize; + +} boot_args_10x; + +typedef struct boot_args_10x boot_args_common; + +extern char assert_boot_args_107_size_is_4096[sizeof(boot_args_107) == 4096 ? 1 : -1]; + #endif /* _PEXPERT_I386_BOOT_H */ Index: branches/cparm/i386/libsaio/Makefile =================================================================== --- branches/cparm/i386/libsaio/Makefile (revision 1723) +++ branches/cparm/i386/libsaio/Makefile (revision 1724) @@ -41,7 +41,7 @@ cpu.o platform.o \ fake_efi.o \ device_inject.o pci_root.o \ - convert.o acpi_tools.o smbios.o smp-imps.o + convert.o acpi_tools.o smbios.o smp-imps.o # example for AcpiCodec #SAIO_OBJS += acpi_codec.o acpicode.o ACPICodec.o acpidecode.o @@ -59,8 +59,8 @@ #SAIO_OBJS += graphic_utils.o gui.o picopng.o GUI_module.o # Options enabled by default: -#CFLAGS += -DNO_WIN_SUPPORT # -7200 bytes -SAIO_OBJS += ntfs.o msdos.o +#CFLAGS += -DNO_WIN_SUPPORT # -7744 bytes +SAIO_OBJS += ntfs.o msdos.o exfat.o #CFLAGS += -DNO_LINUX_SUPPORT # -256 bytes SAIO_OBJS += ext2fs.o @@ -68,6 +68,9 @@ #CFLAGS += -DNO_OTHERS_BSD_SUPPORT # -512 bytes SAIO_OBJS += freebsd.o openbsd.o +#CFLAGS += -DNO_HAIKU_SUPPORT # -256 bytes +SAIO_OBJS += befs.o + # Options disabled by default: #CFLAGS += -DUFS_SUPPORT # +3616 bytes Index: branches/cparm/i386/libsaio/befs.c =================================================================== --- branches/cparm/i386/libsaio/befs.c (revision 0) +++ branches/cparm/i386/libsaio/befs.c (revision 1724) @@ -0,0 +1,43 @@ +/* + * befs.c + * + * + * Created by scorpius + * Copyright 2010 + * + */ + +#include "libsaio.h" +#include "sl.h" +#include "befs.h" + +#define BeFSProbeSize 2048 + +#define SUPER_BLOCK_MAGIC1 0x42465331 /* BFS1 */ +#define SUPER_BLOCK_MAGIC2 0xdd121031 +#define SUPER_BLOCK_MAGIC3 0x15b6830e + +/* Find BeFS signature */ +bool BeFSProbe (const void *buf) +{ + return (OSReadLittleInt32(buf+0x220,0)==SUPER_BLOCK_MAGIC1); +} + +/* Find BeFS volume label */ +void BeFSGetDescription(CICell ih, char *str, long strMaxLen) +{ + char * buf=malloc (BeFSProbeSize); + str[0]=0; + if (!buf) + return; + Seek(ih, 0); + Read(ih, (long)buf, BeFSProbeSize); + if (!BeFSProbe (buf)) + { + free (buf); + return; + } + str[strMaxLen]=0; + strncpy (str, buf+0x200, MIN (strMaxLen, 32)); + free (buf); +} Index: branches/cparm/i386/libsaio/befs.h =================================================================== --- branches/cparm/i386/libsaio/befs.h (revision 0) +++ branches/cparm/i386/libsaio/befs.h (revision 1724) @@ -0,0 +1,11 @@ +/* + * befs.h + * + * + * Created by scorpius + * Copyright 2010 + * + */ + +extern bool BeFSProbe (const void *buf); +extern void BeFSGetDescription(CICell ih, char *str, long strMaxLen); Index: branches/cparm/i386/libsaio/fdisk.h =================================================================== --- branches/cparm/i386/libsaio/fdisk.h (revision 1723) +++ branches/cparm/i386/libsaio/fdisk.h (revision 1724) @@ -56,6 +56,8 @@ #define FDISK_BOOTER 0xab /* Apple booter partition */ #define FDISK_OPENBSD 0xa6 /* OpenBSD FFS partition */ #define FDISK_FREEBSD 0xa5 /* FreeBSD UFS2 partition */ +#define FDISK_BEFS 0xeb /* Haiku BeFS partition */ + /* * Format of fdisk partion entry (if present). */ Index: branches/cparm/i386/libsaio/ntfs.c =================================================================== --- branches/cparm/i386/libsaio/ntfs.c (revision 1723) +++ branches/cparm/i386/libsaio/ntfs.c (revision 1724) @@ -25,6 +25,12 @@ #include "libsaio.h" #include "sl.h" +/* + * dmazar, 14/7/2011 - support for EXFAT volume label reading + */ + +#include "exfat.h" + //#define BYTE_ORDER_MARK 0xFEFF #include "ntfs_private.h" @@ -201,7 +207,14 @@ */ if (memcmp((const char *)boot->bf_sysid, "NTFS ", 8) != 0) { - goto error; + /* + * Check for EXFAT. Finish by jumping to error to free buf, + * although if it is EXFAT then it's no an error. + */ + + EXFATGetDescription(ih, str, strMaxLen); + + goto error; } /* @@ -326,8 +339,10 @@ boot = (struct bootfile *) buf; // Check for NTFS signature - if ( memcmp((void*)boot->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) != 0 ) - return -1; + if ( memcmp((void*)boot->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) != 0 ) { + // If not NTFS, maybe it is EXFAT + return EXFATGetUUID(ih, uuidStr); + } // Check for non-null volume serial number if( !boot->bf_volsn ) @@ -350,5 +365,9 @@ if (strncmp((const char *)part_bootfile->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) == 0) result = true; + // If not NTFS, maybe it is EXFAT + if (!result == false) + result = EXFATProbe(buffer); + return result; } Index: branches/cparm/i386/libsaio/disk.c =================================================================== --- branches/cparm/i386/libsaio/disk.c (revision 1723) +++ branches/cparm/i386/libsaio/disk.c (revision 1724) @@ -71,6 +71,10 @@ #include "freebsd.h" #include "openbsd.h" #endif +#ifndef NO_HAIKU_SUPPORT +#include "befs.h" +#endif + #include "xml.h" #include "disk.h" #include "modules.h" @@ -951,6 +955,18 @@ 0, kBIOSDevTypeHardDrive, 0); break; #endif +#ifndef NO_HAIKU_SUPPORT + case FDISK_BEFS: + bvr = newFDiskBVRef( + biosdev, partno, + part->relsect, + part, + 0, 0, 0, 0, 0, 0, + BeFSGetDescription, + (BVFree)free, + 0, kBIOSDevTypeHardDrive, 0); + break; +#endif #ifndef NO_OTHERS_BSD_SUPPORT case FDISK_FREEBSD: bvr = newFDiskBVRef( @@ -1186,6 +1202,10 @@ else if (OpenBSDProbe(probeBuffer)) result = FDISK_OPENBSD; #endif +#ifndef NO_HAIKU_SUPPORT + else if (BeFSProbe(probeBuffer)) + result = FDISK_BEFS; +#endif #ifndef NO_WIN_SUPPORT else if (NTFSProbe(probeBuffer)) result = FDISK_NTFS; @@ -1814,6 +1834,9 @@ #endif { FDISK_HFS, "Apple HFS" }, { FDISK_BOOTER, "Apple Boot/UFS" }, +#ifndef NO_HAIKU_SUPPORT + { FDISK_BEFS, "Haiku" }, +#endif { 0xCD, "CD-ROM" }, { 0x00, 0 } /* must be last */ }; Index: branches/cparm/i386/libsaio/saio_types.h =================================================================== --- branches/cparm/i386/libsaio/saio_types.h (revision 1723) +++ branches/cparm/i386/libsaio/saio_types.h (revision 1724) @@ -239,6 +239,7 @@ kPartitionTypeEXT3 = 0x83, kPartitionTypeFreeBSD = 0xa5, kPartitionTypeOpenBSD = 0xa6, + kPartitionTypeBEFS = 0xEB }; //#define BIOS_DEV_TYPE(d) ((d) & kBIOSDevTypeMask) Index: branches/cparm/i386/libsaio/fake_efi.c =================================================================== --- branches/cparm/i386/libsaio/fake_efi.c (revision 1723) +++ branches/cparm/i386/libsaio/fake_efi.c (revision 1724) @@ -170,10 +170,8 @@ printf("Ran out of space for configuration tables (max = %d). Please, increase the reserved size in the code.\n", (int)MAX_CONFIGURATION_TABLE_ENTRIES); return EFI_ABORTED; - } + } - - if (archCpuType == CPU_TYPE_I386) { @@ -188,8 +186,7 @@ gEfiConfigurationTable64[i].VendorTable = (EFI_PTR32)table; gNumTables64++ ; } - - + Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid)); // Use the pointer to the GUID we just stuffed into the system table @@ -221,8 +218,7 @@ } void finalizeEFIConfigTable(void ) -{ - +{ if (archCpuType == CPU_TYPE_I386) { EFI_SYSTEM_TABLE_32 *efiSystemTable = gST32; @@ -236,9 +232,8 @@ EFI_SYSTEM_TABLE_64 *efiSystemTable = gST64; efiSystemTable->NumberOfTableEntries = gNumTables64; - efiSystemTable->ConfigurationTable = ptov64((EFI_PTR32)gEfiConfigurationTable64); + efiSystemTable->ConfigurationTable = ptov64((EFI_PTR32)gEfiConfigurationTable64); - } EFI_ST_FIX_CRC32(); @@ -450,8 +445,7 @@ /* Setup ACPI without any patch. */ static EFI_STATUS setupAcpiNoMod() -{ - +{ EFI_STATUS ret = EFI_UNSUPPORTED; ACPI_TABLE_RSDP* rsdp = (ACPI_TABLE_RSDP*)((uint32_t)local_rsd_p); @@ -473,26 +467,29 @@ execute_hook("setupAcpiEfi", &ret, NULL, NULL, NULL, NULL, NULL); - if (ret != EFI_SUCCESS) - { - if (!FindAcpiTables(&acpi_tables)) - { - printf("Failed to detect ACPI tables.\n"); - return EFI_NOT_FOUND; - } - - local_rsd_p = ((uint64_t)((uint32_t)acpi_tables.RsdPointer)); - - { - ACPI_TABLE_FADT *FacpPointer = (acpi_tables.FacpPointer64 != (void*)0ul) ? (ACPI_TABLE_FADT *)acpi_tables.FacpPointer64 : (ACPI_TABLE_FADT *)acpi_tables.FacpPointer; + do { + if (ret != EFI_SUCCESS) + { + if (!FindAcpiTables(&acpi_tables)) + { + printf("Failed to detect ACPI tables.\n"); + ret = EFI_NOT_FOUND; + break; + } - uint8_t type = FacpPointer->PreferredProfile; - if (type <= MaxSupportedPMProfile) - Platform->Type = type; - } + local_rsd_p = ((uint64_t)((uint32_t)acpi_tables.RsdPointer)); + + { + ACPI_TABLE_FADT *FacpPointer = (acpi_tables.FacpPointer64 != (void*)0ul) ? (ACPI_TABLE_FADT *)acpi_tables.FacpPointer64 : (ACPI_TABLE_FADT *)acpi_tables.FacpPointer; + + uint8_t type = FacpPointer->PreferredProfile; + if (type <= MaxSupportedPMProfile) + Platform->Type = type; + } - ret = setupAcpiNoMod(); - } + ret = setupAcpiNoMod(); + } + } while (0); return ret; @@ -602,8 +599,7 @@ EFI_CHAR8* ret = getUUIDFromString(getStringForKey(kSystemID, &bootInfo->bootConfig)); if (!ret) // try bios dmi info UUID extraction - ret = getSmbiosUUID(); - + ret = getSmbiosUUID(); if (!ret) { @@ -708,8 +704,7 @@ { Node *chosenNode = DT__FindNode("/chosen", true); if (chosenNode) - { - + { DT__AddProperty(chosenNode, "boot-args", strlen(bootArgs->CommandLine)+1, (EFI_CHAR16*)bootArgs->CommandLine); // "boot-uuid" MAIN GOAL IS SYMPLY TO BOOT FROM THE UUID SET IN THE DT AND DECREASE BOOT TIME, SEE IOKitBSDInit.cpp @@ -732,12 +727,10 @@ } - // "boot-file" is not used by kextcache if there is no "boot-device-path" or if there is a valid "rootpath" , // but i let it by default since it may be used by another service DT__AddProperty(chosenNode, "boot-file", strlen(bootInfo->bootFile)+1, (EFI_CHAR16*)bootInfo->bootFile); - - + if (bootInfo->adler32) DT__AddProperty(chosenNode, "boot-kernelcache-adler32", sizeof(unsigned long), &bootInfo->adler32); @@ -757,7 +750,7 @@ Node *runtimeServicesNode = DT__AddChild(efiNode, "runtime-services"); Node *kernelCompatibilityNode = 0; // ??? not sure that it should be used like that (because it's maybe the kernel capability and not the cpu capability) - if (gMacOSVersion[3] == '7') + if (gMacOSVersion[3] > '6') { kernelCompatibilityNode = DT__AddChild(efiNode, "kernel-compatibility"); DT__AddProperty(kernelCompatibilityNode, "i386", sizeof(uint32_t), (EFI_UINT32*)&DEVICE_SUPPORTED); @@ -818,9 +811,8 @@ // because the DT_AddProperty function does not copy its args. if (Platform->CPU.FSBFrequency != 0) - DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform->CPU.FSBFrequency); + DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform->CPU.FSBFrequency); - #if UNUSED // Export TSC and CPU frequencies for use by the kernel or KEXTs if (Platform->CPU.TSCFrequency != 0) @@ -830,8 +822,7 @@ DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform->CPU.CPUFrequency); #endif - // Export system-id. Can be disabled with SystemId=No in com.apple.Boot.plist - + // Export system-id. Can be disabled with SystemId=No in com.apple.Boot.plist if (getSystemID() == EFI_SUCCESS) DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) Platform->sysid); @@ -854,11 +845,12 @@ void setupSmbiosConfigFile(const char *filename) { - static bool readSmbConfigFile = true; + //static bool readSmbConfigFile = true; - if (readSmbConfigFile == true) + if (&bootInfo->bootConfig == 0) + //if (readSmbConfigFile == true) { - + verbose("loading smbios plist\n"); char dirSpecSMBIOS[128] = ""; const char *override_pathname = NULL; int len = 0, err = 0; @@ -886,7 +878,7 @@ { verbose("No SMBIOS config file found.\n"); } - readSmbConfigFile = false; + //readSmbConfigFile = false; } } @@ -906,31 +898,31 @@ if (chosenNode) { if (Platform->hardware_signature == 0xFFFFFFFF) - { - if (!local_rsd_p) - { - - if (!FindAcpiTables(&acpi_tables)){ - printf("Failed to detect ACPI tables.\n"); - goto out; + { + do { + if (!local_rsd_p) + { + if (!FindAcpiTables(&acpi_tables)){ + printf("Failed to detect ACPI tables.\n"); + break; + } + + local_rsd_p = ((uint64_t)((uint32_t)acpi_tables.RsdPointer)); } - - local_rsd_p = ((uint64_t)((uint32_t)acpi_tables.RsdPointer)); - } + + ACPI_TABLE_FACS *FacsPointer = (acpi_tables.FacsPointer64 != (void*)0ul) ? (ACPI_TABLE_FACS *)acpi_tables.FacsPointer64:(ACPI_TABLE_FACS *)acpi_tables.FacsPointer; + + Platform->hardware_signature = FacsPointer->HardwareSignature; + + } while (0); - ACPI_TABLE_FACS *FacsPointer = (acpi_tables.FacsPointer64 != (void*)0ul) ? (ACPI_TABLE_FACS *)acpi_tables.FacsPointer64:(ACPI_TABLE_FACS *)acpi_tables.FacsPointer; - - - Platform->hardware_signature = FacsPointer->HardwareSignature; - + // Verify that we have a valid hardware signature + if (Platform->hardware_signature == 0xFFFFFFFF) + { + verbose("Warning: hardware_signature is invalid, defaulting to 0 \n"); + Platform->hardware_signature = 0; + } } -out: - // Verify that we have a valid hardware signature - if (Platform->hardware_signature == 0xFFFFFFFF) - { - verbose("Warning: hardware_signature is invalid, defaulting to 0 \n"); - Platform->hardware_signature = 0; - } DT__AddProperty(chosenNode, "machine-signature", sizeof(uint32_t), &Platform->hardware_signature); } Index: branches/cparm/i386/libsaio/saio_internal.h =================================================================== --- branches/cparm/i386/libsaio/saio_internal.h (revision 1723) +++ branches/cparm/i386/libsaio/saio_internal.h (revision 1724) @@ -78,10 +78,10 @@ /* bootstruct.c */ extern void initKernBootStruct(void); -extern void reserveKernBootStruct(void); extern void copyKernBootStruct(void); extern void finalizeBootStruct(void); extern void reserveKernLegacyBootStruct(void); +extern void reserveKern107BootStruct(void); /* cache.c */ extern void CacheReset(); Index: branches/cparm/i386/boot2/boot.c =================================================================== --- branches/cparm/i386/boot2/boot.c (revision 1723) +++ branches/cparm/i386/boot2/boot.c (revision 1724) @@ -119,6 +119,7 @@ static bool find_file_with_ext(const char* dir, const char *ext, const char * name_compare, size_t ext_size); static bool found_extra_kext(void); static void determineCpuArch(void); +static void init_pic(void); void getKernelCachePath(); @@ -182,6 +183,12 @@ #endif } +static void init_pic(void) +{ + outb(0x21, 0xff); /* Maskout all interrupts Pic1 */ + outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */ +} + //========================================================================== // execKernel - Load the kernel image (mach-o) and jump to its entry point. @@ -194,18 +201,21 @@ if(gMacOSVersion[3] <= '6') { - bootArgs->Version = kBootArgsVersion1; - bootArgs->Revision = gMacOSVersion[3]; + bootArgs->Header.Version = kBootArgsVersion1; + bootArgs->Header.Revision = gMacOSVersion[3]; } else { #if kBootArgsVersion > 1 - bootArgs->Version = kBootArgsVersion; - bootArgs->Revision = kBootArgsRevision; + bootArgs->Header.Version = kBootArgsVersion; + bootArgs->Header.Revision = kBootArgsRevision; #else - bootArgs->Version = 2; - bootArgs->Revision = 0; + if(gMacOSVersion[3] == '7') + { + bootArgs->Header.Version = 2; + bootArgs->Header.Revision = 0; + } #endif } @@ -217,12 +227,8 @@ (int *)&bootArgs->ksize ); if ( ret != 0 ) - return ret; + return ret; - // Reserve space for boot args for 10.7 only (for 10.6 and earlier, we will convert (to legacy) the structure and reserve kernel memory for it later.) - if(gMacOSVersion[3] == '7') - reserveKernBootStruct(); - // Load boot drivers from the specifed root path. if (!gHaveKernelCache) @@ -329,11 +335,13 @@ finalizeBootStruct(); + execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgs, NULL, NULL, NULL, NULL); // Notify modules that the kernel is about to be started - if (gMacOSVersion[3] <= '6') - reserveKernLegacyBootStruct(); + if (gMacOSVersion[3] <= '6') + reserveKernLegacyBootStruct(); + else if (gMacOSVersion[3] == '7') + reserveKern107BootStruct(); - execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgs, NULL, NULL, NULL, NULL); // Notify modules that the kernel is about to be started #if UNUSED turnOffFloppy(); #endif @@ -342,21 +350,28 @@ #include "apic.h" IMPS_LAPIC_WRITE(LAPIC_LVT1, LAPIC_ICR_DM_NMI); #endif - - if (gMacOSVersion[3] <= '6') - { - // Jump to kernel's entry point. There's no going back now. XXX LEGACY OS XXX - startprog( kernelEntry, bootArgsLegacy ); + + switch (gMacOSVersion[3]) { + case '4': + case '5': + case '6': + // Jump to kernel's entry point. There's no going back now. XXX LEGACY OS XXX + startprog( kernelEntry, bootArgsLegacy ); + break; + case '7': + init_pic(); + // Jump to kernel's entry point. There's no going back now. XXX LION XXX + startprog( kernelEntry, bootArgs107 ); + default: +#if DEBUG_BOOT + printf("Error: Unsupported Darwin version\n"); + getc(); +#endif + break; } - - outb(0x21, 0xff); /* Maskout all interrupts Pic1 */ - outb(0xa1, 0xff); /* Maskout all interrupts Pic2 */ - - // Jump to kernel's entry point. There's no going back now. XXX LION XXX - startprog( kernelEntry, bootArgs ); + + // Should not be reached - // Not reached - return 0; } @@ -686,7 +701,7 @@ { bootFile = gBootKernelCacheFile; verbose("Loading kernel cache %s\n", bootFile); - if (gMacOSVersion[3] == '7') + if (gMacOSVersion[3] > '6') { ret = LoadThinFatFile(bootFile, &binary); if (ret <= 0 && archCpuType == CPU_TYPE_X86_64) @@ -838,7 +853,7 @@ } else { - if(gMacOSVersion[3] == '7') + if(gMacOSVersion[3] > '6') { sprintf(gBootKernelCacheFile, "%s", kDefaultCachePath); } Index: branches/cparm/i386/boot2/drivers.c =================================================================== --- branches/cparm/i386/boot2/drivers.c (revision 1723) +++ branches/cparm/i386/boot2/drivers.c (revision 1724) @@ -762,7 +762,7 @@ printf("adler mismatch\n"); return -1; } - if (((gBootMode & kBootModeSafe) == 0) && (gBootKernelCacheFile[0] != '\0') && gMacOSVersion[3] == '7') + if (((gBootMode & kBootModeSafe) == 0) && (gBootKernelCacheFile[0] != '\0') && gMacOSVersion[3] > '6') bootInfo->adler32 = kernel_header->adler32; } Index: branches/cparm/i386/boot2/mboot.c =================================================================== --- branches/cparm/i386/boot2/mboot.c (revision 1723) +++ branches/cparm/i386/boot2/mboot.c (revision 1724) @@ -322,8 +322,8 @@ This is the same assumption that initKernBootStruct makes. We could check the multiboot info I guess, but why bother? */ - boot_args temporaryBootArgsData; - bzero(&temporaryBootArgsData, sizeof(boot_args)); + boot_args_common temporaryBootArgsData; + bzero(&temporaryBootArgsData, sizeof(boot_args_common)); bootArgs = &temporaryBootArgsData; bootArgs->Video.v_display = VGA_TEXT_MODE; Index: branches/cparm/i386/boot2/options.c =================================================================== --- branches/cparm/i386/boot2/options.c (revision 1723) +++ branches/cparm/i386/boot2/options.c (revision 1724) @@ -588,7 +588,7 @@ // If the user is holding down a modifier key, enter safe mode. if ((readKeyboardShiftFlags() & 0x0F) != 0) { - //gBootMode |= kBootModeSafe; + gBootMode |= kBootModeSafe; } // Checking user pressed keys Index: branches/cparm/i386/modules/GUI/gui.c =================================================================== --- branches/cparm/i386/modules/GUI/gui.c (revision 1723) +++ branches/cparm/i386/modules/GUI/gui.c (revision 1724) @@ -12,6 +12,10 @@ * cparm : cleaned */ +/* + * cparm : add volume version detection + */ + #include "gui.h" #include "GUI_appleboot.h" #include "vers.h" @@ -48,6 +52,7 @@ static void colorFont(font_t *font, uint32_t color); static int initFont(font_t *font, image_t *data); static void drawStrCenteredAt(char *text, font_t *font, pixmap_t *blendInto, position_t p); +static position_t drawChar(unsigned char ch, font_t *font, pixmap_t *blendInto, position_t p); static void drawStr(char *ch, font_t *font, pixmap_t *blendInto, position_t p); #if DEBUG static int dprintf( window_t * window, const char * fmt, ...); @@ -89,6 +94,8 @@ #define vram VIDEO(baseAddr) +#define TAB_PIXELS_WIDTH (font->chars[0]->width * 4) // tab = 4 spaces + int lasttime = 0; // we need this for animating maybe extern int gDeviceCount; @@ -104,14 +111,32 @@ iDeviceGeneric_o, iDeviceHFS, iDeviceHFS_o, + iDeviceHFS_Lion, + iDeviceHFS_Lion_o, + iDeviceHFS_SL, + iDeviceHFS_SL_o, + iDeviceHFS_Leo, + iDeviceHFS_Leo_o, + iDeviceHFS_Tiger, + iDeviceHFS_Tiger_o, iDeviceHFSRAID, iDeviceHFSRAID_o, + iDeviceHFSRAID_Lion, + iDeviceHFSRAID_Lion_o, + iDeviceHFSRAID_SL, + iDeviceHFSRAID_SL_o, + iDeviceHFSRAID_Leo, + iDeviceHFSRAID_Leo_o, + iDeviceHFSRAID_Tiger, + iDeviceHFSRAID_Tiger_o, iDeviceEXT3, - iDeviceEXT3_o, + iDeviceEXT3_o, iDeviceFreeBSD, iDeviceFreeBSD_o, iDeviceOpenBSD, iDeviceOpenBSD_o, + iDeviceBEFS, /* Haiku detection and Icon credits to scorpius */ + iDeviceBEFS_o, /* Haiku detection and Icon credits to scorpius */ iDeviceFAT, iDeviceFAT_o, iDeviceFAT16, @@ -155,16 +180,37 @@ {.name = "device_generic", .image = NULL}, {.name = "device_generic_o", .image = NULL}, - {.name = "device_hfsplus", .image = NULL}, - {.name = "device_hfsplus_o", .image = NULL}, + + {.name = "device_hfsplus", .image = NULL}, + {.name = "device_hfsplus_o", .image = NULL}, + {.name = "device_hfsplus_lion", .image = NULL}, + {.name = "device_hfsplus_lion_o", .image = NULL}, + {.name = "device_hfsplus_sl", .image = NULL}, + {.name = "device_hfsplus_sl_o", .image = NULL}, + {.name = "device_hfsplus_leo", .image = NULL}, + {.name = "device_hfsplus_leo_o", .image = NULL}, + {.name = "device_hfsplus_tiger", .image = NULL}, + {.name = "device_hfsplus_tiger_o", .image = NULL}, + {.name = "device_hfsraid", .image = NULL}, {.name = "device_hfsraid_o", .image = NULL}, + {.name = "device_hfsplus_raid_lion", .image = NULL}, + {.name = "device_hfsplus_raid_lion_o", .image = NULL}, + {.name = "device_hfsplus_raid_sl", .image = NULL}, + {.name = "device_hfsplus_raid_sl_o", .image = NULL}, + {.name = "device_hfsplus_raid_leo", .image = NULL}, + {.name = "device_hfsplus_raid_leo_o", .image = NULL}, + {.name = "device_hfsplus_raid_tiger", .image = NULL}, + {.name = "device_hfsplus_raid_tiger_o", .image = NULL}, + {.name = "device_ext3", .image = NULL}, {.name = "device_ext3_o", .image = NULL}, {.name = "device_freebsd", .image = NULL}, {.name = "device_freebsd_o", .image = NULL}, {.name = "device_openbsd", .image = NULL}, {.name = "device_openbsd_o", .image = NULL}, + {.name = "device_befs", .image = NULL}, /* Haiku detection and Icon credits to scorpius */ + {.name = "device_befs_o", .image = NULL}, /* Haiku detection and Icon credits to scorpius */ {.name = "device_fat", .image = NULL}, {.name = "device_fat_o", .image = NULL}, {.name = "device_fat16", .image = NULL}, @@ -299,10 +345,13 @@ } if ((i = getImageIndexByName(image)) >= 0) - { - if (images[i].image == NULL) { - images[i].image = malloc(sizeof(pixmap_t)); - } + { + if (images[i].image == NULL) { + images[i].image = malloc(sizeof(pixmap_t)); + if (images[i].image == NULL) { + return 1; + } + } sprintf(dirspec, "%s/%s/%s.png", src, theme_name, image); width = 0; @@ -336,13 +385,20 @@ return 0; } #endif - else if (alt_image != IMG_REQUIRED && images[alt_image].image->pixels != NULL) + else if (alt_image != IMG_REQUIRED) { - // Using the passed alternate image for non-mandatory images. - // We don't clone the already existing pixmap, but using its properties instead! - images[i].image->width = images[alt_image].image->width; - images[i].image->height = images[alt_image].image->height; - images[i].image->pixels = images[alt_image].image->pixels; + if (images[alt_image].image->pixels != NULL) { + + // Using the passed alternate image for non-mandatory images. + // We don't clone the already existing pixmap, but using its properties instead! + images[i].image->width = images[alt_image].image->width; + images[i].image->height = images[alt_image].image->height; + images[i].image->pixels = images[alt_image].image->pixels; + } else { + free(images[i].image); + images[i].image = NULL; + } + return 0; } else @@ -351,10 +407,13 @@ printf("ERROR: GUI: could not open '%s/%s.png'!\n", theme_name, image); sleep(2); #endif - return 1; + free(images[i].image); + images[i].image = NULL; + return 1; + } - } - + + } return 1; } @@ -366,16 +425,37 @@ LOADPNG(src, device_generic, IMG_REQUIRED); LOADPNG(src, device_generic_o, iDeviceGeneric); + LOADPNG(src, device_hfsplus, iDeviceGeneric); LOADPNG(src, device_hfsplus_o, iDeviceHFS); + LOADPNG(src, device_hfsplus_lion, iDeviceHFS_Lion); + LOADPNG(src, device_hfsplus_lion_o, iDeviceHFS_Lion_o); + LOADPNG(src, device_hfsplus_sl, iDeviceHFS_SL); + LOADPNG(src, device_hfsplus_sl_o, iDeviceHFS_SL_o); + LOADPNG(src, device_hfsplus_leo, iDeviceHFS_Leo); + LOADPNG(src, device_hfsplus_leo_o, iDeviceHFS_Leo_o); + LOADPNG(src, device_hfsplus_tiger, iDeviceHFS_Tiger); + LOADPNG(src, device_hfsplus_tiger_o, iDeviceHFS_Tiger_o); + LOADPNG(src, device_hfsraid, iDeviceGeneric); LOADPNG(src, device_hfsraid_o, iDeviceHFSRAID); + LOADPNG(src, device_hfsplus_raid_lion, iDeviceHFSRAID_Lion); + LOADPNG(src, device_hfsplus_raid_lion_o, iDeviceHFSRAID_Lion_o); + LOADPNG(src, device_hfsplus_raid_sl, iDeviceHFSRAID_SL); + LOADPNG(src, device_hfsplus_raid_sl_o, iDeviceHFSRAID_SL_o); + LOADPNG(src, device_hfsplus_raid_leo, iDeviceHFSRAID_Leo); + LOADPNG(src, device_hfsplus_raid_leo_o, iDeviceHFSRAID_Leo_o); + LOADPNG(src, device_hfsplus_raid_tiger, iDeviceHFSRAID_Tiger); + LOADPNG(src, device_hfsplus_raid_tiger_o, iDeviceHFSRAID_Tiger_o); + LOADPNG(src, device_ext3, iDeviceGeneric); LOADPNG(src, device_ext3_o, iDeviceEXT3); LOADPNG(src, device_freebsd, iDeviceGeneric); LOADPNG(src, device_freebsd_o, iDeviceFreeBSD); LOADPNG(src, device_openbsd, iDeviceGeneric); LOADPNG(src, device_openbsd_o, iDeviceOpenBSD); + LOADPNG(src, device_befs, iDeviceGeneric); /* Haiku detection and Icon credits to scorpius */ + LOADPNG(src, device_befs_o, iDeviceBEFS); /* Haiku detection and Icon credits to scorpius */ LOADPNG(src, device_fat, iDeviceGeneric); LOADPNG(src, device_fat_o, iDeviceFAT); LOADPNG(src, device_fat16, iDeviceFAT); @@ -972,6 +1052,100 @@ return 1; } +/************************************************* + * + * Volume Versioning Management + */ + +volume_t* volumeList = NULL; + + +bool add_volume(char* Version, BVRef bvr) +{ + volume_t* new_volume= malloc(sizeof(volume_t)); + + if (new_volume) + { + new_volume->next = volumeList; + + volumeList = new_volume; + + strlcpy(new_volume->version,Version,sizeof(new_volume->version)+1); + new_volume->bvr = bvr; + return true; + } + + return false; + +} + +bool get_volume_version(char *str,BVRef bvr) +{ + volume_t* volume = volumeList; + while(volume) + { + if (volume->bvr == bvr) { + strlcpy(str,volume->version,sizeof(volume->version)+1); + return true; + } + volume = volume->next; + } + return false; +} + +static bool getOSVersionForVolume(char *str, BVRef bvr) +{ + bool valid = false; + + if (get_volume_version(str,bvr) == false) + { + char dirSpec[128]; + char dirSpec2[128]; + config_file_t systemVersion; + + sprintf(dirSpec, "hd(%d,%d)/System/Library/CoreServices/SystemVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + sprintf(dirSpec2, "hd(%d,%d)/System/Library/CoreServices/ServerVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + + if (!loadConfigFile(dirSpec, &systemVersion)) + { + valid = true; + } + else if (!loadConfigFile(dirSpec2, &systemVersion)) + { + valid = true; + } + + if (valid) + { + const char *val; + int len; + + if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) + { + // getValueForKey uses const char for val + // so copy it and trim + *str = '\0'; + strncat(str, val, MIN(len, 4)); + add_volume(str, bvr); + } + else + valid = false; + } + } + else + { + valid = true; + } + + return valid; +} + +static bool is_image_loaded(int i) +{ + return (images[i].image != NULL) ? true : false; +} + +/*************************************************/ static void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p, bool isSelected) { int devicetype; @@ -983,15 +1157,249 @@ switch (device->part_type) { case kPartitionTypeHFS: + { + char VolumeMacOSVersion[8]; + #ifdef BOOT_HELPER_SUPPORT // Use HFS or HFSRAID icon depending on bvr flags. - devicetype = (device->flags & kBVFlagBooter) ? iDeviceHFSRAID : iDeviceHFS; -#else - devicetype = iDeviceHFS; + if (device->flags & kBVFlagBooter) { + + getOSVersionForRaidVolume(VolumeMacOSVersion,device); + + switch (VolumeMacOSVersion[3]) { + case '7': + devicetype = is_image_loaded(iDeviceHFSRAID_Lion) ? iDeviceHFSRAID_Lion : is_image_loaded(iDeviceHFSRAID) ? iDeviceHFSRAID : iDeviceGeneric; + break; + case '6': + devicetype = is_image_loaded(iDeviceHFSRAID_SL) ? iDeviceHFSRAID_SL : is_image_loaded(iDeviceHFSRAID) ? iDeviceHFSRAID : iDeviceGeneric; + break; + case '5': + devicetype = is_image_loaded(iDeviceHFSRAID_Leo) ? iDeviceHFSRAID_Leo : is_image_loaded(iDeviceHFSRAID) ? iDeviceHFSRAID : iDeviceGeneric; + break; + case '4': + devicetype = is_image_loaded(iDeviceHFSRAID_Tiger) ? iDeviceHFSRAID_Tiger : is_image_loaded(iDeviceHFSRAID) ? iDeviceHFSRAID : iDeviceGeneric; + break; + default: + devicetype = is_image_loaded(iDeviceHFSRAID) ? iDeviceHFSRAID : iDeviceGeneric; + break; + } + + } else #endif + { + + getOSVersionForVolume(VolumeMacOSVersion,device); + + switch (VolumeMacOSVersion[3]) { + case '7': + devicetype = is_image_loaded(iDeviceHFS_Lion) ? iDeviceHFS_Lion : is_image_loaded(iDeviceHFS) ? iDeviceHFS : iDeviceGeneric; + break; + case '6': + devicetype = is_image_loaded(iDeviceHFS_SL) ? iDeviceHFS_SL : is_image_loaded(iDeviceHFS) ? iDeviceHFS : iDeviceGeneric; + break; + case '5': + devicetype = is_image_loaded(iDeviceHFS_Leo) ? iDeviceHFS_Leo : is_image_loaded(iDeviceHFS) ? iDeviceHFS : iDeviceGeneric; + break; + case '4': + devicetype = is_image_loaded(iDeviceHFS_Tiger) ? iDeviceHFS_Tiger : is_image_loaded(iDeviceHFS) ? iDeviceHFS : iDeviceGeneric; + break; + default: + devicetype = is_image_loaded(iDeviceHFS) ? iDeviceHFS : iDeviceGeneric; + break; + } + + } + break; + } case kPartitionTypeHPFS: + devicetype = is_image_loaded(iDeviceNTFS) ? iDeviceNTFS : iDeviceGeneric; // Use HPFS / NTFS icon + break; + + case kPartitionTypeFAT16: + devicetype = is_image_loaded(iDeviceFAT16) ? iDeviceFAT16 : iDeviceGeneric; // Use FAT16 icon + break; + + case kPartitionTypeFAT32: + devicetype = is_image_loaded(iDeviceFAT32) ? iDeviceFAT32 : iDeviceGeneric; // Use FAT32 icon + break; + + case kPartitionTypeEXT3: + devicetype = is_image_loaded(iDeviceEXT3) ? iDeviceEXT3 : iDeviceGeneric; // Use EXT2/3 icon + break; + + case kPartitionTypeFreeBSD: + devicetype = is_image_loaded(iDeviceFreeBSD) ? iDeviceFreeBSD : iDeviceGeneric; // Use FreeBSD icon + break; + + case kPartitionTypeOpenBSD: + devicetype = is_image_loaded(iDeviceOpenBSD) ? iDeviceOpenBSD : iDeviceGeneric; // Use OpenBSD icon + break; + + case kPartitionTypeBEFS: /* Haiku detection and Icon credits to scorpius */ + devicetype = is_image_loaded(iDeviceBEFS) ? iDeviceBEFS : iDeviceGeneric;// Use BEFS / Haiku icon + break; + + default: + devicetype = iDeviceGeneric; // Use Generic icon + break; + } + } + + // Draw the selection image and use the next (device_*_o) image for the selected item. + if (isSelected) + { + blend(images[iSelection].image, buffer, centeredAt(images[iSelection].image, p)); + devicetype++; // selec override image + } + + // draw icon + blend( images[devicetype].image, buffer, centeredAt( images[devicetype].image, p )); + + p.y += (images[iSelection].image->height / 2) + font_console.chars[0]->height; + + // draw volume label + drawStrCenteredAt( device->label, &font_small, buffer, p); + +} + +#if 0 +static void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p, bool isSelected) +{ + int devicetype; + + if( diskIsCDROM(device) ) + devicetype = iDeviceCDROM; // Use CDROM icon + else + { + switch (device->part_type) + { + case kPartitionTypeHFS: + { + bool hfs_img_replacement_found = false; + char VolumeMacOSVersion[8]; + +#ifdef BOOT_HELPER_SUPPORT + // Use HFS or HFSRAID icon depending on bvr flags. + if (device->flags & kBVFlagBooter) { + + if (getOSVersionForRaidVolume(VolumeMacOSVersion,device)) + { + int i ; + if (VolumeMacOSVersion[3] == '7') { + if ((i = getImageIndexByName("device_hfsplus_raid_lion")) >= 0) + { + if (images[i].image != NULL) { + hfs_img_replacement_found = true; + } + } + } else if (VolumeMacOSVersion[3] == '6') { + if ((i = getImageIndexByName("device_hfsplus_raid_sl")) >= 0) + { + if (images[i].image != NULL) { + hfs_img_replacement_found = true; + } + } + } else if (VolumeMacOSVersion[3] == '5') { + if ((i = getImageIndexByName("device_hfsplus_raid_leo")) >= 0) + { + if (images[i].image != NULL) { + hfs_img_replacement_found = true; + } + } + } else if (VolumeMacOSVersion[3] == '4') { + if ((i = getImageIndexByName("device_hfsplus_raid_tiger")) >= 0) + { + if (images[i].image != NULL) { + hfs_img_replacement_found = true; + } + } + } + } + + switch (VolumeMacOSVersion[3]) { + case '7': + devicetype = (hfs_img_replacement_found) ? iDeviceHFSRAID_Lion : iDeviceHFSRAID; + break; + case '6': + devicetype = (hfs_img_replacement_found) ? iDeviceHFSRAID_SL : iDeviceHFSRAID; + break; + case '5': + devicetype = (hfs_img_replacement_found) ? iDeviceHFSRAID_Leo : iDeviceHFSRAID; + break; + case '4': + devicetype = (hfs_img_replacement_found) ? iDeviceHFSRAID_Tiger : iDeviceHFSRAID; + break; + default: + devicetype = iDeviceHFSRAID; + break; + } + + } else +#endif + { + + if (getOSVersionForVolume(VolumeMacOSVersion,device)) + { + + int i ; + if (VolumeMacOSVersion[3] == '7') { + if ((i = getImageIndexByName("device_hfsplus_lion")) >= 0) + { + if (images[i].image != NULL) { + hfs_img_replacement_found = true; + } + } + } else if (VolumeMacOSVersion[3] == '6') { + if ((i = getImageIndexByName("device_hfsplus_sl")) >= 0) + { + if (images[i].image != NULL) { + hfs_img_replacement_found = true; + } + } + } else if (VolumeMacOSVersion[3] == '5') { + if ((i = getImageIndexByName("device_hfsplus_leo")) >= 0) + { + if (images[i].image != NULL) { + hfs_img_replacement_found = true; + } + } + } else if (VolumeMacOSVersion[3] == '4') { + if ((i = getImageIndexByName("device_hfsplus_tiger")) >= 0) + { + if (images[i].image != NULL) { + hfs_img_replacement_found = true; + } + } + } + + } + + switch (VolumeMacOSVersion[3]) { + case '7': + devicetype = (hfs_img_replacement_found) ? iDeviceHFS_Lion : iDeviceHFS; + break; + case '6': + devicetype = (hfs_img_replacement_found) ? iDeviceHFS_SL : iDeviceHFS; + break; + case '5': + devicetype = (hfs_img_replacement_found) ? iDeviceHFS_Leo : iDeviceHFS; + break; + case '4': + devicetype = (hfs_img_replacement_found) ? iDeviceHFS_Tiger : iDeviceHFS; + break; + default: + devicetype = iDeviceHFS; + break; + } + + } + + break; + + } + case kPartitionTypeHPFS: devicetype = iDeviceNTFS; // Use HPFS / NTFS icon break; @@ -1015,6 +1423,10 @@ devicetype = iDeviceOpenBSD; // Use OpenBSD icon break; + case kPartitionTypeBEFS: /* Haiku detection and Icon credits to scorpius */ + devicetype = iDeviceBEFS;// Use BEFS / Haiku icon + break; + default: devicetype = iDeviceGeneric; // Use Generic icon break; @@ -1037,7 +1449,7 @@ drawStrCenteredAt( device->label, &font_small, buffer, p); } - +#endif void drawDeviceList (int start, int end, int selection) { int i; @@ -1530,34 +1942,52 @@ return 1; } +pixmap_t* charToPixmap(unsigned char ch, font_t *font) { + unsigned int cha = (unsigned int)ch - 32; + if (cha >= font->count) + // return ? if the font for the char doesn't exists + cha = '?' - 32; + return font->chars[cha] ? font->chars[cha] : NULL; +} + +static position_t drawChar(unsigned char ch, font_t *font, pixmap_t *blendInto, position_t p) { + pixmap_t* pm = charToPixmap(ch, font); + if (pm && ((p.x + pm->width) < blendInto->width)) + { + blend(pm, blendInto, p); + return pos(p.x + pm->width, p.y); + } + else + return p; +} + static void drawStr(char *ch, font_t *font, pixmap_t *blendInto, position_t p) { int i=0; - int y=0; // we need this to support multilines '\n' - int x=0; + position_t current_pos = pos(p.x, p.y); - for(i=0;iheight; + current_pos.x = p.x; + current_pos.y += font->height; continue; } // tab ? - if( ch[i] == '\t' ) - x+=(font->chars[0]->width*5); + if ( ch[i] == '\t' ) + { + current_pos.x += TAB_PIXELS_WIDTH; + continue; + } - if(font->chars[cha]) - blend(font->chars[cha], blendInto, pos(p.x+x, p.y+y)); - - x += font->chars[cha]->width; + current_pos = drawChar(ch[i], font, blendInto, current_pos); } } @@ -1565,32 +1995,32 @@ { int i = 0; int width = 0; - + int max_width = 0; + int height = font->height; + // calculate the width in pixels - for(i=0;ichars[text[i]-32]->width; - - p.x = ( p.x - ( width / 2 ) ); - p.y = ( p.y - ( font->height / 2 ) ); - - if ( p.x == -6 ) - { - p.x = 0; - } - - for(i=0;ichars[cha]) + for (i=0; i < strlen(text); i++) { + if (text[i] == '\n') { - blend(font->chars[cha], blendInto, p); - p.x += font->chars[cha]->width; + width = 0; + height += font->height; } + else if (text[i] == '\t') + width += TAB_PIXELS_WIDTH; + else + { + pixmap_t* pm = charToPixmap(text[i], font); + if (pm) + width += pm->width; + } + if (width > max_width) + max_width = width; } + p.x = ( p.x - ( max_width / 2 ) ); + p.y = ( p.y - ( height / 2 ) ); + + drawStr(text, font, blendInto, p); } static int initFont(font_t *font, image_t *data) @@ -1603,7 +2033,7 @@ font->height = data->image->height; - for( x = 0; x < data->image->width; x++) + for( x = 0; x < data->image->width && count < CHARACTERS_COUNT; x++) { start = end; @@ -1641,9 +2071,14 @@ } } + for (x = count; x < CHARACTERS_COUNT; x++) + font->chars[x] = NULL; + if(monospaced) font->width = 0; + font->count = count; + return 0; } Index: branches/cparm/i386/modules/GUI/gui.h =================================================================== --- branches/cparm/i386/modules/GUI/gui.h (revision 1723) +++ branches/cparm/i386/modules/GUI/gui.h (revision 1724) @@ -70,12 +70,22 @@ } image_t; /* + * Volume structure. + */ +typedef struct volume_t { + char version[8]; + BVRef bvr; + struct volume_t* next; +} volume_t; + +/* * Font structure. */ typedef struct { uint16_t height; // Font Height uint16_t width; // Font Width for monospace font only pixmap_t *chars[CHARACTERS_COUNT]; + uint16_t count; // Number of chars in font } font_t; /* @@ -130,25 +140,20 @@ int initGUI(); -//int startGUI(); void drawBootGraphics(void); void drawBackground(); void drawLogo(); -//void setupDeviceList(config_file_t *theme); -//void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p, bool isSelected); + void drawDeviceList(int start, int end, int selection); -//void drawProgressBar(pixmap_t *blendInto, uint16_t width, position_t p, uint8_t progress); void showInfoBox(char *title, char *text); -//int dprintf( window_t * window, const char * fmt, ...); int gprintf( window_t * window, const char * fmt, ...); int vprf(const char * fmt, va_list ap); int drawInfoMenu(); int updateInfoMenu(int key); -//void drawInfoMenuItems(); void showGraphicBootPrompt(); void clearGraphicBootPrompt(); @@ -156,7 +161,4 @@ void updateVRAM(); -//void drawStr(char *ch, font_t *font, pixmap_t *blendInto, position_t p); -//void drawStrCenteredAt(char *ch, font_t *font, pixmap_t *blendInto, position_t p); - #endif /* !__BOOT2_GUI_H */ Index: branches/cparm/README =================================================================== --- branches/cparm/README (revision 1723) +++ branches/cparm/README (revision 1724) @@ -1,4 +1,3 @@ Chameleon is a Darwin/XNU boot loader based on Apple's boot-132. -WARNING: FOR NOW, THIS PROJECT IS NOT YET FULLY COMPATIBLE WITH XCODE4 - (AFAIK ONLY THE MODULES GUI AND SMBIOSGETTERS WILL NOT WORK WITH XCODE4, EVEN IF THEY ARE BUILT WITHOUT ANY ERRORS) \ No newline at end of file +WARNING: THIS PROJECT IS NOT COMPATIBLE WITH XCODE4 \ No newline at end of file