Chameleon

Chameleon Svn Source Tree

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

Source at commit 152 created 13 years 11 months ago.
By meklort, Load a ramdisk if it exists, and notify XNU of the ramdisk
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 = 0;
25int fh = 0;
26
27// Look for a ramdisk at Postboot.img (TODO: make configurable)
28filename = "rd(0,0)/Extra/Postboot.img";
29if((fh = open(filename, 0)) == -1)
30{
31filename = "/Extra/Postboot.img";// Check /Extra if not in rd(0,0)
32fh = open(filename, 0);
33
34}
35
36
37if (fh != -1)
38{
39verbose("Enabling ramdisk %s\n", filename);
40
41ramdiskPtr.size = file_size(fh);
42ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size);
43
44if(ramdiskPtr.size && ramdiskPtr.base)
45{
46// Read new ramdisk image contents in kernel memory.
47if (read(fh, (char*) ramdiskPtr.base, ramdiskPtr.size) == ramdiskPtr.size)
48{
49AllocateMemoryRange("RAMDisk", ramdiskPtr.base, ramdiskPtr.size, kBootDriverTypeInvalid);
50Node* node = DT__FindNode("/chosen/memory-map", false);
51if(node != NULL)
52{
53DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam), (void*)&ramdiskPtr);
54
55}
56else
57{
58verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename);
59}
60
61}
62else {
63verbose("Unable to read ramdisk %s\n", filename);
64}
65
66} else {
67verbose("Ramdisk %s is empty.\n", filename);
68}
69
70
71close(fh);
72
73}
74else {
75verbose("Unable to open %s\n", filename);
76}
77}
78
79
80void umountRAMDisk()
81{
82 if (gRAMDiskMI != NULL)
83 {
84 // Release ramdisk BVRef and DiskBVMap.
85 struct DiskBVMap *oldMap = diskResetBootVolumes(0x100);
86 CacheReset();
87 diskFreeMap(oldMap);
88
89 // Free multiboot info and module structures.
90 if ((void *)gRAMDiskMI->mi_mods_addr != NULL) free((void *)gRAMDiskMI->mi_mods_addr);
91 if (gRAMDiskMI != NULL) free(gRAMDiskMI);
92
93 // Reset multiboot structures.
94 gMI = gRAMDiskMI = NULL;
95 *gRAMDiskFile = '\0';
96
97 // Release ramdisk driver hooks.
98 p_get_ramdisk_info = NULL;
99 p_ramdiskReadBytes = NULL;
100
101 printf("\nunmounting: done");
102 }
103}
104
105int mountRAMDisk(const char * param)
106{
107 int fh = 0, ramDiskSize;
108 int error = 0;
109
110 // Get file handle for ramdisk file.
111 fh = open(param, 0);
112 if (fh != -1)
113 {
114printf("\nreading ramdisk image: %s", param);
115
116ramDiskSize = file_size(fh);
117 if (ramDiskSize > 0)
118 {
119 // Unmount previously mounted image if exists.
120 umountRAMDisk();
121
122 // Read new ramdisk image contents into PREBOOT_DATA area.
123 if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1;
124 }
125 else error = -1;
126
127 close(fh);
128 }
129 else error = -1;
130
131 if (error == 0)
132 {
133 // Save filename in gRAMDiskFile to display information.
134 strcpy(gRAMDiskFile, param);
135
136 // Set gMI as well for the multiboot ramdisk driver hook.
137 gMI = gRAMDiskMI = malloc(sizeof(multiboot_info));
138 struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module));
139
140 // Fill in multiboot info and module structures.
141 if (gRAMDiskMI != NULL && ramdisk_module != NULL)
142 {
143 gRAMDiskMI->mi_mods_count = 1;
144 gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module;
145 ramdisk_module->mm_mod_start = PREBOOT_DATA;
146 ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize;
147
148 // Set ramdisk driver hooks.
149 p_get_ramdisk_info = &multiboot_get_ramdisk_info;
150 p_ramdiskReadBytes = &multibootRamdiskReadBytes;
151
152 int partCount; // unused
153 // Save bvr of the mounted image.
154 gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount);
155 if(gRAMDiskVolume == NULL)
156 {
157 umountRAMDisk();
158 printf("\nRamdisk contains no partitions.");
159 }
160 else
161 {
162 char dirSpec[128];
163
164 // Reading ramdisk configuration.
165 strcpy(dirSpec, RAMDISKCONFIG_FILENAME);
166
167 if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0)
168 {
169 getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig);
170 }
171 else
172 {
173 printf("\nno ramdisk config...\n");
174 }
175
176 printf("\nmounting: done");
177 }
178 }
179
180 }
181
182 return error;
183}
184
185void setRAMDiskBTHook(bool mode)
186{
187 gRAMDiskBTAliased = mode;
188 if (mode) {
189 printf("\nEnabled bt(0,0) alias.");
190 } else {
191 printf("\nDisabled bt(0,0) alias.");
192 }
193}
194
195void showInfoRAMDisk(void)
196{
197 int len;
198 const char *val;
199
200 if (gRAMDiskMI != NULL)
201 {
202 struct multiboot_module * ramdisk_module = (void *)gRAMDiskMI->mi_mods_addr;
203
204 printf("\nfile: %s %d", gRAMDiskFile,
205 ramdisk_module->mm_mod_end - ramdisk_module->mm_mod_start);
206 printf("\nalias: %s", gRAMDiskBTAliased ? "enabled" : "disabled");
207
208 // Display ramdisk information if available.
209
210 if (getValueForKey("Info", &val, &len, &bootInfo->ramdiskConfig))
211 printf("\ninfo: %s", val);
212 else
213 printf("\nramdisk info not available.");
214
215 }
216 else
217 {
218 printf("\nNo ramdisk mounted.");
219 }
220}
221
222int loadPrebootRAMDisk()
223{
224 mountRAMDisk("bt(0,0)/Extra/Preboot.dmg");
225 if (gRAMDiskMI != NULL)
226 {
227 printf("\n");
228 return 0;
229 }
230 else
231 {
232 return -1;
233 }
234}
235
236void processRAMDiskCommand(char ** argPtr, const char * cmd)
237{
238 char * ptr = *argPtr;
239 char param[1024];
240 getNextArg(&ptr, param);
241
242 if (strcmp(cmd, "m") == 0)
243 {
244 mountRAMDisk(param);
245 sleep(2);
246 }
247 else if (strcmp(cmd, "u") == 0)
248 {
249 umountRAMDisk();
250 sleep(2);
251 }
252 else if (strcmp(cmd, "e") == 0)
253 {
254 setRAMDiskBTHook(1);
255 sleep(2);
256 }
257 else if (strcmp(cmd, "d") == 0)
258 {
259 setRAMDiskBTHook(0);
260 sleep(2);
261 }
262 else if (strcmp(cmd, "i") == 0)
263 {
264 setActiveDisplayPage(1);
265 clearScreenRows(0, 24);
266 setCursorPosition(0, 0, 1);
267 showInfoRAMDisk();
268 printf("\n\nPress any key to continue.\n");
269 getc();
270 setActiveDisplayPage(0);
271 }
272 else
273 {
274 setActiveDisplayPage(1);
275 clearScreenRows(0, 24);
276 setCursorPosition(0, 0, 1);
277 printf("\nusage:\n");
278 printf("\n?rd i - display ramdisk information");
279 printf("\n?rd m <filename> - mount ramdisk image\n?rd u - unmount ramdisk image");
280 printf("\n?rd e - enable bt(0,0) alias\n?rd d - disable bt(0,0) alias");
281 printf("\n\nPress any key to continue.\n");
282 getc();
283 setActiveDisplayPage(0);
284 }
285}
286

Archive Download this file

Revision: 152