]>
Commit | Line | Data |
---|---|---|
2d21ac55 A |
1 | /* |
2 | * Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
25 | * | |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
27 | */ | |
9bccf70c A |
28 | /* |
29 | * DINetBootHook.c | |
30 | * DiskImages | |
31 | * | |
32 | * Created by Byron Han on Sat Apr 13 2002. | |
9bccf70c A |
33 | * |
34 | * Revision History | |
35 | * | |
36 | * $Log: DINetBootHook.cpp,v $ | |
2d21ac55 A |
37 | * Revision 1.4 2005/07/29 21:49:57 lindak |
38 | * Merge of branch "chardonnay" to pick up all chardonnay changes in Leopard | |
39 | * as of xnu-792.7.4 | |
40 | * | |
0c530ab8 A |
41 | * Revision 1.3.1558.1 2005/06/24 01:47:25 lindak |
42 | * Bringing over all of the Karma changes into chardonnay. | |
2d21ac55 | 43 | * |
0c530ab8 A |
44 | * Revision 1.1.1.1 2005/02/24 21:48:06 akosut |
45 | * Import xnu-764 from Tiger8A395 | |
46 | * | |
9bccf70c A |
47 | * Revision 1.3 2002/06/16 20:36:02 lindak |
48 | * Merged PR-2957314 into Jaguar (siegmund: netboot kernel code needs to set | |
49 | * com.apple.AppleDiskImageController.load to boolean Yes) | |
0c530ab8 | 50 | * |
9bccf70c A |
51 | * Revision 1.2.40.2 2002/06/15 03:50:38 dieter |
52 | * - corrected com.apple.AppleDiskImageController.load string | |
53 | * | |
54 | * Revision 1.2.40.1 2002/06/15 03:01:08 dieter | |
55 | * Bug #: 2957314 | |
56 | * - add call to force IOHDIXController to get loaded/matched | |
57 | * | |
58 | * Revision 1.2 2002/05/03 18:08:39 lindak | |
59 | * Merged PR-2909558 into Jaguar (siegmund POST WWDC: add support for NetBoot | |
60 | * over IOHDIXController) | |
61 | * | |
62 | * Revision 1.1.2.1 2002/04/24 22:29:12 dieter | |
63 | * Bug #: 2909558 | |
64 | * - added IOHDIXController netboot stubs | |
65 | * | |
66 | * Revision 1.3 2002/04/16 00:41:37 han | |
67 | * migrated code out of here to IOHDIXController's setProperty method | |
68 | * | |
69 | * Revision 1.2 2002/04/14 23:53:53 han | |
70 | * eliminate qDEBUG=1, use emums instead of hard coded string constants | |
71 | * | |
72 | * Revision 1.1 2002/04/14 22:54:42 han | |
73 | * Renamed from DINetBookHook.c. | |
74 | * First stab at implementing this code. | |
75 | * | |
76 | * Revision 1.1 2002/04/13 19:22:28 han | |
77 | * added stub file DINetBookHook.c | |
78 | * | |
79 | * | |
80 | */ | |
81 | #ifndef qDEBUG | |
82 | #define qDEBUG 0 | |
83 | #endif | |
84 | ||
85 | #if qDEBUG | |
86 | #warning qDEBUG is 1! | |
87 | #endif | |
88 | ||
89 | #include <sys/types.h> | |
90 | #include <IOKit/IOService.h> | |
91 | #include <IOKit/IOLib.h> | |
92 | ||
93 | #define kIOHDIXControllerClassName "IOHDIXController" | |
94 | #define kDIRootImageKey "di-root-image" | |
95 | #define kDIRootImageResultKey "di-root-image-result" | |
96 | #define kDIRootImageDevNameKey "di-root-image-devname" | |
97 | #define kDIRootImageDevTKey "di-root-image-devt" | |
6d2010ae A |
98 | #define kDIRootRamFileKey "di-root-ram-file" |
99 | ||
100 | static IOService * | |
101 | di_load_controller( void ) | |
102 | { | |
103 | OSIterator * controllerIterator = 0; | |
104 | OSDictionary * matchDictionary = 0; | |
105 | IOService * controller = 0; | |
106 | ||
107 | do { | |
108 | IOService::getResourceService()->publishResource("com.apple.AppleDiskImageController.load", kOSBooleanTrue); | |
109 | IOService::getResourceService()->waitQuiet(); | |
110 | ||
111 | // first find IOHDIXController | |
112 | matchDictionary = IOService::serviceMatching(kIOHDIXControllerClassName); | |
113 | if (!matchDictionary) | |
114 | break; | |
115 | ||
116 | controllerIterator = IOService::getMatchingServices(matchDictionary); | |
117 | if (!controllerIterator) | |
118 | break; | |
119 | ||
120 | controller = OSDynamicCast(IOService, controllerIterator->getNextObject()); | |
121 | if (!controller) | |
122 | break; | |
123 | ||
124 | controller->retain(); | |
125 | } while (false); | |
126 | ||
127 | if (matchDictionary) matchDictionary->release(); | |
128 | if (controllerIterator) controllerIterator->release(); | |
129 | ||
130 | return controller; | |
131 | } | |
9bccf70c A |
132 | |
133 | extern "C" { | |
134 | /* | |
135 | Name: di_root_image | |
136 | Function: mount the disk image returning the dev node | |
137 | Parameters: path -> path/url to disk image | |
138 | devname <- dev node used to set the rootdevice global variable | |
139 | dev_p <- device number generated from major/minor numbers | |
140 | Comments: | |
141 | */ | |
142 | int di_root_image(const char *path, char devname[], dev_t *dev_p) | |
143 | { | |
144 | IOReturn res = 0; | |
9bccf70c A |
145 | IOService * controller = 0; |
146 | OSString * pathString = 0; | |
147 | OSNumber * myResult = 0; | |
148 | OSString * myDevName = 0; | |
149 | OSNumber * myDevT = 0; | |
150 | ||
151 | // sanity check arguments please | |
152 | if (devname) *devname = 0; | |
153 | if (dev_p) *dev_p = 0; | |
154 | ||
155 | if (!path) return kIOReturnBadArgument; | |
156 | if (!devname) return kIOReturnBadArgument; | |
157 | if (!dev_p) return kIOReturnBadArgument; | |
158 | ||
6d2010ae | 159 | controller = di_load_controller(); |
9bccf70c A |
160 | if (!controller) { |
161 | res = kIOReturnNotFound; | |
162 | goto NoIOHDIXController; | |
163 | } | |
164 | ||
165 | // okay create path object | |
166 | pathString = OSString::withCString(path); | |
167 | if (!pathString) { | |
168 | res = kIOReturnNoMemory; | |
169 | goto CannotCreatePathOSString; | |
170 | } | |
171 | ||
172 | // do it | |
173 | if (!controller->setProperty(kDIRootImageKey, pathString)) | |
174 | IOLog("IOHDIXController::setProperty(%s, %s) failed.\n", kDIRootImageKey, pathString->getCStringNoCopy()); | |
175 | ||
176 | myResult = OSDynamicCast(OSNumber, controller->getProperty(kDIRootImageResultKey)); | |
177 | res = kIOReturnError; | |
178 | if (myResult) | |
179 | res = myResult->unsigned32BitValue(); | |
180 | ||
181 | if (res) { | |
182 | IOLog("%s is 0x%08X/%d\n", kDIRootImageResultKey, res, res); | |
183 | goto di_root_image_FAILED; | |
184 | } | |
185 | ||
186 | // success - grab | |
187 | myDevT = OSDynamicCast(OSNumber, controller->getProperty(kDIRootImageDevTKey)); | |
188 | if (myDevT) | |
189 | *dev_p = myDevT->unsigned32BitValue(); | |
190 | else { | |
191 | IOLog("could not get %s\n", kDIRootImageDevTKey); | |
192 | res = kIOReturnError; | |
193 | goto di_root_image_FAILED; | |
194 | } | |
195 | ||
196 | myDevName = OSDynamicCast(OSString, controller->getProperty(kDIRootImageDevNameKey)); | |
2d21ac55 A |
197 | if (myDevName) { |
198 | /* rootdevice is 16 chars in bsd_init.c */ | |
199 | strlcpy(devname, myDevName->getCStringNoCopy(), 16); | |
200 | } else { | |
9bccf70c A |
201 | IOLog("could not get %s\n", kDIRootImageDevNameKey); |
202 | res = kIOReturnError; | |
203 | goto di_root_image_FAILED; | |
204 | } | |
205 | ||
206 | ||
207 | di_root_image_FAILED: | |
208 | CannotCreatePathOSString: | |
9bccf70c | 209 | NoIOHDIXController: |
9bccf70c A |
210 | |
211 | // clean up memory allocations | |
212 | if (pathString) pathString->release(); | |
6d2010ae | 213 | if (controller) controller->release(); |
9bccf70c A |
214 | |
215 | return res; | |
216 | } | |
217 | ||
6d2010ae A |
218 | void di_root_ramfile( IORegistryEntry * entry ) |
219 | { | |
220 | OSData * data; | |
221 | IOMemoryDescriptor * mem; | |
222 | uint64_t dmgSize; | |
223 | uint64_t remain, length; | |
224 | OSData * extentData = 0; | |
225 | IOAddressRange * extentList; | |
226 | uint64_t extentSize; | |
227 | uint32_t extentCount; | |
228 | ||
229 | do { | |
230 | data = OSDynamicCast(OSData, entry->getProperty("boot-ramdmg-size")); | |
231 | if (!data || (data->getLength() != sizeof(uint64_t))) | |
232 | break; // bad disk image size | |
233 | ||
234 | dmgSize = *(uint64_t *) data->getBytesNoCopy(); | |
235 | if (!dmgSize) | |
236 | break; | |
237 | ||
238 | data = OSDynamicCast(OSData, entry->getProperty("boot-ramdmg-extents")); | |
239 | if (!data || (data->getLength() == 0) || | |
240 | ((data->getLength() & (sizeof(IOAddressRange)-1)) != 0)) | |
241 | break; // bad extents | |
242 | ||
243 | // make modifications to local copy | |
244 | extentData = OSData::withData(data); | |
245 | assert(extentData); | |
246 | ||
247 | extentList = (IOAddressRange *) extentData->getBytesNoCopy(); | |
248 | extentCount = extentData->getLength() / sizeof(IOAddressRange); | |
249 | extentSize = 0; | |
250 | remain = dmgSize; | |
251 | ||
252 | // truncate extent length to enclosing disk image | |
253 | for (uint32_t i = 0; i < extentCount; i++) | |
254 | { | |
255 | length = extentList[i].length; | |
256 | if (!length) break; | |
257 | ||
258 | extentSize += length; | |
259 | if (length >= remain) | |
260 | { | |
261 | extentList[i].length = remain; | |
262 | extentCount = i + 1; | |
263 | break; | |
264 | } | |
265 | remain -= length; | |
266 | } | |
267 | if (extentSize < dmgSize) | |
268 | break; // not enough extent bytes for enclosing disk image | |
269 | ||
270 | mem = IOMemoryDescriptor::withAddressRanges( | |
271 | extentList, extentCount, | |
272 | kIODirectionOut | kIOMemoryMapperNone, NULL); | |
273 | ||
274 | if (mem) | |
275 | { | |
276 | IOService * controller = di_load_controller(); | |
277 | if (controller) | |
278 | { | |
279 | controller->setProperty(kDIRootRamFileKey, mem); | |
280 | controller->release(); | |
281 | } | |
282 | mem->release(); | |
283 | } | |
284 | } while (false); | |
285 | ||
286 | if (extentData) | |
287 | extentData->release(); | |
288 | } | |
289 | ||
9bccf70c | 290 | }; |