Index: branches/ErmaC/Enoch/i386/libsaio/disk.c =================================================================== --- branches/ErmaC/Enoch/i386/libsaio/disk.c (revision 2836) +++ branches/ErmaC/Enoch/i386/libsaio/disk.c (revision 2837) @@ -1698,9 +1698,20 @@ static bool getOSVersion(BVRef bvr, char *str) { bool valid = false; - config_file_t systemVersion; + config_file_t configFile; char dirSpec[512]; + const char *val; int len; + const char *fakeOSVersion; + int fakeOSVersionInt; + // our pattern: avoiding to use full path. this help if the app is named as Beta or DP.. + char *LionPattern = "Install%20Mac%20OS%20X%20Lion"; + char *MLPattern = "Install%20OS%20X%20Mountain%20Lion"; + char *MavPattern = "Install%20OS%20X%20Mavericks"; + char *YosPattern = "Install%20OS%20X%20Yosemite"; + char *ECPattern = "Install%20OS%20X%20El%20Capitan"; + char *SierraPattern = "Install%10.12"; + /* * Only look for OS Version on HFS+ */ @@ -1709,99 +1720,264 @@ return valid; } - // OS X Recovery - sprintf(dirSpec, "hd(%d,%d)/com.apple.recovery.boot/SystemVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + /* + * Micky1979, let it search for the right Version *.plist + * + * NOTE: + * order is important because vanilla installer (createinstallermedia method 10.9 +) has both /.IABootFilesSystemVersion.plist and + * /System/Library/CoreServices/SystemVersion.plist otherwise fail to recognize it as Installer! + * + * OS X Installer made by the Vanilla app for Lion and newer. + * This kind of Installer can be a guest in a already working System, and produces some temporary files: + * 1) ".IABootFiles" folder is created in the root of the same partition where the app reside. + * 2) "Mac OS X Install Data" or "OS X Install Data" in the target partition + * 3) The presence of ".IABootFilesSystemVersion.plist" file if present or not, distinguishes this installer + * by the one create with "createinstallmedia" method (is present), so we know what kind of installer is. + */ - if (!loadConfigFile(dirSpec, &systemVersion)) + // is an installer or a system to Upgrade OSX? + snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/.IAProductInfo", BIOS_DEV_UNIT(bvr), bvr->part_no); + + if (!loadConfigFile(dirSpec, &configFile)) { - bvr->OSisInstaller = true; valid = true; } - if (!valid) + if (valid) { - // OS X Standard - snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/System/Library/CoreServices/SystemVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); - - if (!loadConfigFile(dirSpec, &systemVersion)) + // is createinstallmedia? + snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/.IABootFilesSystemVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + if (!loadConfigFile(dirSpec, &configFile)) { - bvr->OSisInstaller = false; - valid = true; + valid = false; } else { - // OS X Server - snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/System/Library/CoreServices/ServerVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); - - if (!loadConfigFile(dirSpec, &systemVersion)) + // if not exist probably is a vanilla installer made w/o createinstallermedia method + snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/.IABootFiles/com.apple.Boot.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + if (!loadConfigFile(dirSpec, &configFile)) { - bvr->OSisServer = false; valid = true; } -/* else + else { - snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/.IAProductInfo", BIOS_DEV_UNIT(bvr), bvr->part_no); - - if (!loadConfigFile(dirSpec, &systemVersion)) - { - - } + valid = false; } -*/ } + } - if ( LION ) + if (valid) + { + /* + * we don't know the real OS version, but "Kernel Flags" key contain the URL path to the app.. + * and we try to see if contain a match for our patterns ("Install%20OS%20X%20El%20Capitan" = 10.11) + */ + if (getValueForKey("Kernel Flags", &val, &len, &configFile)) { - int fh = -1; - snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/.PhysicalMediaInstall", BIOS_DEV_UNIT(bvr), bvr->part_no); - fh = open(dirSpec, 0); - - if (fh >= 0) + if(strstr(val, LionPattern)) { + fakeOSVersion = "10.7"; + fakeOSVersionInt = 7; valid = true; - bvr->OSisInstaller = true; - strcpy(bvr->OSVersion, "10.7"); // 10.7 + - close(fh); } + else if(strstr(val, MLPattern)) + { + fakeOSVersion = "10.8"; + fakeOSVersionInt = 8; + valid = true; + } + else if(strstr(val, MavPattern)) + { + fakeOSVersion = "10.9"; + fakeOSVersionInt = 9; + valid = true; + } + else if(strstr(val, YosPattern)) + { + fakeOSVersion = "10.10"; + fakeOSVersionInt = 10; + valid = true; + } + else if(strstr(val, ECPattern)) + { + fakeOSVersion = "10.11"; + fakeOSVersionInt = 11; + valid = true; + } + else if(strstr(val, SierraPattern)) + { + fakeOSVersion = "10.12"; + fakeOSVersionInt = 12; + valid = true; + } else { - close(fh); + valid = false; } } + else + { + valid = false; + } + } -// if ( MOUNTAIN_LION ){} + if (valid) + { + /* + * if we are here that is an createinstallmedia Installer! + * fake the OS version so we can find the right path to the kernelcache/prelinked! + * To patch the kernelcache we aquire the "Darwin versionn" later.. + */ + strncpy( bvr->OSFullVer, fakeOSVersion, strlen(fakeOSVersion) ); + bvr->OSisInstaller = true; + // no SystemVersion.plist ...so no build... + strncpy( bvr->OSBuildVer, "INSTALLER", strlen("INSTALLER") ); + return true; + } - if ( MAVERICKS ) + /* + * Not valid? But we have the "/.IAProductInfo" in the root so this is not a conventional installer + * and probably this is an Upgrade made by the "Install OS X app" + */ + if (!valid) + { + len = 0; val = 0; + // 10.9 and later use "/OS X Install Data" folder + snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/OS X Install Data/com.apple.Boot.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + if (!loadConfigFile(dirSpec, &configFile)) { - int fh = -1; - snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/.IAPhysicalMedia", BIOS_DEV_UNIT(bvr), bvr->part_no); - fh = open(dirSpec, 0); + /* + * bad is that we can't find what is the exactly Major OS version.. + * but what we need is the right path to the kernel cache: + * kernelcache = 10.9 and 10.10 + * prelinkedkernel = 10.11 and later - if (fh >= 0) + * so we fake the OS version just to find the correct path! + * .. later the right "Darwin Version" will use to patch the kernel cache! + */ + + if (getValueForKey("Kernel Cache", &val, &len, &configFile)) { - valid = true; - bvr->OSisInstaller = true; - strcpy(bvr->OSVersion, "10.9"); // 10.9 + + if(strstr(val, "prelinkedkernel")) // /OS X Install Data/prelinkedkernel + { + fakeOSVersion = "10.11"; // fake OS to find prelinkedkernel on newer OSes + + switch (fakeOSVersionInt) + { + case 11: + fakeOSVersion = "10.11"; + break; + case 12: + fakeOSVersion = "10.12"; + break; + default: + fakeOSVersion = "10.12"; + break; + } + + valid = true; + } + else if(strstr(val, "kernelcache")) // /OS X Install Data/kernelcache + { + fakeOSVersion = "10.10"; // fake OS to find prelinkedkernel on 10.9 and 10.10 + valid = true; + } + else + { + valid = false; + } + + if (valid) + { + strncpy( bvr->OSFullVer, fakeOSVersion, strlen(fakeOSVersion) ); + bvr->OSisOSXUpgrade = true; + strncpy( bvr->OSBuildVer, "UPGRADE", strlen("UPGRADE") ); + return true; + } } else { - close(fh); + valid = false; } + } + else + { + valid = false; + } + } -// if ( YOSEMITE ){} + if (!valid) + { + /* + * Not valid? 10.8 and older use "/Mac OS X Install Data" folder.. + */ + snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/Mac OS X Install Data/com.apple.Boot.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + if (!loadConfigFile(dirSpec, &configFile)) + { + fakeOSVersion = "10.8"; // fake the OS version using 10.8.. just to find the kernelcache path for 10.7 and 10.8.. + strncpy( bvr->OSFullVer, fakeOSVersion, strlen(fakeOSVersion) ); + bvr->OSisMacOSXUpgrade = true; + // again no SystemVersion.plist, so no build version.. but is usefull to know that is a System upgrade.. + strncpy( bvr->OSBuildVer, "UPGRADE", strlen("UPGRADE") ); + return true; + } + else + { + valid = false; + } + } -// if ( ELCAPITAN ){} + len = 0; val = 0; + // OS X Installer createinstallermedia method for 10.9 and newer. + snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/.IABootFilesSystemVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + + if (!loadConfigFile(dirSpec, &configFile)) + { + bvr->OSisInstaller = true; + valid = true; } + // OS X Standard + if (!valid) + { + snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/System/Library/CoreServices/SystemVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + + if (!loadConfigFile(dirSpec, &configFile)) + { + valid = true; + } + else + { + // OS X Server + snprintf(dirSpec, sizeof(dirSpec), "hd(%d,%d)/System/Library/CoreServices/ServerVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + + if (!loadConfigFile(dirSpec, &configFile)) + { + bvr->OSisServer = true; + valid = true; + } + } + } + + if (!valid) + { + // OS X Recovery + sprintf(dirSpec, "hd(%d,%d)/com.apple.recovery.boot/SystemVersion.plist", BIOS_DEV_UNIT(bvr), bvr->part_no); + + if (!loadConfigFile(dirSpec, &configFile)) + { + bvr->OSisRecovery = true; + valid = true; + } + } + if (valid) { - const char *val; - int len; // ProductVersion - if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) + if (getValueForKey(kProductVersion, &val, &len, &configFile)) { // Copy the complete value into OSFullVer strncpy( bvr->OSFullVer, val, len ); @@ -1815,6 +1991,14 @@ { str[4] = '\0'; } + + // ProductBuildVersion + if (getValueForKey(kProductBuildVersion, &val, &len, &configFile)) + { + strncpy( bvr->OSBuildVer, val, len ); + bvr->OSBuildVer[len] = '\0'; /* null character manually added */ + } + } else { Index: branches/ErmaC/Enoch/i386/libsaio/stringTable.c =================================================================== --- branches/ErmaC/Enoch/i386/libsaio/stringTable.c (revision 2836) +++ branches/ErmaC/Enoch/i386/libsaio/stringTable.c (revision 2837) @@ -663,7 +663,7 @@ "/com.apple.recovery.boot/com.apple.Boot.plist", // OS X Recovery "/OS X Install Data/com.apple.Boot.plist", // OS X Upgrade (10.8+) "/Mac OS X Install Data/com.apple.Boot.plist", // OS X Upgrade (Lion 10.7) - //"/.IABootFiles/com.apple.Boot.plist", // OS X Installer + "/.IABootFiles/com.apple.Boot.plist", // OS X Installer "/Library/Preferences/SystemConfiguration/com.apple.Boot.plist" // (Installed System or Installer) }; Index: branches/ErmaC/Enoch/i386/libsaio/saio_types.h =================================================================== --- branches/ErmaC/Enoch/i386/libsaio/saio_types.h (revision 2836) +++ branches/ErmaC/Enoch/i386/libsaio/saio_types.h (revision 2837) @@ -214,8 +214,10 @@ char OSFullVer[OSVERSTRLEN]; /* Null terminated string from '/System/Library/CoreServices/SystemVersion.plist/ProductVersion' */ char OSBuildVer[OSVERSTRLEN];/* Null terminated string from '/System/Library/CoreServices/SystemVersion.plist/ProductBuildVersion' */ bool OSisServer; /* 1 = OS X server , 0 = OS X client */ - bool OSisInstaller; /* 1 = OS X Install partition / recovery partition , 0 = OS X Install */ - + bool OSisInstaller; /* 1 = OS X Installer */ + bool OSisMacOSXUpgrade; /* 1 = OS X Installer Upgrade */ + bool OSisOSXUpgrade; /* 1 = OS X Installer Upgrade */ + bool OSisRecovery; /* 1 = Recovery HD partition */ }; enum Index: branches/ErmaC/Enoch/i386/boot2/drivers.c =================================================================== --- branches/ErmaC/Enoch/i386/boot2/drivers.c (revision 2836) +++ branches/ErmaC/Enoch/i386/boot2/drivers.c (revision 2837) @@ -202,6 +202,11 @@ } verbose("Attempting to loading drivers from \"Extra\" repository:\n"); + // ===================================================================== + // Firstly try to load drivers from Common folder + sprintf(dirSpecExtra, "bt(0,0)/Extra/Common/"); + FileLoadDrivers(dirSpecExtra, 0); + // ===================================================================== // Next try to load Extra extensions from the selected root partition. strlcpy(dirSpecExtra, "/Extra/", sizeof(dirSpecExtra)); @@ -1000,6 +1005,7 @@ } // Bungo: scan binary for Darwin Kernel Version string + useDarwinVersion = true; uint32_t offset = 0; strncpy(gDarwinBuildVerStr, "Darwin Kernel Version", sizeof(gDarwinBuildVerStr)); @@ -1014,8 +1020,206 @@ else { strcat(gDarwinBuildVerStr, ": Unknown"); + useDarwinVersion = false; } + // Micky1979 use Bungo gDarwinBuildVerStr and split into gDarwinMajor, gDarwinMinor and gDarwinRev + if (useDarwinVersion) + { + useDarwinVersion = false; + const char *pattern = strstr(gDarwinBuildVerStr, "Darwin Kernel Version ")+22; + const char *until = strstr(pattern, ":"); + size_t vlen = until - pattern; + char *ver = (char *)malloc(sizeof(char)*(len+1)); + strncpy(ver, pattern, vlen); + ver[vlen] = '\0'; + char *delim; + char *temp; + gDarwinMajor = -1; gDarwinMinor = -1; gDarwinRev = -1; + if (ver != NULL) + { + temp = ver; + int count = 1; + while ((delim = strsep_c(&ver, ".")) != NULL) + { + switch (count) + { + case 1: gDarwinMajor = atoi(delim); break; + case 2: gDarwinMinor = atoi(delim); break; + case 3: gDarwinRev = atoi(delim); break; + default: break; + } + count ++; + } + free(temp); + } + if (gDarwinMajor >= 0 && gDarwinMinor >= 0 && gDarwinRev >= 0) + { + useDarwinVersion = true; + } + + switch (gDarwinMajor) + { + case 10: + switch (gDarwinMinor) + { + case 0: kernelOSVer = 0xA060000; break; + case 1: kernelOSVer = 0xA060100; break; + case 2: kernelOSVer = 0xA060200; break; + case 3: kernelOSVer = 0xA060300; break; + case 4: kernelOSVer = 0xA060400; break; + case 5: kernelOSVer = 0xA060500; break; + case 6: kernelOSVer = 0xA060600; break; + case 7: kernelOSVer = 0xA060700; break; + case 8: kernelOSVer = 0xA060800; break; + default:kernelOSVer = 0xA060800; break; //Last known kernel + } + break; + case 11: + switch (gDarwinMinor) + { + case 0: kernelOSVer = 0xA070000; break; + case 1: kernelOSVer = 0xA070100; break; + case 2: kernelOSVer = 0xA070200; break; + case 3: kernelOSVer = 0xA070300; break; + case 4: + switch (gDarwinRev) + { + case 0: kernelOSVer = 0xA070400; break; + case 1: kernelOSVer = 0xA070400; break; + case 2: kernelOSVer = 0xA070500; break; + default:kernelOSVer = 0xA070500; break; //Last known kernel + } + default:kernelOSVer = 0xA070500; break; //Last known kernel + } + break; + case 12: + switch (gDarwinMinor) + { + case 0: kernelOSVer = 0xA080000; break; + case 1: kernelOSVer = 0xA080100; break; + case 2: kernelOSVer = 0xA080200; break; + case 3: kernelOSVer = 0xA080300; break; + case 4: kernelOSVer = 0xA080400; break; + case 5: kernelOSVer = 0xA080500; break; // 10.8.5 + case 6: kernelOSVer = 0xA080500; break; // 10.8.5 update + default:kernelOSVer = 0xA080500; break; //Last known kernel + } + break; + case 13: + switch (gDarwinMinor) + { + case 0: kernelOSVer = 0xA090000; + switch (gDarwinRev) + { + case 0: kernelOSVer = 0xA090000; break; + case 1: kernelOSVer = 0xA090000; break; // never exist (or released) + case 2: kernelOSVer = 0xA090100; break; + default:kernelOSVer = 0xA090100; break; //Last known kernel + } + break; + case 1: kernelOSVer = 0xA090100; break; // never exist (or released) + case 2: kernelOSVer = 0xA090200; break; + case 3: kernelOSVer = 0xA090300; break; + case 4: kernelOSVer = 0xA090400; break; + case 5: kernelOSVer = 0xA090500; break; + default:kernelOSVer = 0xA090500; break; //Last known kernel + } + break; + case 14: + switch (gDarwinMinor) + { + case 0: kernelOSVer = 0xA0A0000; break; // same kernel of 10.10.1 + case 1: kernelOSVer = 0xA0A0100; break; // same kernel of 10.10 + case 2: kernelOSVer = 0xA0A0200; break; + case 3: kernelOSVer = 0xA0A0300; break; + case 4: kernelOSVer = 0xA0A0400; break; + case 5: kernelOSVer = 0xA0A0500; break; + default:kernelOSVer = 0xA0A0500; break; //Last known kernel + } + break; + case 15: + switch (gDarwinMinor) + { + case 0: kernelOSVer = 0xA0B0000; break; + case 1: kernelOSVer = 0xA0B0100; break; + case 2: kernelOSVer = 0xA0B0200; break; + case 3: kernelOSVer = 0xA0B0300; break; + case 4: kernelOSVer = 0xA0B0400; break; + case 5: kernelOSVer = 0xA0B0500; break; + case 6: kernelOSVer = 0xA0B0600; break; + default:kernelOSVer = 0xA0B0600; break; //Last known kernel (add here updates) + } + break; + case 16: + switch (gDarwinMinor) + { + case 0: kernelOSVer = 0xA0C0000; break; + default:kernelOSVer = 0xA0C0000; break; //Last known kernel (add here updates) + } + break; + default: + kernelOSVer = 0xA0B0100; + break; //Last known kernel + } + } + else + { + switch (MacOSVerCurrent) + { + // Snow + case 0xA060000: gDarwinMajor = 10; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.6 + case 0xA060100: gDarwinMajor = 10; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.6.1 + case 0xA060200: gDarwinMajor = 10; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.6.2 + case 0xA060300: gDarwinMajor = 10; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.6.3 + case 0xA060400: gDarwinMajor = 10; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.6.4 + case 0xA060500: gDarwinMajor = 10; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.6.5 + case 0xA060600: gDarwinMajor = 10; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.6.6 + case 0xA060700: gDarwinMajor = 10; gDarwinMinor = 7; gDarwinRev = 0; break; // 10.6.7 + case 0xA060800: gDarwinMajor = 10; gDarwinMinor = 8; gDarwinRev = 0; break; // 10.6.8 + // Lion + case 0xA070000: gDarwinMajor = 11; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.7 + case 0xA070100: gDarwinMajor = 11; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.7.1 + case 0xA070200: gDarwinMajor = 11; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.7.2 + case 0xA070300: gDarwinMajor = 11; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.7.3 + case 0xA070400: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.7.4 + case 0xA070500: gDarwinMajor = 11; gDarwinMinor = 4; gDarwinRev = 2; break; // 10.7.5 + // ML + case 0xA080000: gDarwinMajor = 12; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.8 + case 0xA080100: gDarwinMajor = 12; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.8.1 + case 0xA080200: gDarwinMajor = 12; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.8.2 + case 0xA080300: gDarwinMajor = 12; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.8.3 + case 0xA080400: gDarwinMajor = 12; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.8.4 + case 0xA080500: gDarwinMajor = 12; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.8.5 + // Mavericks + case 0xA090000: gDarwinMajor = 13; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.9 + case 0xA090100: gDarwinMajor = 13; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.9.1 + case 0xA090200: gDarwinMajor = 13; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.9.2 + case 0xA090300: gDarwinMajor = 13; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.9.3 + case 0xA090400: gDarwinMajor = 13; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.9.4 + case 0xA090500: gDarwinMajor = 13; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.9.5 + // Yosemite + case 0xA0A0000: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10 + case 0xA0A0100: gDarwinMajor = 14; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.10.1 + case 0xA0A0200: gDarwinMajor = 14; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.10.2 + case 0xA0A0300: gDarwinMajor = 14; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.10.3 + case 0xA0A0400: gDarwinMajor = 14; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.10.4 + case 0xA0A0500: gDarwinMajor = 14; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.10.5 + // El Capitan + case 0xA0B0000: gDarwinMajor = 15; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.11 + case 0xA0B0100: gDarwinMajor = 15; gDarwinMinor = 1; gDarwinRev = 0; break; // 10.11.1 + case 0xA0B0200: gDarwinMajor = 15; gDarwinMinor = 2; gDarwinRev = 0; break; // 10.11.2 + case 0xA0B0300: gDarwinMajor = 15; gDarwinMinor = 3; gDarwinRev = 0; break; // 10.11.3 + case 0xA0B0400: gDarwinMajor = 15; gDarwinMinor = 4; gDarwinRev = 0; break; // 10.11.4 + case 0xA0B0500: gDarwinMajor = 15; gDarwinMinor = 5; gDarwinRev = 0; break; // 10.11.5 + case 0xA0B0600: gDarwinMajor = 15; gDarwinMinor = 6; gDarwinRev = 0; break; // 10.11.6 + // Sierra + case 0xA0C0000: gDarwinMajor = 16; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.12 + // default = last known kernel + default: gDarwinMajor = 16; gDarwinMinor = 0; gDarwinRev = 0; break; // 10.12; + } + } + // Notify modules that the kernel has been decompressed, thinned and is about to be decoded execute_hook("DecodeKernel", (void *)binary, NULL, NULL, NULL); Index: branches/ErmaC/Enoch/i386/boot2/boot.c =================================================================== --- branches/ErmaC/Enoch/i386/boot2/boot.c (revision 2836) +++ branches/ErmaC/Enoch/i386/boot2/boot.c (revision 2837) @@ -81,6 +81,12 @@ bool gScanSingleDrive; bool useGUI; +/* recovery or installer ? */ +bool isInstaller; +bool isRecoveryHD; +bool isMacOSXUpgrade; +bool isOSXUpgrade; + #if DEBUG_INTERRUPTS static int interruptsAvailable = 0; #endif @@ -331,21 +337,108 @@ } closedir(cacheDir); } - else if ( MacOSVerCurrent >= MacOSVer2Int("10.7") && MacOSVerCurrent < MacOSVer2Int("10.10") ) + else if ( MacOSVerCurrent >= MacOSVer2Int("10.7") && MacOSVerCurrent < MacOSVer2Int("10.9") ) { - // Lion, Mountain Lion and Mavericks prelink kernel cache file - // for 10.7 10.8 10.9 - snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCachePathSnow); + // Lion, Mountain Lion + // for 10.7 10.8 + if (isMacOSXUpgrade) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", "/Mac OS X Install Data/"); + } + else if (isInstaller) + { + if (MacOSVerCurrent >= MacOSVer2Int("10.7") && MacOSVerCurrent < MacOSVer2Int("10.8") ) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kLionInstallerDataFolder); + } + else if ( MacOSVerCurrent >= MacOSVer2Int("10.8") && MacOSVerCurrent < MacOSVer2Int("10.9") ) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kMLionInstallerDataFolder); + } + + } + else if (isRecoveryHD) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCacheRecoveryHD); + } + else + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCachePathSnow); + } + verbose("Kernel Cache file path (Mac OS X 10.7 and newer): %s\n", kernelCacheFile); } - else + else if ( MacOSVerCurrent >= MacOSVer2Int("10.9") && MacOSVerCurrent < MacOSVer2Int("10.10") ) { - // Yosemite and El Capitan prelink kernel cache file - // for 10.10 10.11 - snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%sprelinkedkernel", kDefaultCachePathYosemite); - verbose("Kernel Cache file path (OS X 10.10 and newer): %s\n", kernelCacheFile); + // Mavericks prelinked cache file + // for 10.9 + if (isOSXUpgrade) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", "/OS X Install Data/"); + } + else if (isInstaller) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCacheInstallerNew); + } + else if (isRecoveryHD) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCacheRecoveryHD); + } + else + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCachePathSnow); + } + + verbose("Kernel Cache file path (OS X 10.9): %s\n", kernelCacheFile); + } + else if ( MacOSVerCurrent >= MacOSVer2Int("10.10") && MacOSVerCurrent < MacOSVer2Int("10.11") ) + { + // Yosemite prelink kernel cache file + // for 10.10 and 10.11 + if (isOSXUpgrade) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", "/OS X Install Data/"); + } + else if (isInstaller) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCacheInstallerNew); + } + else if (isRecoveryHD) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%skernelcache", kDefaultCacheRecoveryHD); + } + else + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%sprelinkedkernel", kDefaultCachePathYosemite); + } + + verbose("Kernel Cache file path (OS X 10.10): %s\n", kernelCacheFile); + } + else if ( MacOSVerCurrent >= MacOSVer2Int("10.11") ) + { + // El Capitan on prelinked kernel cache file + // for 10.10 and 10.11 + if (isOSXUpgrade) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%sprelinkedkernel", "/OS X Install Data/"); + } + else if (isInstaller) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%sprelinkedkernel", kDefaultCacheInstallerNew); + } + else if (isRecoveryHD) + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%sprelinkedkernel", kDefaultCacheRecoveryHD); + } + else + { + snprintf(kernelCacheFile, sizeof(kernelCacheFile), "%sprelinkedkernel", kDefaultCachePathYosemite); + } + + verbose("Kernel Cache file path (OS X 10.11 and newer): %s\n", kernelCacheFile); + } } // Check if the kernel cache file exists @@ -353,22 +446,76 @@ if (gBootVolume->flags & kBVFlagBooter) { - snprintf(kernelCachePath, sizeof(kernelCachePath), "/com.apple.boot.P/%s", kernelCacheFile); - ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); + if (isRecoveryHD) + { + strncpy(kernelCachePath, "/com.apple.recovery.boot/prelinkedkernel", sizeof(kernelCachePath) ); + ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); - if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) + if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) + { + strncpy(kernelCachePath, "/com.apple.recovery.boot/kernelcache", sizeof(kernelCachePath) ); + ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); + + if ((flags & kFileTypeMask) != kFileTypeFlat) + { + ret = -1; + } + } + } + else if (isInstaller) { - snprintf(kernelCachePath, sizeof(kernelCachePath), "/com.apple.boot.R/%s", kernelCacheFile); + strncpy(kernelCachePath, "/.IABootFiles/prelinkedkernel", sizeof(kernelCachePath) ); ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) { - snprintf(kernelCachePath, sizeof(kernelCachePath), "/com.apple.boot.S/%s", kernelCacheFile); + strncpy(kernelCachePath, "/.IABootFiles/kernelcache", sizeof(kernelCachePath) ); ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); + if ((flags & kFileTypeMask) != kFileTypeFlat) + { + ret = -1; + } + } + } + else if (isMacOSXUpgrade) + { + strncpy(kernelCachePath, "/Mac OS X Install Data/kernelcache", sizeof(kernelCachePath) ); + ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); + + if ((flags & kFileTypeMask) != kFileTypeFlat) + { + ret = -1; + } + } + else if (isOSXUpgrade) + { + strncpy(kernelCachePath, "/OS X Install Data/prelinkedkernel", sizeof(kernelCachePath) ); + ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); + + if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) + { + strncpy(kernelCachePath, "/OS X Install Data/kernelcache", sizeof(kernelCachePath) ); + ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); + + if ((flags & kFileTypeMask) != kFileTypeFlat) + { + ret = -1; + } + } + } + else + { + snprintf(kernelCachePath, sizeof(kernelCachePath), "/com.apple.boot.P/%s", kernelCacheFile); + ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); + if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) + { + snprintf(kernelCachePath, sizeof(kernelCachePath), "/com.apple.boot.R/%s", kernelCacheFile); + ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); + if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) { - strncpy(kernelCachePath, "/com.apple.recovery.boot/kernelcache", sizeof(kernelCachePath) ); + snprintf(kernelCachePath, sizeof(kernelCachePath), "/com.apple.boot.S/%s", kernelCacheFile); ret = GetFileInfo(NULL, kernelCachePath, &flags, &cachetime); if ((flags & kFileTypeMask) != kFileTypeFlat) @@ -399,24 +546,27 @@ return -1; } - // Check if the kernel cache file is more recent (mtime) - // than the kernel file or the S/L/E directory - ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime); - - // Check if the kernel file is more recent than the cache file - if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat) && (kerneltime > cachetime)) + if ( !isInstaller && !isRecoveryHD && !isMacOSXUpgrade && !isOSXUpgrade ) { - DBG("Kernel file '%s' is more recent than Kernel Cache '%s'! Ignoring Kernel Cache.\n", bootInfo->bootFile, kernelCacheFile); - return -1; - } + // Check if the kernel cache file is more recent (mtime) + // than the kernel file or the S/L/E directory + ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime); - ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime); + // Check if the kernel file is more recent than the cache file + if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat) && (kerneltime > cachetime)) + { + DBG("Kernel file '%s' is more recent than Kernel Cache '%s'! Ignoring Kernel Cache.\n", bootInfo->bootFile, kernelCacheFile); + return -1; + } - // Check if the S/L/E directory time is more recent than the cache file - if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory) && (exttime > cachetime)) - { - DBG("Folder '/System/Library/Extensions' is more recent than Kernel Cache file '%s'! Ignoring Kernel Cache.\n", kernelCacheFile); - return -1; + ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime); + + // Check if the S/L/E directory time is more recent than the cache file + if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory) && (exttime > cachetime)) + { + DBG("Folder '/System/Library/Extensions' is more recent than Kernel Cache file '%s'! Ignoring Kernel Cache.\n", kernelCacheFile); + return -1; + } } // Since the kernel cache file exists and is the most recent try to load it @@ -675,61 +825,88 @@ // Notify modules that we are attempting to boot execute_hook("PreBoot", NULL, NULL, NULL, NULL); - if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig)) + if (gBootVolume->OSisInstaller) { - tryresume = true; - tryresumedefault = true; + isInstaller = true; } - else + + if (gBootVolume->OSisMacOSXUpgrade) { - tryresumedefault = false; + isMacOSXUpgrade = true; } - if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->chameleonConfig)) + if (gBootVolume->OSisOSXUpgrade) { - forceresume = false; + isOSXUpgrade = true; } - if (forceresume) + if (gBootVolume->OSisRecovery) { - tryresume = true; - tryresumedefault = false; + isRecoveryHD = true; } - while (tryresume) + if ( !isRecoveryHD && !isInstaller && !isMacOSXUpgrade && !isOSXUpgrade ) { - const char *tmp; - BVRef bvr; - if (!getValueForKey(kWakeImage, &val, &len, &bootInfo->chameleonConfig)) - val = "/private/var/vm/sleepimage"; + if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig)) + { + tryresume = true; + tryresumedefault = true; + } + else + { + tryresumedefault = false; + } - // Do this first to be sure that root volume is mounted - ret = GetFileInfo(0, val, &flags, &sleeptime); + if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->chameleonConfig)) + { + forceresume = false; + } - if ((bvr = getBootVolumeRef(val, &tmp)) == NULL) - break; + if (forceresume) + { + tryresume = true; + tryresumedefault = false; + } - // Can't check if it was hibernation Wake=y is required - if (bvr->modTime == 0 && tryresumedefault) - break; + while (tryresume) + { + const char *tmp; + BVRef bvr; + if (!getValueForKey(kWakeImage, &val, &len, &bootInfo->chameleonConfig)) + val = "/private/var/vm/sleepimage"; - if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) - break; + // Do this first to be sure that root volume is mounted + ret = GetFileInfo(0, val, &flags, &sleeptime); - if (!forceresume && ((sleeptime+3)modTime)) - { + if ((bvr = getBootVolumeRef(val, &tmp)) == NULL) + break; + + // Can't check if it was hibernation Wake=y is required + if (bvr->modTime == 0 && tryresumedefault) + break; + + if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) + break; + + if (!forceresume && ((sleeptime+3)modTime)) + { #if DEBUG - printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n", - bvr->modTime-sleeptime); + printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n", + bvr->modTime-sleeptime); #endif + break; + } + + HibernateBoot((char *)val); break; } + } - HibernateBoot((char *)val); - break; + if (!isRecoveryHD && !isInstaller && !isMacOSXUpgrade && !isOSXUpgrade ) + { + getBoolForKey(kUseKernelCache, &useKernelCache, &bootInfo->chameleonConfig); } - getBoolForKey(kUseKernelCache, &useKernelCache, &bootInfo->chameleonConfig); if (useKernelCache) { do @@ -945,23 +1122,22 @@ verbose("\n"); int csrValue; -#if 0 /* * A special BootArgs flag "kBootArgsFlagCSRBoot" * is set in the Recovery or Installation environment. * This flag is kind of overkill by turning off all the protections */ - if (isRecoveryHD) + if (isRecoveryHD || isInstaller || isOSXUpgrade || isMacOSXUpgrade) { // SIP can be controlled with or without FileNVRAM.kext (Pike R. Alpha) bootArgs->flags |= (kBootArgsFlagCSRActiveConfig + kBootArgsFlagCSRConfigMode + kBootArgsFlagCSRBoot); } -#endif + else + { + bootArgs->flags |= kBootArgsFlagCSRActiveConfig; + } - bootArgs->flags |= kBootArgsFlagCSRActiveConfig; - - // Set limit to 7bit if ( getIntForKey(kCsrActiveConfig, &csrValue, &bootInfo->chameleonConfig) && (csrValue >= 0 && csrValue <= 127) ) { Index: branches/ErmaC/Enoch/i386/boot2/boot.h =================================================================== --- branches/ErmaC/Enoch/i386/boot2/boot.h (revision 2836) +++ branches/ErmaC/Enoch/i386/boot2/boot.h (revision 2837) @@ -48,15 +48,17 @@ #define kDefaultCachePathLeo "/System/Library/Caches/com.apple.kernelcaches/" #define kDefaultCachePathSnow "/System/Library/Caches/com.apple.kext.caches/Startup/" #define kDefaultCachePathYosemite "/System/Library/PrelinkedKernels/" +#define kDefaultCacheRecoveryHD "/com.apple.recovery.boot/" -// Lion installer +// Lion installer ?? #define kLionInstallerDataFolder "/Mac OS X Install Data/" -#define kLionInstallerPlist kLionInstallerDataFolder "com.apple.Boot.plist" -// Mountain Lion installer +// Mountain Lion installer ?? #define kMLionInstallerDataFolder "/OS X Install Data/" -#define kMLionInstallerPlist kMLionInstallerDataFolder "com.apple.Boot.plist" +// Installer new +#define kDefaultCacheInstallerNew "/.IABootFiles/" + //kernel path #define kDefaultKernelPathPreYos "/" #define kDefaultKernelPathForYos "/System/Library/Kernels/" //for Yosemite and El Capitan @@ -209,7 +211,11 @@ #define kDropMCFG "DropMCFG" /* acpi_patcher.c */ #define kDropAPIC "DropAPIC" /* acpi_patcher.c */ #define kCsrActiveConfig "CsrActiveConfig" /* boot.c */ +#define kProductBuildVersion "ProductBuildVersion" /* boot.c */ +uint32_t kernelOSVer; /* boot.c */ + + /* Pike R. Alpha: added this key */ #define kBlackMode "BlackMode" @@ -309,6 +315,12 @@ // Bungo: extern char gDarwinBuildVerStr[256]; +// Micky1979 +int gDarwinMajor; +int gDarwinMinor; +int gDarwinRev; +bool useDarwinVersion; + /*! Hookable function pointer called during the driver loading phase that allows other code to cause additional drivers to be loaded. Index: branches/ErmaC/Enoch/i386/boot2/options.c =================================================================== --- branches/ErmaC/Enoch/i386/boot2/options.c (revision 2836) +++ branches/ErmaC/Enoch/i386/boot2/options.c (revision 2837) @@ -1394,6 +1394,62 @@ addBootArg("kext-dev-mode=1"); } + // Micky1979 (Recovery HD) + if (gBootVolume->OSisRecovery) + { + const char *rval = 0; + config_file_t ocBplist; + char caBp[1024]; //too large ?. On El capitan is 365 bytes.. but we are testing + snprintf(caBp, sizeof(caBp), "/com.apple.recovery.boot/com.apple.Boot.plist"); + + loadConfigFile(caBp, &ocBplist); + rval = getStringForKey(kKernelFlagsKey, &ocBplist); + addBootArg(rval); + } + + // Micky1979 (Vanilla Installer) + if (gBootVolume->OSisInstaller) + { + const char *rval = 0; + config_file_t ocBplist; + + char caBp[2048]; + + snprintf(caBp, sizeof(caBp), "/.IABootFiles/com.apple.Boot.plist"); + + loadConfigFile(caBp, &ocBplist); + rval = getStringForKey(kKernelFlagsKey, &ocBplist); + addBootArg(rval); + } + + // Micky1979 (old Vanilla upgrade) + if (gBootVolume->OSisMacOSXUpgrade) + { + const char *rval = 0; + config_file_t ocBplist; + char caBp[2048]; + + snprintf(caBp, sizeof(caBp), "/Mac OS X Install Data/com.apple.Boot.plist"); + + loadConfigFile(caBp, &ocBplist); + rval = getStringForKey(kKernelFlagsKey, &ocBplist); + addBootArg(rval); + } + + // Micky1979 (new Vanilla upgrade) + if (gBootVolume->OSisMacOSXUpgrade) + { + const char *rval = 0; + config_file_t ocBplist; + char caBp[2048]; + + snprintf(caBp, sizeof(caBp), "/OS X Install Data/com.apple.Boot.plist"); + + loadConfigFile(caBp, &ocBplist); + rval = getStringForKey(kKernelFlagsKey, &ocBplist); + addBootArg(rval); + } + cntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space argP = bootArgs->CommandLine; Index: branches/ErmaC/Enoch/i386/libsa/libsa.h =================================================================== --- branches/ErmaC/Enoch/i386/libsa/libsa.h (revision 2836) +++ branches/ErmaC/Enoch/i386/libsa/libsa.h (revision 2837) @@ -108,6 +108,10 @@ extern char *strncat(char * s1, const char * s2, size_t n); extern char *strdup(const char *s1); +extern char *strpbrk_c(const char *s, const char *accept); +extern char *strsep_c(char **stringp, const char *delim); +extern size_t __strxspn_c(const char *s, const char *map, int parity); + #if STRNCASECMP extern int strncasecmp(const char *s1, const char *s2, size_t n); #endif Index: branches/ErmaC/Enoch/i386/libsa/string.c =================================================================== --- branches/ErmaC/Enoch/i386/libsa/string.c (revision 2836) +++ branches/ErmaC/Enoch/i386/libsa/string.c (revision 2837) @@ -432,3 +432,54 @@ return csum; } +/* + bsd functions variants (already available in klibc) + strsep, strpbrk and __strxspn + */ +#ifndef UCHAR_MAX + #define UCHAR_MAX 255u +#endif +//========================================================================== +char *strsep_c(char **stringp, const char *delim) +{ + char *s = *stringp; + char *e; + + if (!s) + return NULL; + + e = strpbrk_c(s, delim); + if (e) + *e++ = '\0'; + + *stringp = e; + return s; +} +//========================================================================== +char *strpbrk_c(const char *s, const char *accept) +{ + const char *ss = s + __strxspn_c(s, accept, 1); + + return *ss ? (char *)ss : NULL; +} +//========================================================================== +size_t __strxspn_c(const char *s, const char *map, int parity) +{ + char matchmap[UCHAR_MAX + 1]; + size_t n = 0; + + /* Create bitmap */ + memset(matchmap, 0, sizeof matchmap); + while (*map) + matchmap[(unsigned char)*map++] = 1; + + /* Make sure the null character never matches */ + matchmap[0] = parity; + + /* Calculate span length */ + while (matchmap[(unsigned char)*s++] ^ parity) + n++; + + return n; +} +//==========================================================================