void HibernateBoot(char *image_filename) { long long size, imageSize, codeSize, allocSize; long mem_base; IOHibernateImageHeader _header; IOHibernateImageHeader * header = &_header; long buffer; size = ReadFileAtOffset (image_filename, header, 0, sizeof(IOHibernateImageHeader)); printf("header read size %x\n", size); imageSize = header->image1Size; codeSize = header->restore1PageCount << 12; if (kIOHibernateHeaderSignature != header->signature) { printf ("Incorrect image signature\n"); return; } if (header->encryptStart) { printf ("Resuming from Encrypted image is unsupported.\n" "Uncheck \"Use secure virtual memory\" in \"Security\" pane on system preferences.\n" "Press any key to proceed with normal boot.\n"); getc (); return; } // depends on NVRAM #if 0 { uint32_t machineSignature; size = GetProp(gChosenPH, kIOHibernateMachineSignatureKey, (char *)&machineSignature, sizeof(machineSignature)); if (size != sizeof(machineSignature)) machineSignature = 0; if (machineSignature != header->machineSignature) break; } #endif allocSize = imageSize + ((4095 + sizeof(hibernate_graphics_t)) & ~4095); mem_base = getmemorylimit() - allocSize;//TODO: lower this printf("mem_base %x\n", mem_base); if (!((long long)mem_base+allocSize<1024*bootInfo->extmem+0x100000)) { printf ("Not enough space to restore image. Press any key to proceed with normal boot.\n"); getc (); return; } bcopy(header, (void *) mem_base, sizeof(IOHibernateImageHeader)); header = (IOHibernateImageHeader *) mem_base; imageSize -= sizeof(IOHibernateImageHeader); buffer = (long)(header + 1); if (header->previewSize) { uint64_t preview_offset = header->fileExtentMapSize - sizeof(header->fileExtentMap) + codeSize; uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize]; ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader), preview_offset+header->previewSize); drawPreview ((void *)(long)(buffer+preview_offset + header->previewPageListSize), &(progressSaveUnder[0][0])); previewTotalSectors = (imageSize-(preview_offset+header->previewSize))/512; previewLoadedSectors = 0; previewSaveunder = &(progressSaveUnder[0][0]); if (preview_offset+header->previewSize<imageSize) ReadFileAtOffset (image_filename, (char *)(long)(buffer+preview_offset+header->previewSize), sizeof(IOHibernateImageHeader)+preview_offset+header->previewSize, imageSize-(preview_offset+header->previewSize)); previewTotalSectors = 0; previewLoadedSectors = 0; previewSaveunder = 0; #if 0 AsereBLN: check_vga_nvidia() didn't work as expected (recursion level > 0 & return value). Unforutnaltely I cannot find a note why to switch back to text mode for nVidia cards only and because it check_vga_nvidia does not work (cards normally are behind a bridge) I will remove it completely setVideoMode( VGA_TEXT_MODE, 0 ); #endif }
void HibernateBoot(char *image_filename) { long long size, imageSize, codeSize, allocSize; long mem_base; IOHibernateImageHeader _header; IOHibernateImageHeader * header = &_header; long buffer; size = ReadFileAtOffset (image_filename, header, 0, sizeof(IOHibernateImageHeader)); printf("header read size %x\n", size); imageSize = header->image1Size; codeSize = header->restore1PageCount << 12; if (kIOHibernateHeaderSignature != header->signature) { printf ("Incorrect image signature\n"); return; } if (header->encryptStart) { printf ("Resuming from Encrypted image is unsupported.\n" "Uncheck \"Use secure virtual memory\" in \"Security\" pane on system preferences.\n" "Press any key to proceed with normal boot.\n"); getc (); return; } // depends on NVRAM #if 0 { uint32_t machineSignature; size = GetProp(gChosenPH, kIOHibernateMachineSignatureKey, (char *)&machineSignature, sizeof(machineSignature)); if (size != sizeof(machineSignature)) machineSignature = 0; if (machineSignature != header->machineSignature) break; } #endif allocSize = imageSize + ((4095 + sizeof(hibernate_graphics_t)) & ~4095); mem_base = getmemorylimit() - allocSize;//TODO: lower this printf("mem_base %x\n", mem_base); if (!(long long)mem_base+allocSize<1024*bootInfo->extmem+0x100000) { printf ("Not enough space to restore image. Press any key to proceed with normal boot.\n"); getc (); return; } bcopy(header, (void *) mem_base, sizeof(IOHibernateImageHeader)); header = (IOHibernateImageHeader *) mem_base; imageSize -= sizeof(IOHibernateImageHeader); buffer = (long)(header + 1); if (header->previewSize) { uint64_t preview_offset = header->fileExtentMapSize - sizeof(header->fileExtentMap) + codeSize; uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize]; ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader), preview_offset+header->previewSize); drawPreview ((void *)(long)(buffer+preview_offset + header->previewPageListSize), &(progressSaveUnder[0][0])); previewTotalSectors = (imageSize-(preview_offset+header->previewSize))/512; previewLoadedSectors = 0; previewSaveunder = &(progressSaveUnder[0][0]); if (preview_offset+header->previewSize<imageSize) ReadFileAtOffset (image_filename, (char *)(long)(buffer+preview_offset+header->previewSize), sizeof(IOHibernateImageHeader)+preview_offset+header->previewSize, imageSize-(preview_offset+header->previewSize)); previewTotalSectors = 0; previewLoadedSectors = 0; previewSaveunder = 0; if(check_vga_nvidia(root_pci_dev) ==1 ) setVideoMode( VGA_TEXT_MODE, 0 ); } else ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader), imageSize); // Depends on NVRAM #if 0 if (header->encryptStart) { // decryption data static const unsigned char first_iv[AES_BLOCK_SIZE] = { 0xa3, 0x63, 0x65, 0xa9, 0x0b, 0x71, 0x7b, 0x1c, 0xdf, 0x9e, 0x5f, 0x32, 0xd7, 0x61, 0x63, 0xda }; hibernate_cryptvars_t _cryptvars; hibernate_cryptvars_t * cryptvars = &_cryptvars; aes_decrypt_key(&decryptkey, decryptkeysize, &cryptvars->ctx.decrypt); // set the vector for the following decryptions bcopy(((uint8_t *) header) + header->image1Size - AES_BLOCK_SIZE, &cryptvars->aes_iv[0], AES_BLOCK_SIZE); // decrypt the buffer uint32_t len = (uint32_t)(header->image1Size - header->encryptStart); aes_decrypt_cbc(((uint8_t *) header) + header->encryptStart, &first_iv[0], len >> 4, ((uint8_t *) header) + header->encryptStart, &cryptvars->ctx.decrypt); bzero(&cryptvars->aes_iv[0], sizeof(cryptvars)); bzero(&decryptkey, sizeof(decryptkey)); } #endif WakeKernel(header); }