1 | Index: /Users/mr_w/Workspace/chameleon/i386/boot2/resume.c␊ |
2 | ===================================================================␊ |
3 | --- /Users/mr_w/Workspace/chameleon/i386/boot2/resume.c␉(revision 1227)␊ |
4 | +++ /Users/mr_w/Workspace/chameleon/i386/boot2/resume.c␉(working copy)␊ |
5 | @@ -14,6 +14,7 @@␊ |
6 | #include "bootstruct.h"␊ |
7 | #include "boot.h"␊ |
8 | #include "pci.h"␊ |
9 | +#include "bootargs.h"␊ |
10 | ␊ |
11 | extern int previewTotalSectors;␊ |
12 | extern int previewLoadedSectors;␊ |
13 | @@ -39,6 +40,11 @@␊ |
14 | return 0x10000000;␊ |
15 | }␊ |
16 | ␊ |
17 | +static bool checkOSVersion(const char * version) ␊ |
18 | +{␊ |
19 | +␉return ((gMacOSVersion[0] == version[0]) && (gMacOSVersion[1] == version[1]) && (gMacOSVersion[2] == version[2]) && (gMacOSVersion[3] == version[3]));␊ |
20 | +}␊ |
21 | +␊ |
22 | static void WakeKernel(IOHibernateImageHeader * header)␊ |
23 | {␊ |
24 | ␉uint32_t proc;␊ |
25 | @@ -96,6 +102,176 @@␊ |
26 | ␉return;␊ |
27 | }␊ |
28 | ␊ |
29 | +static void WakeKernel107(IOHibernateImageHeader107 * header)␊ |
30 | +{␊ |
31 | +␉uint32_t proc;␊ |
32 | +␉unsigned long cnt, newSP;␊ |
33 | +␉unsigned long *src, *dst;␊ |
34 | +␉unsigned int ␉count;␊ |
35 | +␉unsigned int ␉page;␊ |
36 | +␉unsigned int ␉compressedSize;␊ |
37 | +␉int32_t ␉byteCnt;␊ |
38 | +␉u_int32_t ␉lowHalf, highHalf;␊ |
39 | +␉u_int32_t ␉sum;␊ |
40 | +␉␊ |
41 | +␉printf("\nWake Kernel!\n");␊ |
42 | +␉␊ |
43 | +␉dst = (unsigned long *) (header->restore1CodePhysPage << 12);␊ |
44 | +␉count = header->restore1PageCount;␊ |
45 | +␉proc = (header->restore1CodeOffset + ((uint32_t) dst));␊ |
46 | +␉newSP = header->restore1StackOffset + (header->restore1CodePhysPage << 12);␊ |
47 | +␉␊ |
48 | +␉src = (unsigned long *) (((u_int32_t) &header->fileExtentMap[0]) ␊ |
49 | +␉␉␉␉␉␉␉ + header->fileExtentMapSize);␊ |
50 | +␉sum = 0;␊ |
51 | +␉␊ |
52 | +␉for (page = 0; page < count; page++)␊ |
53 | +␉{␊ |
54 | +␉␉compressedSize = 4096;␊ |
55 | +␉␉␊ |
56 | +␉␉lowHalf = 1;␊ |
57 | +␉␉highHalf = 0;␊ |
58 | +␉␉␊ |
59 | +␉␉for (cnt = 0; cnt < compressedSize; cnt += 0x20) {␊ |
60 | +␉␉␉dst[0] = src[0];␊ |
61 | +␉␉␉dst[1] = src[1];␊ |
62 | +␉␉␉dst[2] = src[2];␊ |
63 | +␉␉␉dst[3] = src[3];␊ |
64 | +␉␉␉dst[4] = src[4];␊ |
65 | +␉␉␉dst[5] = src[5];␊ |
66 | +␉␉␉dst[6] = src[6];␊ |
67 | +␉␉␉dst[7] = src[7];␊ |
68 | +␉␉␉for (byteCnt = 0; byteCnt < 0x20; byteCnt++) {␊ |
69 | +␉␉␉␉lowHalf += ((u_int8_t *) dst)[byteCnt];␊ |
70 | +␉␉␉␉highHalf += lowHalf;␊ |
71 | +␉␉␉}␊ |
72 | +␉␉␉src += 8;␊ |
73 | +␉␉␉dst += 8;␊ |
74 | +␉␉}␊ |
75 | +␉␉␊ |
76 | +␉␉lowHalf %= 65521L;␊ |
77 | +␉␉highHalf %= 65521L;␊ |
78 | +␉␉sum += (highHalf << 16) | lowHalf;␊ |
79 | +␉}␊ |
80 | +␉header->actualRestore1Sum = sum;␊ |
81 | +␉startprog (proc, header);␊ |
82 | +␉␊ |
83 | +␉return;␊ |
84 | +}␊ |
85 | +␊ |
86 | +static void HibernateBoot107(char *image_filename)␊ |
87 | +{␊ |
88 | +␉long long size, imageSize, codeSize, allocSize;␊ |
89 | +␉long mem_base;␊ |
90 | +␉IOHibernateImageHeader107 _header;␊ |
91 | +␉IOHibernateImageHeader107 * header = &_header;␊ |
92 | +␉long buffer;␊ |
93 | +␉␊ |
94 | +␉size = ReadFileAtOffset (image_filename, header, 0, sizeof(IOHibernateImageHeader107));␊ |
95 | +␉printf("header read size %x\n", size);␊ |
96 | +␉␊ |
97 | +␉imageSize = header->image1Size;␊ |
98 | +␉codeSize = header->restore1PageCount << 12;␊ |
99 | +␉if (kIOHibernateHeaderSignature != header->signature)␊ |
100 | +␉{␊ |
101 | +␉␉printf ("Incorrect image signature, expected version 10.7\n");␊ |
102 | +␉␉getchar();␊ |
103 | +␉␉return;␊ |
104 | +␉}␊ |
105 | +␉if (header->encryptStart)␊ |
106 | +␉{␊ |
107 | +␉␉printf ("Resuming from Encrypted image is unsupported.\n"␊ |
108 | +␉␉␉␉"Uncheck \"Use secure virtual memory\" in \"Security\" pane on system preferences.\n"␊ |
109 | +␉␉␉␉"Press any key to proceed with normal boot.\n");␊ |
110 | +␉␉getchar();␊ |
111 | +␉␉return;␊ |
112 | +␉}␊ |
113 | +// depends on NVRAM␊ |
114 | +#if 0␊ |
115 | +␉{␊ |
116 | +␉␉uint32_t machineSignature;␊ |
117 | +␉␉size = GetProp(gChosenPH, kIOHibernateMachineSignatureKey,␊ |
118 | +␉␉␉␉␉ (char *)&machineSignature, sizeof(machineSignature));␊ |
119 | +␉␉if (size != sizeof(machineSignature)) machineSignature = 0;␊ |
120 | +␉␉if (machineSignature != header->machineSignature)␊ |
121 | +␉␉␉break;␊ |
122 | +␉}␊ |
123 | +#endif␊ |
124 | +␉␊ |
125 | +␉allocSize = imageSize + ((4095 + sizeof(hibernate_graphics_t)) & ~4095);␊ |
126 | +␉␊ |
127 | +␉mem_base = getmemorylimit() - allocSize;//TODO: lower this␊ |
128 | +␉␊ |
129 | +␉printf("mem_base %x\n", mem_base);␊ |
130 | +␉␊ |
131 | +␉bcopy(header, (void *) mem_base, sizeof(IOHibernateImageHeader107));␊ |
132 | +␉header = (IOHibernateImageHeader107 *) mem_base;␊ |
133 | +␉␊ |
134 | +␉imageSize -= sizeof(IOHibernateImageHeader107);␊ |
135 | +␉buffer = (long)(header + 1);␊ |
136 | +␉␊ |
137 | +␉if (header->previewSize)␊ |
138 | +␉{␊ |
139 | +␉␉uint64_t preview_offset = header->fileExtentMapSize - sizeof(header->fileExtentMap) + codeSize;␊ |
140 | +␉␉uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize];␊ |
141 | +␉␉␊ |
142 | +␉␉ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader107), preview_offset+header->previewSize);␊ |
143 | +␉␉drawPreview ((void *)(long)(buffer+preview_offset + header->previewPageListSize), &(progressSaveUnder[0][0]));␊ |
144 | +␉␉previewTotalSectors = (imageSize-(preview_offset+header->previewSize))/512;␊ |
145 | +␉␉previewLoadedSectors = 0;␊ |
146 | +␉␉previewSaveunder = &(progressSaveUnder[0][0]);␊ |
147 | +␉␉if (preview_offset+header->previewSize<imageSize)␊ |
148 | +␉␉␉ReadFileAtOffset (image_filename, (char *)(long)(buffer+preview_offset+header->previewSize),␊ |
149 | +␉␉␉␉␉␉␉ sizeof(IOHibernateImageHeader107)+preview_offset+header->previewSize,␊ |
150 | +␉␉␉␉␉␉␉ imageSize-(preview_offset+header->previewSize));␊ |
151 | +␉␉previewTotalSectors = 0;␊ |
152 | +␉␉previewLoadedSectors = 0;␊ |
153 | +␉␉previewSaveunder = 0;␊ |
154 | +#if 0␊ |
155 | +␉␉/* AsereBLN:␊ |
156 | +␉␉check_vga_nvidia() didn't work as expected (recursion level > 0 & return value).␊ |
157 | +␉␉Unforutnaltely I cannot find a note why to switch back to text mode for nVidia cards only␊ |
158 | +␉␉and because it check_vga_nvidia does not work (cards normally are behind a bridge) I will␊ |
159 | +␉␉remove it completely */␊ |
160 | +␉␉setVideoMode( VGA_TEXT_MODE, 0 );␊ |
161 | +#endif␊ |
162 | +␉}␊ |
163 | +␉else␊ |
164 | +␉␉ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader107), imageSize);␊ |
165 | +␉␊ |
166 | +// Depends on NVRAM␊ |
167 | +#if 0␊ |
168 | +␉if (header->encryptStart) {␊ |
169 | +␉␉// decryption data␊ |
170 | +␉␉static const unsigned char first_iv[AES_BLOCK_SIZE]␊ |
171 | +␉␉= { 0xa3, 0x63, 0x65, 0xa9, 0x0b, 0x71, 0x7b, 0x1c,␊ |
172 | +␉␉0xdf, 0x9e, 0x5f, 0x32, 0xd7, 0x61, 0x63, 0xda };␊ |
173 | +␉␉hibernate_cryptvars_t _cryptvars;␊ |
174 | +␉␉hibernate_cryptvars_t * cryptvars = &_cryptvars;␊ |
175 | +␉␉␊ |
176 | +␉␉aes_decrypt_key(&decryptkey,␊ |
177 | +␉␉␉␉␉␉decryptkeysize,␊ |
178 | +␉␉␉␉␉␉&cryptvars->ctx.decrypt);␊ |
179 | +␉␉␉␊ |
180 | +␉␉// set the vector for the following decryptions␊ |
181 | +␉␉bcopy(((uint8_t *) header) + header->image1Size - AES_BLOCK_SIZE,␊ |
182 | +␉␉␉␉&cryptvars->aes_iv[0], AES_BLOCK_SIZE);␊ |
183 | +␉␉␊ |
184 | +␉␉// decrypt the buffer␊ |
185 | +␉␉uint32_t len = (uint32_t)(header->image1Size - header->encryptStart);␊ |
186 | +␉␉aes_decrypt_cbc(((uint8_t *) header) + header->encryptStart,␊ |
187 | +␉␉␉␉␉␉&first_iv[0],␊ |
188 | +␉␉␉␉␉␉len >> 4,␊ |
189 | +␉␉␉␉␉␉((uint8_t *) header) + header->encryptStart,␊ |
190 | +␉␉␉␉␉␉&cryptvars->ctx.decrypt);␊ |
191 | +␉␉bzero(&cryptvars->aes_iv[0], sizeof(cryptvars));␊ |
192 | +␉␉bzero(&decryptkey, sizeof(decryptkey));␊ |
193 | +␉}␊ |
194 | +#endif␊ |
195 | +␉␊ |
196 | +␉WakeKernel107(header);␊ |
197 | +}␊ |
198 | +␊ |
199 | void HibernateBoot(char *image_filename)␊ |
200 | {␊ |
201 | ␉long long size, imageSize, codeSize, allocSize;␊ |
202 | @@ -104,6 +280,12 @@␊ |
203 | ␉IOHibernateImageHeader * header = &_header;␊ |
204 | ␉long buffer;␊ |
205 | ␉␊ |
206 | + if(checkOSVersion("10.7"))␊ |
207 | + {␊ |
208 | + HibernateBoot107(image_filename);␊ |
209 | + return;␊ |
210 | + }␊ |
211 | + ␊ |
212 | ␉size = ReadFileAtOffset (image_filename, header, 0, sizeof(IOHibernateImageHeader));␊ |
213 | ␉printf("header read size %x\n", size);␊ |
214 | ␉␊ |
215 | @@ -139,13 +321,6 @@␊ |
216 | ␉mem_base = getmemorylimit() - allocSize;//TODO: lower this␊ |
217 | ␉␊ |
218 | ␉printf("mem_base %x\n", mem_base);␊ |
219 | -␉// Rek : hibernate fix ␊ |
220 | -␉if (!((long long)mem_base+allocSize<1024*bootInfo->extmem+0x100000))␊ |
221 | -␉{␊ |
222 | -␉␉printf ("Not enough space to restore image. Press any key to proceed with normal boot.\n");␊ |
223 | -␉␉getchar();␊ |
224 | -␉␉return;␊ |
225 | -␉}␊ |
226 | ␉␊ |
227 | ␉bcopy(header, (void *) mem_base, sizeof(IOHibernateImageHeader));␊ |
228 | ␉header = (IOHibernateImageHeader *) mem_base;␊ |
229 | @@ -171,11 +346,11 @@␊ |
230 | ␉␉previewLoadedSectors = 0;␊ |
231 | ␉␉previewSaveunder = 0;␊ |
232 | #if 0␊ |
233 | -␉␉AsereBLN:␊ |
234 | +␉␉/* AsereBLN:␊ |
235 | ␉␉check_vga_nvidia() didn't work as expected (recursion level > 0 & return value).␊ |
236 | ␉␉Unforutnaltely I cannot find a note why to switch back to text mode for nVidia cards only␊ |
237 | ␉␉and because it check_vga_nvidia does not work (cards normally are behind a bridge) I will␊ |
238 | -␉␉remove it completely␊ |
239 | +␉␉remove it completely */␊ |
240 | ␉␉setVideoMode( VGA_TEXT_MODE, 0 );␊ |
241 | #endif␊ |
242 | ␉}␊ |
243 | @@ -214,3 +389,5 @@␊ |
244 | ␉␊ |
245 | ␉WakeKernel(header);␊ |
246 | }␊ |
247 | +␊ |
248 | +␊ |
249 | Index: /Users/mr_w/Workspace/chameleon/i386/boot2/IOHibernatePrivate.h␊ |
250 | ===================================================================␊ |
251 | --- /Users/mr_w/Workspace/chameleon/i386/boot2/IOHibernatePrivate.h␉(revision 1227)␊ |
252 | +++ /Users/mr_w/Workspace/chameleon/i386/boot2/IOHibernatePrivate.h␉(working copy)␊ |
253 | @@ -95,7 +95,71 @@␊ |
254 | };␊ |
255 | typedef struct IOHibernateImageHeader IOHibernateImageHeader;␊ |
256 | ␊ |
257 | +struct IOHibernateImageHeader107␊ |
258 | +{␊ |
259 | + uint64_t␉imageSize;␊ |
260 | + uint64_t␉image1Size;␊ |
261 | + ␊ |
262 | + uint32_t␉restore1CodePhysPage;␊ |
263 | + uint32_t reserved1;␊ |
264 | + uint64_t␉restore1CodeVirt;␊ |
265 | + uint32_t␉restore1PageCount;␊ |
266 | + uint32_t␉restore1CodeOffset;␊ |
267 | + uint32_t␉restore1StackOffset;␊ |
268 | + ␊ |
269 | + uint32_t␉pageCount;␊ |
270 | + uint32_t␉bitmapSize;␊ |
271 | ␊ |
272 | + uint32_t␉restore1Sum;␊ |
273 | + uint32_t␉image1Sum;␊ |
274 | + uint32_t␉image2Sum;␊ |
275 | +␊ |
276 | + uint32_t␉actualRestore1Sum;␊ |
277 | + uint32_t␉actualImage1Sum;␊ |
278 | + uint32_t␉actualImage2Sum;␊ |
279 | +␊ |
280 | + uint32_t␉actualUncompressedPages;␊ |
281 | + uint32_t␉conflictCount;␊ |
282 | + uint32_t␉nextFree;␊ |
283 | +␊ |
284 | + uint32_t␉signature;␊ |
285 | + uint32_t␉processorFlags;␊ |
286 | +␊ |
287 | + uint32_t runtimePages;␊ |
288 | + uint32_t runtimePageCount;␊ |
289 | + uint64_t runtimeVirtualPages __attribute__ ((packed));␊ |
290 | +␊ |
291 | + uint32_t performanceDataStart;␊ |
292 | + uint32_t performanceDataSize;␊ |
293 | + ␊ |
294 | + uint64_t␉encryptStart __attribute__ ((packed));␊ |
295 | + uint64_t␉machineSignature __attribute__ ((packed));␊ |
296 | +␊ |
297 | + uint32_t previewSize;␊ |
298 | + uint32_t previewPageListSize;␊ |
299 | +␊ |
300 | + uint32_t␉diag[4];␊ |
301 | +␊ |
302 | + uint32_t handoffPages;␊ |
303 | + uint32_t handoffPageCount;␊ |
304 | +␊ |
305 | + uint32_t systemTableOffset;␊ |
306 | +␊ |
307 | + uint32_t␉debugFlags;␊ |
308 | + uint32_t␉options;␊ |
309 | +␊ |
310 | + uint32_t␉reserved[70];␉␉// make sizeof == 512␊ |
311 | +␊ |
312 | + uint64_t␉encryptEnd __attribute__ ((packed));␊ |
313 | + uint64_t␉deviceBase __attribute__ ((packed));␊ |
314 | +␊ |
315 | + uint32_t␉␉fileExtentMapSize;␊ |
316 | + IOPolledFileExtent␉fileExtentMap[2];␊ |
317 | +};␊ |
318 | +␊ |
319 | +␊ |
320 | +typedef struct IOHibernateImageHeader107 IOHibernateImageHeader107;␊ |
321 | +␊ |
322 | struct hibernate_bitmap_t␊ |
323 | {␊ |
324 | uint32_t␉first_page;␊ |
325 | |