Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 296