- vars->srcBuffer = IOBufferMemoryDescriptor::withOptions(kIODirectionOutIn,
- 4 * page_size, page_size);
- vars->ioBuffer = IOBufferMemoryDescriptor::withOptions(kIODirectionOutIn,
- 2 * kDefaultIOSize, page_size);
-
- if (!vars->srcBuffer || !vars->ioBuffer)
- {
- err = kIOReturnNoMemory;
- break;
- }
-
- err = IOPolledFileOpen(gIOHibernateFilename, vars->ioBuffer,
- &vars->fileVars, &vars->fileExtents, &data);
- if (KERN_SUCCESS != err)
- {
- HIBLOG("IOPolledFileOpen(%x)\n", err);
- break;
- }
- if (vars->fileVars->fileRef)
- {
- // invalidate the image file
- gIOHibernateCurrentHeader->signature = kIOHibernateHeaderInvalidSignature;
- int err = kern_write_file(vars->fileVars->fileRef, 0,
- (caddr_t) gIOHibernateCurrentHeader, sizeof(IOHibernateImageHeader));
- if (KERN_SUCCESS != err)
- HIBLOG("kern_write_file(%d)\n", err);
- }
-
- bzero(gIOHibernateCurrentHeader, sizeof(IOHibernateImageHeader));
- gIOHibernateCurrentHeader->debugFlags = gIOHibernateDebugFlags;
-
- boolean_t encryptedswap;
- err = hibernate_setup(gIOHibernateCurrentHeader,
- gIOHibernateFreeRatio, gIOHibernateFreeTime,
- &vars->page_list, &vars->page_list_wired, &encryptedswap);
- if (KERN_SUCCESS != err)
- {
- HIBLOG("hibernate_setup(%d)\n", err);
- break;
- }
-
- if (encryptedswap)
- gIOHibernateMode ^= kIOHibernateModeEncrypt;
-
- vars->videoAllocSize = kVideoMapSize;
- if (KERN_SUCCESS != kmem_alloc_pageable(kernel_map, &vars->videoMapping, vars->videoAllocSize))
- vars->videoMapping = 0;
-
- // generate crypt keys
- for (uint32_t i = 0; i < sizeof(vars->wiredCryptKey); i++)
- vars->wiredCryptKey[i] = random();
- for (uint32_t i = 0; i < sizeof(vars->cryptKey); i++)
- vars->cryptKey[i] = random();
-
- // set nvram
-
- IORegistryEntry * regEntry;
- if (!gIOOptionsEntry)
- {
- regEntry = IORegistryEntry::fromPath("/options", gIODTPlane);
- gIOOptionsEntry = OSDynamicCast(IODTNVRAM, regEntry);
- if (regEntry && !gIOOptionsEntry)
- regEntry->release();
- }
- if (!gIOChosenEntry)
- gIOChosenEntry = IORegistryEntry::fromPath("/chosen", gIODTPlane);
-
- if (gIOOptionsEntry)
- {
- const OSSymbol * sym;
-
- sym = OSSymbol::withCStringNoCopy(kIOHibernateBootImageKey);
- if (sym)
- {
- gIOOptionsEntry->setProperty(sym, data);
- sym->release();
- }
- data->release();
-
-#if defined(__ppc__)
- size_t len;
- char valueString[16];
-
- vars->saveBootDevice = gIOOptionsEntry->copyProperty(kIOSelectedBootDeviceKey);
- if (gIOChosenEntry)
- {
- OSData * bootDevice = OSDynamicCast(OSData, gIOChosenEntry->getProperty(kIOBootPathKey));
- if (bootDevice)
- {
- sym = OSSymbol::withCStringNoCopy(kIOSelectedBootDeviceKey);
- OSString * str2 = OSString::withCStringNoCopy((const char *) bootDevice->getBytesNoCopy());
- if (sym && str2)
- gIOOptionsEntry->setProperty(sym, str2);
- if (sym)
- sym->release();
- if (str2)
- str2->release();
- }
- data = OSDynamicCast(OSData, gIOChosenEntry->getProperty(kIOHibernateMemorySignatureKey));
- if (data)
- {
- vars->haveFastBoot = true;
-
- len = snprintf(valueString, sizeof(valueString), "0x%lx", *((UInt32 *)data->getBytesNoCopy()));
- data = OSData::withBytes(valueString, len + 1);
- sym = OSSymbol::withCStringNoCopy(kIOHibernateMemorySignatureEnvKey);
- if (sym && data)
- gIOOptionsEntry->setProperty(sym, data);
- if (sym)
- sym->release();
- if (data)
- data->release();
- }
- data = OSDynamicCast(OSData, gIOChosenEntry->getProperty(kIOHibernateMachineSignatureKey));
- if (data)
- gIOHibernateCurrentHeader->machineSignature = *((UInt32 *)data->getBytesNoCopy());
- }
-#endif /* __ppc__ */
-#if defined(__i386__) || defined(__x86_64__)
- struct AppleRTCHibernateVars
- {
- uint8_t signature[4];
- uint32_t revision;
- uint8_t booterSignature[20];
- uint8_t wiredCryptKey[16];
- };
- AppleRTCHibernateVars rtcVars;
-
- rtcVars.signature[0] = 'A';
- rtcVars.signature[1] = 'A';
- rtcVars.signature[2] = 'P';
- rtcVars.signature[3] = 'L';
- rtcVars.revision = 1;
- bcopy(&vars->wiredCryptKey[0], &rtcVars.wiredCryptKey[0], sizeof(rtcVars.wiredCryptKey));
- if (gIOHibernateBootSignature[0])
- {
- char c;
- uint8_t value = 0;
- for (uint32_t i = 0;
- (c = gIOHibernateBootSignature[i]) && (i < (sizeof(rtcVars.booterSignature) << 1));
- i++)
- {
- if (c >= 'a')
- c -= 'a' - 10;
- else if (c >= 'A')
- c -= 'A' - 10;
- else if (c >= '0')
- c -= '0';
- else
- continue;
- value = (value << 4) | c;
- if (i & 1)
- rtcVars.booterSignature[i >> 1] = value;
- }
- }
- data = OSData::withBytes(&rtcVars, sizeof(rtcVars));
- if (data)
- {
- IOService::getPMRootDomain()->setProperty(kIOHibernateRTCVariablesKey, data);
-
- if( gIOOptionsEntry )
- {
- if( gIOHibernateMode & kIOHibernateModeSwitch )
- {
- const OSSymbol *sym;
- sym = OSSymbol::withCStringNoCopy(kIOHibernateBootSwitchVarsKey);
- if( sym )
- {
- gIOOptionsEntry->setProperty(sym, data); /* intentional insecure backup of rtc boot vars */
- sym->release();
- }
- }
- }
-
- data->release();
- }
- if (gIOChosenEntry)
- {
- data = OSDynamicCast(OSData, gIOChosenEntry->getProperty(kIOHibernateMachineSignatureKey));
- if (data)
- gIOHibernateCurrentHeader->machineSignature = *((UInt32 *)data->getBytesNoCopy());