Chameleon

View hibernate107v1.patch

1Index: /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+
249Index: /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_timageSize;
260+ uint64_timage1Size;
261+
262+ uint32_trestore1CodePhysPage;
263+ uint32_t reserved1;
264+ uint64_trestore1CodeVirt;
265+ uint32_trestore1PageCount;
266+ uint32_trestore1CodeOffset;
267+ uint32_trestore1StackOffset;
268+
269+ uint32_tpageCount;
270+ uint32_tbitmapSize;
271
272+ uint32_trestore1Sum;
273+ uint32_timage1Sum;
274+ uint32_timage2Sum;
275+
276+ uint32_tactualRestore1Sum;
277+ uint32_tactualImage1Sum;
278+ uint32_tactualImage2Sum;
279+
280+ uint32_tactualUncompressedPages;
281+ uint32_tconflictCount;
282+ uint32_tnextFree;
283+
284+ uint32_tsignature;
285+ uint32_tprocessorFlags;
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_tencryptStart __attribute__ ((packed));
295+ uint64_tmachineSignature __attribute__ ((packed));
296+
297+ uint32_t previewSize;
298+ uint32_t previewPageListSize;
299+
300+ uint32_tdiag[4];
301+
302+ uint32_t handoffPages;
303+ uint32_t handoffPageCount;
304+
305+ uint32_t systemTableOffset;
306+
307+ uint32_tdebugFlags;
308+ uint32_toptions;
309+
310+ uint32_treserved[70];// make sizeof == 512
311+
312+ uint64_tencryptEnd __attribute__ ((packed));
313+ uint64_tdeviceBase __attribute__ ((packed));
314+
315+ uint32_tfileExtentMapSize;
316+ IOPolledFileExtentfileExtentMap[2];
317+};
318+
319+
320+typedef struct IOHibernateImageHeader107 IOHibernateImageHeader107;
321+
322 struct hibernate_bitmap_t
323 {
324 uint32_tfirst_page;
325

Archive Download this file

Attachment to issue 133

Created: 10 years 5 months ago by Vladimir Zidar