Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/modules/RamDiskLoader/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
19long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p) = NULL;
20int (*p_ramdiskReadBytes)( int biosdev, unsigned int blkno,
21 unsigned int byteoff,
22 unsigned int byteCount, void * buffer ) = NULL;
23int (*p_get_ramdisk_info)(int biosdev, struct driveInfo *dip) = NULL;
24
25int multibootRamdiskReadBytes( int biosdev, unsigned int blkno,
26 unsigned int byteoff,
27 unsigned int byteCount, void * buffer );
28int multiboot_get_ramdisk_info(int biosdev, struct driveInfo *dip);
29static long multiboot_LoadExtraDrivers(FileLoadDrivers_t FileLoadDrivers_p);
30
31
32// Notify OS X that a ramdisk has been setup. XNU with attach this to /dev/md0
33void md0Ramdisk()
34{
35RAMDiskParam ramdiskPtr;
36char filename[512];
37const char* override_filename = 0;
38int fh = -1;
39int len;
40
41if(getValueForKey(kMD0Image, &override_filename, &len,
42 &bootInfo->bootConfig))
43{
44// Use user specified md0 file
45sprintf(filename, "%s", override_filename);
46fh = open(filename);
47
48if(fh < 0)
49{
50sprintf(filename, "bt(0,0)/Extra/%s", override_filename);
51fh = open(filename);
52
53if(fh < 0)
54{
55sprintf(filename, "rd(0,0)/Extra/%s", override_filename);
56fh = open(filename);
57
58if(fh < 0)
59{
60sprintf(filename, "/Extra/%s", override_filename);
61fh = open(filename);
62}
63}
64}
65}
66
67if(fh < 0)
68{
69sprintf(filename, "bt(0,0)/Extra/Postboot.img");
70fh = open(filename);
71
72if(fh < 0)
73{
74sprintf(filename, "rd(0,0)/Extra/Postboot.img");
75fh = open(filename);
76
77if(fh < 0)
78{
79sprintf(filename, "/Extra/Postboot.img");// Check /Extra if not in rd(0,0)
80fh = open(filename);
81}
82}
83}
84
85if (fh >= 0)
86{
87verbose("Enabling ramdisk %s\n", filename);
88
89ramdiskPtr.size = file_size(fh);
90ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size);
91
92if(ramdiskPtr.size && ramdiskPtr.base)
93{
94// Read new ramdisk image contents in kernel memory.
95if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size)
96{
97#if UNUSED
98 AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size, kBootDriverTypeInvalid);
99#else
100 AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size);
101#endif
102Node* node = DT__FindNode("/chosen/memory-map", false);
103if(node != NULL)
104{
105DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam), (void*)&ramdiskPtr);
106}
107else
108{
109verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename);
110}
111}
112else
113{
114verbose("Unable to read md0 image %s.\n", filename);
115}
116}
117else
118{
119verbose("md0 image %s is empty.\n", filename);
120}
121
122close(fh);
123
124}
125}
126
127void umountRAMDisk()
128{
129if (gRAMDiskMI != NULL)
130{
131// Release ramdisk BVRef and DiskBVMap.
132struct DiskBVMap *oldMap = diskResetBootVolumes(0x100);
133CacheReset();
134diskFreeMap(oldMap);
135
136// Free multiboot info and module structures.
137if ((void *)gRAMDiskMI->mi_mods_addr != NULL) free((void *)gRAMDiskMI->mi_mods_addr);
138if (gRAMDiskMI != NULL) free(gRAMDiskMI);
139
140// Reset multiboot structures.
141gRAMDiskMI = NULL;
142gMI = gRAMDiskMI;
143
144*gRAMDiskFile = '\0';
145
146// Release ramdisk driver hooks.
147p_get_ramdisk_info = NULL;
148p_ramdiskReadBytes = NULL;
149LoadExtraDrivers_p = NULL;
150
151// Reset ramdisk bvr
152gRAMDiskVolume = NULL;
153printf("\nunmounting: done");
154}
155}
156
157int mountRAMDisk(const char * param)
158{
159int fh = 0, ramDiskSize;
160int error = 0;
161
162// Get file handle for ramdisk file.
163fh = open(param);
164if (fh != -1)
165{
166printf("\nreading ramdisk image: %s\n", param);
167
168ramDiskSize = file_size(fh);
169if (ramDiskSize > 0)
170{
171// Unmount previously mounted image if exists.
172umountRAMDisk();
173
174// Read new ramdisk image contents into PREBOOT_DATA area.
175if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1;
176}
177else error = -1;
178
179close(fh);
180}
181else error = -1;
182
183if (error == 0)
184{
185// Save filename in gRAMDiskFile to display information.
186strcpy(gRAMDiskFile, param);
187
188// Set gMI as well for the multiboot ramdisk driver hook.
189gRAMDiskMI = malloc(sizeof(multiboot_info));
190gMI = gRAMDiskMI;
191
192struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module));
193
194// Fill in multiboot info and module structures.
195if (gRAMDiskMI != NULL && ramdisk_module != NULL)
196{
197gRAMDiskMI->mi_mods_count = 1;
198gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module;
199ramdisk_module->mm_mod_start = PREBOOT_DATA;
200ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize;
201
202// Set ramdisk driver hooks.
203p_get_ramdisk_info = &multiboot_get_ramdisk_info;
204p_ramdiskReadBytes = &multibootRamdiskReadBytes;
205LoadExtraDrivers_p = &multiboot_LoadExtraDrivers;
206
207int partCount; // unused
208// Save bvr of the mounted image.
209gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount);
210if(gRAMDiskVolume == NULL)
211{
212umountRAMDisk();
213printf("\nRamdisk contains no partitions.\n");
214pause();
215
216}
217else
218{
219char dirSpec[128];
220
221// Reading ramdisk configuration.
222strcpy(dirSpec, RAMDISKCONFIG_FILENAME);
223
224if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0)
225{
226getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig);
227}
228else
229{
230verbose("\nno ramdisk config...\n");
231}
232
233printf("\nmounting: done");
234}
235}
236}
237return error;
238}
239
240void setRAMDiskBTHook(bool mode)
241{
242gRAMDiskBTAliased = mode;
243if (mode)
244{
245printf("\nEnabled bt(0,0) alias.");
246}
247else
248{
249printf("\nDisabled bt(0,0) alias.");
250}
251}
252
253void showInfoRAMDisk(void)
254{
255int len;
256const char *val;
257
258if (gRAMDiskMI != NULL)
259{
260struct multiboot_module * ramdisk_module = (void *)gRAMDiskMI->mi_mods_addr;
261
262printf("\nfile: %s %d", gRAMDiskFile,
263ramdisk_module->mm_mod_end - ramdisk_module->mm_mod_start);
264printf("\nalias: %s", gRAMDiskBTAliased ? "enabled" : "disabled");
265
266// Display ramdisk information if available.
267if (getValueForKey("Info", &val, &len, &bootInfo->ramdiskConfig))
268{
269printf("\ninfo: %s", val);
270}
271else
272{
273printf("\nramdisk info not available.");
274}
275}
276else
277{
278printf("\nNo ramdisk mounted.");
279}
280}
281
282int loadPrebootRAMDisk()
283{
284mountRAMDisk("bt(0,0)/Extra/Preboot.dmg");
285if (gRAMDiskMI != NULL)
286{
287printf("\n");
288return 0;
289}
290else
291{
292return -1;
293}
294}
295
296void processRAMDiskCommand(char ** argPtr, const char * cmd)
297{
298char * ptr = *argPtr;
299char param[1024];
300getNextArg(&ptr, param);
301
302if (strcmp(cmd, "m") == 0)
303{
304mountRAMDisk(param);
305sleep(2);
306}
307else if (strcmp(cmd, "u") == 0)
308{
309umountRAMDisk();
310sleep(2);
311}
312else if (strcmp(cmd, "e") == 0)
313{
314setRAMDiskBTHook(true);
315sleep(2);
316}
317else if (strcmp(cmd, "d") == 0)
318{
319setRAMDiskBTHook(false);
320sleep(2);
321}
322else if (strcmp(cmd, "i") == 0)
323{
324setActiveDisplayPage(1);
325clearScreenRows(0, 24);
326setCursorPosition(0, 0, 1);
327showInfoRAMDisk();
328printf("\n\nPress any key to continue.\n");
329getc();
330setActiveDisplayPage(0);
331}
332else
333{
334setActiveDisplayPage(1);
335clearScreenRows(0, 24);
336setCursorPosition(0, 0, 1);
337printf("\nusage:\n");
338printf("\n?rd i - display ramdisk information");
339printf("\n?rd m <filename> - mount ramdisk image\n?rd u - unmount ramdisk image");
340printf("\n?rd e - enable bt(0,0) alias\n?rd d - disable bt(0,0) alias");
341printf("\n\nPress any key to continue.\n");
342getc();
343setActiveDisplayPage(0);
344}
345}
346
347///////////////////////////////////////////////////////////////////////////
348// Ramdisk multiboot support
349
350int multibootRamdiskReadBytes( int biosdev, unsigned int blkno,
351 unsigned int byteoff,
352 unsigned int byteCount, void * buffer )
353{
354 int module_count = gMI->mi_mods_count;
355 struct multiboot_module *modules = (void*)gMI->mi_mods_addr;
356 if(biosdev < 0x100)
357 return -1;
358 if(biosdev >= (0x100 + module_count))
359 return -1;
360 struct multiboot_module *module = modules + (biosdev - 0x100);
361
362 void *p_initrd = (void*)module->mm_mod_start;
363 bcopy(p_initrd + blkno*512 + byteoff, buffer, byteCount);
364 return 0;
365}
366
367int multiboot_get_ramdisk_info(int biosdev, struct driveInfo *dip)
368{
369 int module_count = gMI->mi_mods_count;
370 struct multiboot_module *modules = (void*)gMI->mi_mods_addr;
371 if(biosdev < 0x100)
372 return -1;
373 if(biosdev >= (0x100 + module_count))
374 return -1;
375 struct multiboot_module *module = modules + (biosdev - 0x100);
376 dip->biosdev = biosdev;
377 dip->uses_ebios = true;// XXX aserebln uses_ebios isn't a boolean at all
378 dip->di.params.phys_sectors = (module->mm_mod_end - module->mm_mod_start + 511) / 512;
379 dip->valid = true;
380 return 0;
381}
382
383static long multiboot_LoadExtraDrivers(FileLoadDrivers_t FileLoadDrivers_p)
384{
385 char extensionsSpec[1024];
386 int ramdiskUnit;
387 for(ramdiskUnit = 0; ramdiskUnit < gMI->mi_mods_count; ++ramdiskUnit)
388 {
389 int partCount; // unused
390 BVRef ramdiskChain = diskScanBootVolumes(0x100 + ramdiskUnit, &partCount);
391 if(ramdiskChain == NULL)
392 {
393 verbose("Ramdisk contains no partitions\n");
394 continue;
395 }
396 for(; ramdiskChain != NULL; ramdiskChain = ramdiskChain->next)
397 {
398 sprintf(extensionsSpec, "rd(%d,%d)/Extra/", ramdiskUnit, ramdiskChain->part_no);
399 struct dirstuff *extradir = opendir(extensionsSpec);
400 closedir(extradir);
401 if(extradir != NULL)
402 {
403 int ret = FileLoadDrivers_p(extensionsSpec, 0 /* this is a kext root dir, not a kext with plugins */);
404 if(ret != 0)
405 {
406 verbose("FileLoadDrivers failed on a ramdisk\n");
407 return ret;
408 }
409 }
410 }
411 }
412 return 0;
413}
414

Archive Download this file

Revision: 1119