Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/boot2/ramdisk.c

1/*
2 * Supplemental ramdisk functions for the multiboot ramdisk driver.
3 * Copyright 2009 Tamas Kosarszky. All rights reserved.
4 *
5 */
6
7#include "boot.h"
8#include "bootstruct.h"
9#include "multiboot.h"
10#include "ramdisk.h"
11
12struct multiboot_info * gRAMDiskMI = NULL;
13
14// gRAMDiskVolume holds the bvr for the mounted ramdisk image.
15BVRef gRAMDiskVolume = NULL;
16bool gRAMDiskBTAliased = false;
17char gRAMDiskFile[512];
18
19
20// Notify OS X that a ramdisk has been setup. XNU with attach this to /dev/md0
21void md0Ramdisk()
22{
23RAMDiskParam ramdiskPtr;
24char filename[512];
25const char* override_filename = 0;
26int fh = -1;
27int len;
28
29if(getValueForKey(kMD0Image, &override_filename, &len,
30 &bootInfo->bootConfig))
31{
32// Use user specified md0 file
33sprintf(filename, "%s", override_filename);
34fh = open(filename, 0);
35
36if(fh < 0)
37{
38if(gRAMDiskVolume && !gRAMDiskBTAliased)
39{
40sprintf(filename, "rd(0,0)/Extra/%s", override_filename);
41fh = open(filename, 0);
42}
43
44if(fh < 0)
45{
46sprintf(filename, "/Extra/%s", override_filename);
47fh = open(filename, 0);
48
49}
50}
51}
52
53
54if(fh < 0)
55{
56// Fallback to Postboot.img
57if(gRAMDiskVolume && !gRAMDiskBTAliased)
58{
59sprintf(filename, "rd(0,0)/Extra/Postboot.img");
60fh = open(filename, 0);
61}
62
63if(fh < 0)
64{
65sprintf(filename, "/Extra/Postboot.img");// Check /Extra if not in rd(0,0)
66fh = open(filename, 0);
67
68}
69}
70
71if (fh >= 0)
72{
73verbose("Enabling ramdisk %s\n", filename);
74
75ramdiskPtr.size = file_size(fh);
76ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size);
77
78if(ramdiskPtr.size && ramdiskPtr.base)
79{
80// Read new ramdisk image contents in kernel memory.
81if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size)
82{
83AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size, kBootDriverTypeInvalid);
84Node* node = DT__FindNode("/chosen/memory-map", false);
85if(node != NULL)
86{
87DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam), (void*)&ramdiskPtr);
88
89}
90else
91{
92verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename);
93}
94
95}
96else {
97verbose("Unable to read md0 image %s.\n", filename);
98}
99
100} else {
101verbose("md0 image %s is empty.\n", filename);
102}
103
104
105close(fh);
106
107}
108}
109
110
111void umountRAMDisk()
112{
113 if (gRAMDiskMI != NULL)
114 {
115 // Release ramdisk BVRef and DiskBVMap.
116 struct DiskBVMap *oldMap = diskResetBootVolumes(0x100);
117 CacheReset();
118 diskFreeMap(oldMap);
119
120 // Free multiboot info and module structures.
121 if ((void *)gRAMDiskMI->mi_mods_addr != NULL) free((void *)gRAMDiskMI->mi_mods_addr);
122 if (gRAMDiskMI != NULL) free(gRAMDiskMI);
123
124 // Reset multiboot structures.
125 gMI = gRAMDiskMI = NULL;
126 *gRAMDiskFile = '\0';
127
128 // Release ramdisk driver hooks.
129 p_get_ramdisk_info = NULL;
130 p_ramdiskReadBytes = NULL;
131
132 printf("\nunmounting: done");
133 }
134}
135
136int mountRAMDisk(const char * param)
137{
138 int fh = 0, ramDiskSize;
139 int error = 0;
140
141 // Get file handle for ramdisk file.
142 fh = open(param, 0);
143 if (fh != -1)
144 {
145printf("\nreading ramdisk image: %s", param);
146
147ramDiskSize = file_size(fh);
148 if (ramDiskSize > 0)
149 {
150 // Unmount previously mounted image if exists.
151 umountRAMDisk();
152
153 // Read new ramdisk image contents into PREBOOT_DATA area.
154 if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1;
155 }
156 else error = -1;
157
158 close(fh);
159 }
160 else error = -1;
161
162 if (error == 0)
163 {
164 // Save filename in gRAMDiskFile to display information.
165 strcpy(gRAMDiskFile, param);
166
167 // Set gMI as well for the multiboot ramdisk driver hook.
168 gMI = gRAMDiskMI = malloc(sizeof(multiboot_info));
169 struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module));
170
171 // Fill in multiboot info and module structures.
172 if (gRAMDiskMI != NULL && ramdisk_module != NULL)
173 {
174 gRAMDiskMI->mi_mods_count = 1;
175 gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module;
176 ramdisk_module->mm_mod_start = PREBOOT_DATA;
177 ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize;
178
179 // Set ramdisk driver hooks.
180 p_get_ramdisk_info = &multiboot_get_ramdisk_info;
181 p_ramdiskReadBytes = &multibootRamdiskReadBytes;
182
183 int partCount; // unused
184 // Save bvr of the mounted image.
185 gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount);
186 if(gRAMDiskVolume == NULL)
187 {
188 umountRAMDisk();
189 printf("\nRamdisk contains no partitions.");
190 }
191 else
192 {
193 char dirSpec[128];
194
195 // Reading ramdisk configuration.
196 strcpy(dirSpec, RAMDISKCONFIG_FILENAME);
197
198 if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0)
199 {
200 getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig);
201 }
202 else
203 {
204 printf("\nno ramdisk config...\n");
205 }
206
207 printf("\nmounting: done");
208 }
209 }
210
211 }
212
213 return error;
214}
215
216void setRAMDiskBTHook(bool mode)
217{
218 gRAMDiskBTAliased = mode;
219 if (mode) {
220 printf("\nEnabled bt(0,0) alias.");
221 } else {
222 printf("\nDisabled bt(0,0) alias.");
223 }
224}
225
226void showInfoRAMDisk(void)
227{
228 int len;
229 const char *val;
230
231 if (gRAMDiskMI != NULL)
232 {
233 struct multiboot_module * ramdisk_module = (void *)gRAMDiskMI->mi_mods_addr;
234
235 printf("\nfile: %s %d", gRAMDiskFile,
236 ramdisk_module->mm_mod_end - ramdisk_module->mm_mod_start);
237 printf("\nalias: %s", gRAMDiskBTAliased ? "enabled" : "disabled");
238
239 // Display ramdisk information if available.
240
241 if (getValueForKey("Info", &val, &len, &bootInfo->ramdiskConfig))
242 printf("\ninfo: %s", val);
243 else
244 printf("\nramdisk info not available.");
245
246 }
247 else
248 {
249 printf("\nNo ramdisk mounted.");
250 }
251}
252
253int loadPrebootRAMDisk()
254{
255 mountRAMDisk("bt(0,0)/Extra/Preboot.dmg");
256 if (gRAMDiskMI != NULL)
257 {
258 printf("\n");
259 return 0;
260 }
261 else
262 {
263 return -1;
264 }
265}
266
267void processRAMDiskCommand(char ** argPtr, const char * cmd)
268{
269 char * ptr = *argPtr;
270 char param[1024];
271 getNextArg(&ptr, param);
272
273 if (strcmp(cmd, "m") == 0)
274 {
275 mountRAMDisk(param);
276 sleep(2);
277 }
278 else if (strcmp(cmd, "u") == 0)
279 {
280 umountRAMDisk();
281 sleep(2);
282 }
283 else if (strcmp(cmd, "e") == 0)
284 {
285 setRAMDiskBTHook(1);
286 sleep(2);
287 }
288 else if (strcmp(cmd, "d") == 0)
289 {
290 setRAMDiskBTHook(0);
291 sleep(2);
292 }
293 else if (strcmp(cmd, "i") == 0)
294 {
295 setActiveDisplayPage(1);
296 clearScreenRows(0, 24);
297 setCursorPosition(0, 0, 1);
298 showInfoRAMDisk();
299 printf("\n\nPress any key to continue.\n");
300 getc();
301 setActiveDisplayPage(0);
302 }
303 else
304 {
305 setActiveDisplayPage(1);
306 clearScreenRows(0, 24);
307 setCursorPosition(0, 0, 1);
308 printf("\nusage:\n");
309 printf("\n?rd i - display ramdisk information");
310 printf("\n?rd m <filename> - mount ramdisk image\n?rd u - unmount ramdisk image");
311 printf("\n?rd e - enable bt(0,0) alias\n?rd d - disable bt(0,0) alias");
312 printf("\n\nPress any key to continue.\n");
313 getc();
314 setActiveDisplayPage(0);
315 }
316}
317

Archive Download this file

Revision: 262