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

Archive Download this file

Revision: 789