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

Archive Download this file

Revision: 385