Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/boot2/ramdisk.c

Source at commit 251 created 13 years 8 months ago.
By meklort, Make md0 image user selectable. Falls back to Postboot.img
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{
38sprintf(filename, "rd(0,0)/Extra/%s");
39if((fh = open(filename, 0)) < 0)
40{
41sprintf(filename, "/Extra/%s");
42fh = open(filename, 0);
43
44}
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);
54if(fh < 0)
55{
56sprintf(filename, "/Extra/Postboot.img");// Check /Extra if not in rd(0,0)
57fh = open(filename, 0);
58
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
86}
87else {
88verbose("Unable to read md0 image %s.\n", filename);
89}
90
91} else {
92verbose("md0 image %s is empty.\n", filename);
93}
94
95
96close(fh);
97
98}
99}
100
101
102void umountRAMDisk()
103{
104 if (gRAMDiskMI != NULL)
105 {
106 // Release ramdisk BVRef and DiskBVMap.
107 struct DiskBVMap *oldMap = diskResetBootVolumes(0x100);
108 CacheReset();
109 diskFreeMap(oldMap);
110
111 // Free multiboot info and module structures.
112 if ((void *)gRAMDiskMI->mi_mods_addr != NULL) free((void *)gRAMDiskMI->mi_mods_addr);
113 if (gRAMDiskMI != NULL) free(gRAMDiskMI);
114
115 // Reset multiboot structures.
116 gMI = gRAMDiskMI = NULL;
117 *gRAMDiskFile = '\0';
118
119 // Release ramdisk driver hooks.
120 p_get_ramdisk_info = NULL;
121 p_ramdiskReadBytes = NULL;
122
123 printf("\nunmounting: done");
124 }
125}
126
127int mountRAMDisk(const char * param)
128{
129 int fh = 0, ramDiskSize;
130 int error = 0;
131
132 // Get file handle for ramdisk file.
133 fh = open(param, 0);
134 if (fh != -1)
135 {
136printf("\nreading ramdisk image: %s", param);
137
138ramDiskSize = file_size(fh);
139 if (ramDiskSize > 0)
140 {
141 // Unmount previously mounted image if exists.
142 umountRAMDisk();
143
144 // Read new ramdisk image contents into PREBOOT_DATA area.
145 if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1;
146 }
147 else error = -1;
148
149 close(fh);
150 }
151 else error = -1;
152
153 if (error == 0)
154 {
155 // Save filename in gRAMDiskFile to display information.
156 strcpy(gRAMDiskFile, param);
157
158 // Set gMI as well for the multiboot ramdisk driver hook.
159 gMI = gRAMDiskMI = malloc(sizeof(multiboot_info));
160 struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module));
161
162 // Fill in multiboot info and module structures.
163 if (gRAMDiskMI != NULL && ramdisk_module != NULL)
164 {
165 gRAMDiskMI->mi_mods_count = 1;
166 gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module;
167 ramdisk_module->mm_mod_start = PREBOOT_DATA;
168 ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize;
169
170 // Set ramdisk driver hooks.
171 p_get_ramdisk_info = &multiboot_get_ramdisk_info;
172 p_ramdiskReadBytes = &multibootRamdiskReadBytes;
173
174 int partCount; // unused
175 // Save bvr of the mounted image.
176 gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount);
177 if(gRAMDiskVolume == NULL)
178 {
179 umountRAMDisk();
180 printf("\nRamdisk contains no partitions.");
181 }
182 else
183 {
184 char dirSpec[128];
185
186 // Reading ramdisk configuration.
187 strcpy(dirSpec, RAMDISKCONFIG_FILENAME);
188
189 if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0)
190 {
191 getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig);
192 }
193 else
194 {
195 printf("\nno ramdisk config...\n");
196 }
197
198 printf("\nmounting: done");
199 }
200 }
201
202 }
203
204 return error;
205}
206
207void setRAMDiskBTHook(bool mode)
208{
209 gRAMDiskBTAliased = mode;
210 if (mode) {
211 printf("\nEnabled bt(0,0) alias.");
212 } else {
213 printf("\nDisabled bt(0,0) alias.");
214 }
215}
216
217void showInfoRAMDisk(void)
218{
219 int len;
220 const char *val;
221
222 if (gRAMDiskMI != NULL)
223 {
224 struct multiboot_module * ramdisk_module = (void *)gRAMDiskMI->mi_mods_addr;
225
226 printf("\nfile: %s %d", gRAMDiskFile,
227 ramdisk_module->mm_mod_end - ramdisk_module->mm_mod_start);
228 printf("\nalias: %s", gRAMDiskBTAliased ? "enabled" : "disabled");
229
230 // Display ramdisk information if available.
231
232 if (getValueForKey("Info", &val, &len, &bootInfo->ramdiskConfig))
233 printf("\ninfo: %s", val);
234 else
235 printf("\nramdisk info not available.");
236
237 }
238 else
239 {
240 printf("\nNo ramdisk mounted.");
241 }
242}
243
244int loadPrebootRAMDisk()
245{
246 mountRAMDisk("bt(0,0)/Extra/Preboot.dmg");
247 if (gRAMDiskMI != NULL)
248 {
249 printf("\n");
250 return 0;
251 }
252 else
253 {
254 return -1;
255 }
256}
257
258void processRAMDiskCommand(char ** argPtr, const char * cmd)
259{
260 char * ptr = *argPtr;
261 char param[1024];
262 getNextArg(&ptr, param);
263
264 if (strcmp(cmd, "m") == 0)
265 {
266 mountRAMDisk(param);
267 sleep(2);
268 }
269 else if (strcmp(cmd, "u") == 0)
270 {
271 umountRAMDisk();
272 sleep(2);
273 }
274 else if (strcmp(cmd, "e") == 0)
275 {
276 setRAMDiskBTHook(1);
277 sleep(2);
278 }
279 else if (strcmp(cmd, "d") == 0)
280 {
281 setRAMDiskBTHook(0);
282 sleep(2);
283 }
284 else if (strcmp(cmd, "i") == 0)
285 {
286 setActiveDisplayPage(1);
287 clearScreenRows(0, 24);
288 setCursorPosition(0, 0, 1);
289 showInfoRAMDisk();
290 printf("\n\nPress any key to continue.\n");
291 getc();
292 setActiveDisplayPage(0);
293 }
294 else
295 {
296 setActiveDisplayPage(1);
297 clearScreenRows(0, 24);
298 setCursorPosition(0, 0, 1);
299 printf("\nusage:\n");
300 printf("\n?rd i - display ramdisk information");
301 printf("\n?rd m <filename> - mount ramdisk image\n?rd u - unmount ramdisk image");
302 printf("\n?rd e - enable bt(0,0) alias\n?rd d - disable bt(0,0) alias");
303 printf("\n\nPress any key to continue.\n");
304 getc();
305 setActiveDisplayPage(0);
306 }
307}
308

Archive Download this file

Revision: 251