]> git.saurik.com Git - apple/xnu.git/blame - iokit/bsddev/IOKitBSDInit.cpp
xnu-1228.tar.gz
[apple/xnu.git] / iokit / bsddev / IOKitBSDInit.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
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.
8f6c56a5 14 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28#include <IOKit/IOBSD.h>
29#include <IOKit/IOLib.h>
30#include <IOKit/IOService.h>
31#include <IOKit/IODeviceTreeSupport.h>
32#include <IOKit/IOKitKeys.h>
1c79356b
A
33#include <IOKit/IOPlatformExpert.h>
34
1c79356b
A
35extern "C" {
36
37#include <pexpert/pexpert.h>
38#include <kern/clock.h>
2d21ac55 39#include <uuid/uuid.h>
1c79356b
A
40
41// how long to wait for matching root device, secs
42#define ROOTDEVICETIMEOUT 60
43
55e303ae
A
44extern dev_t mdevadd(int devid, ppnum_t base, unsigned int size, int phys);
45extern dev_t mdevlookup(int devid);
1c79356b
A
46
47kern_return_t
48IOKitBSDInit( void )
49{
1c79356b
A
50 IOService::publishResource("IOBSD");
51
52 return( kIOReturnSuccess );
53}
54
55OSDictionary * IOBSDNameMatching( const char * name )
56{
57 OSDictionary * dict;
58 const OSSymbol * str = 0;
59
60 do {
61
62 dict = IOService::serviceMatching( gIOServiceKey );
63 if( !dict)
64 continue;
65 str = OSSymbol::withCString( name );
66 if( !str)
67 continue;
68 dict->setObject( kIOBSDNameKey, (OSObject *) str );
69 str->release();
70
71 return( dict );
72
73 } while( false );
74
75 if( dict)
76 dict->release();
77 if( str)
78 str->release();
79
80 return( 0 );
81}
82
91447636
A
83OSDictionary * IOUUIDMatching( void )
84{
85 return IOService::resourceMatching( "boot-uuid-media" );
86}
87
88
55e303ae 89OSDictionary * IOCDMatching( void )
0b4e3aa0
A
90{
91 OSDictionary * dict;
92 const OSSymbol * str;
55e303ae
A
93
94 dict = IOService::serviceMatching( "IOMedia" );
95 if( dict == 0 ) {
96 IOLog("Unable to find IOMedia\n");
97 return 0;
98 }
99
100 str = OSSymbol::withCString( "CD_ROM_Mode_1" );
101 if( str == 0 ) {
102 dict->release();
103 return 0;
104 }
105
106 dict->setObject( "Content Hint", (OSObject *)str );
107 str->release();
108 return( dict );
0b4e3aa0
A
109}
110
1c79356b
A
111OSDictionary * IONetworkMatching( const char * path,
112 char * buf, int maxLen )
113{
114 OSDictionary * matching = 0;
115 OSDictionary * dict;
116 OSString * str;
117 char * comp;
118 const char * skip;
119 int len;
120
121 do {
122
123 len = strlen( kIODeviceTreePlane ":" );
124 maxLen -= len;
125 if( maxLen < 0)
126 continue;
127
128 strcpy( buf, kIODeviceTreePlane ":" );
129 comp = buf + len;
130
131 // remove parameters following ':' from the path
132 skip = strchr( path, ':');
133 if( !skip)
134 continue;
135
136 len = skip - path;
137 maxLen -= len;
138 if( maxLen < 0)
139 continue;
140 strncpy( comp, path, len );
141 comp[ len ] = 0;
142
143 matching = IOService::serviceMatching( "IONetworkInterface" );
144 if( !matching)
145 continue;
146 dict = IOService::addLocation( matching );
147 if( !dict)
148 continue;
149
150 str = OSString::withCString( buf );
151 if( !str)
152 continue;
153 dict->setObject( kIOPathMatchKey, str );
154 str->release();
155
156 return( matching );
157
158 } while( false );
159
160 if( matching)
161 matching->release();
162
163 return( 0 );
164}
165
166OSDictionary * IONetworkNamePrefixMatching( const char * prefix )
167{
168 OSDictionary * matching;
169 OSDictionary * propDict = 0;
170 const OSSymbol * str = 0;
2d21ac55
A
171 char networkType[128];
172
1c79356b
A
173 do {
174 matching = IOService::serviceMatching( "IONetworkInterface" );
175 if ( matching == 0 )
176 continue;
177
178 propDict = OSDictionary::withCapacity(1);
179 if ( propDict == 0 )
180 continue;
181
182 str = OSSymbol::withCString( prefix );
183 if ( str == 0 )
184 continue;
185
0b4e3aa0 186 propDict->setObject( "IOInterfaceNamePrefix", (OSObject *) str );
1c79356b
A
187 str->release();
188 str = 0;
189
2d21ac55
A
190 // see if we're contrained to netroot off of specific network type
191 if(PE_parse_boot_argn( "network-type", networkType, 128 ))
192 {
193 str = OSSymbol::withCString( networkType );
194 if(str)
195 {
196 propDict->setObject( "IONetworkRootType", str);
197 str->release();
198 str = 0;
199 }
200 }
201
1c79356b
A
202 if ( matching->setObject( gIOPropertyMatchKey,
203 (OSObject *) propDict ) != true )
204 continue;
205
206 propDict->release();
207 propDict = 0;
208
209 return( matching );
210
211 } while ( false );
212
213 if ( matching ) matching->release();
214 if ( propDict ) propDict->release();
215 if ( str ) str->release();
216
217 return( 0 );
218}
219
0b4e3aa0 220static bool IORegisterNetworkInterface( IOService * netif )
1c79356b 221{
0b4e3aa0
A
222 // A network interface is typically named and registered
223 // with BSD after receiving a request from a user space
224 // "namer". However, for cases when the system needs to
225 // root from the network, this registration task must be
226 // done inside the kernel and completed before the root
227 // device is handed to BSD.
228
229 IOService * stack;
230 OSNumber * zero = 0;
231 OSString * path = 0;
232 OSDictionary * dict = 0;
233 char * pathBuf = 0;
234 int len;
235 enum { kMaxPathLen = 512 };
1c79356b 236
0b4e3aa0
A
237 do {
238 stack = IOService::waitForService(
239 IOService::serviceMatching("IONetworkStack") );
240 if ( stack == 0 ) break;
1c79356b 241
0b4e3aa0
A
242 dict = OSDictionary::withCapacity(3);
243 if ( dict == 0 ) break;
1c79356b 244
0b4e3aa0
A
245 zero = OSNumber::withNumber((UInt64) 0, 32);
246 if ( zero == 0 ) break;
1c79356b 247
0b4e3aa0
A
248 pathBuf = (char *) IOMalloc( kMaxPathLen );
249 if ( pathBuf == 0 ) break;
250
251 len = kMaxPathLen;
252 if ( netif->getPath( pathBuf, &len, gIOServicePlane )
253 == false ) break;
254
255 path = OSString::withCStringNoCopy( pathBuf );
256 if ( path == 0 ) break;
257
258 dict->setObject( "IOInterfaceUnit", zero );
259 dict->setObject( kIOPathMatchKey, path );
260
261 stack->setProperties( dict );
262 }
263 while ( false );
264
265 if ( zero ) zero->release();
266 if ( path ) path->release();
267 if ( dict ) dict->release();
268 if ( pathBuf ) IOFree(pathBuf, kMaxPathLen);
269
270 return ( netif->getProperty( kIOBSDNameKey ) != 0 );
1c79356b
A
271}
272
273OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen )
274{
275 const char * look;
276 const char * alias;
277 char * comp;
278 long unit = -1;
279 long partition = -1;
55e303ae 280 long lun = -1;
1c79356b
A
281 char c;
282
283 // scan the tail of the path for "@unit:partition"
284 do {
285 // Have to get the full path to the controller - an alias may
286 // tell us next to nothing, like "hd:8"
287 alias = IORegistryEntry::dealiasPath( &path, gIODTPlane );
55e303ae 288
1c79356b
A
289 look = path + strlen( path);
290 c = ':';
291 while( look != path) {
292 if( *(--look) == c) {
293 if( c == ':') {
294 partition = strtol( look + 1, 0, 0 );
295 c = '@';
296 } else if( c == '@') {
91447636
A
297 unit = strtol( look + 1, &comp, 16 );
298
299 if( *comp == ',') {
300 lun = strtol( comp + 1, 0, 16 );
55e303ae
A
301 }
302
1c79356b
A
303 c = '/';
304 } else if( c == '/') {
305 c = 0;
306 break;
307 }
308 }
309
310 if( alias && (look == path)) {
311 path = alias;
312 look = path + strlen( path);
313 alias = 0;
314 }
315 }
316 if( c || unit == -1 || partition == -1)
317 continue;
55e303ae 318
1c79356b
A
319 maxLen -= strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
320 maxLen -= ( alias ? strlen( alias ) : 0 ) + (look - path);
55e303ae 321 maxLen -= strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" );
1c79356b
A
322
323 if( maxLen > 0) {
324 sprintf( buf, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
325 comp = buf + strlen( buf );
55e303ae 326
1c79356b
A
327 if( alias) {
328 strcpy( comp, alias );
329 comp += strlen( alias );
330 }
55e303ae 331
1c79356b
A
332 if ( (look - path)) {
333 strncpy( comp, path, look - path);
334 comp += look - path;
335 }
55e303ae
A
336
337 if ( lun != -1 )
338 {
339 sprintf ( comp, "/@%lx,%lx:%ld';}", unit, lun, partition );
340 }
341 else
342 {
343 sprintf( comp, "/@%lx:%ld';}", unit, partition );
344 }
1c79356b
A
345 } else
346 continue;
55e303ae 347
1c79356b
A
348 return( OSDynamicCast(OSDictionary, OSUnserialize( buf, 0 )) );
349
350 } while( false );
351
352 return( 0 );
353}
354
355OSDictionary * IOOFPathMatching( const char * path, char * buf, int maxLen )
356{
91447636
A
357 OSDictionary * matching;
358 OSString * str;
359 char * comp;
360 int len;
361
1c79356b
A
362 /* need to look up path, get device type,
363 call matching help based on device type */
364
91447636
A
365 matching = IODiskMatching( path, buf, maxLen );
366 if( matching)
367 return( matching );
368
369 do {
370
371 len = strlen( kIODeviceTreePlane ":" );
372 maxLen -= len;
373 if( maxLen < 0)
374 continue;
375
376 strcpy( buf, kIODeviceTreePlane ":" );
377 comp = buf + len;
378
379 len = strlen( path );
380 maxLen -= len;
381 if( maxLen < 0)
382 continue;
383 strncpy( comp, path, len );
384 comp[ len ] = 0;
385
386 matching = OSDictionary::withCapacity( 1 );
387 if( !matching)
388 continue;
389
390 str = OSString::withCString( buf );
391 if( !str)
392 continue;
393 matching->setObject( kIOPathMatchKey, str );
394 str->release();
395
396 return( matching );
397
398 } while( false );
1c79356b 399
91447636
A
400 if( matching)
401 matching->release();
402
403 return( 0 );
1c79356b
A
404}
405
55e303ae
A
406IOService * IOFindMatchingChild( IOService * service )
407{
408 // find a matching child service
409 IOService * child = 0;
410 OSIterator * iter = service->getClientIterator();
411 if ( iter ) {
412 while( ( child = (IOService *) iter->getNextObject() ) ) {
413 OSDictionary * dict = OSDictionary::withCapacity( 1 );
414 if( dict == 0 ) {
415 iter->release();
416 return 0;
417 }
418 const OSSymbol * str = OSSymbol::withCString( "Apple_HFS" );
419 if( str == 0 ) {
420 dict->release();
421 iter->release();
422 return 0;
423 }
424 dict->setObject( "Content", (OSObject *)str );
425 str->release();
426 if ( child->compareProperty( dict, "Content" ) ) {
427 dict->release();
428 break;
429 }
430 dict->release();
431 IOService * subchild = IOFindMatchingChild( child );
432 if ( subchild ) {
433 child = subchild;
434 break;
435 }
436 }
437 iter->release();
438 }
439 return child;
440}
441
442static int didRam = 0;
443
1c79356b
A
444kern_return_t IOFindBSDRoot( char * rootName,
445 dev_t * root, u_int32_t * oflags )
446{
447 mach_timespec_t t;
448 IOService * service;
449 IORegistryEntry * regEntry;
450 OSDictionary * matching = 0;
451 OSString * iostr;
452 OSNumber * off;
453 OSData * data = 0;
55e303ae 454 UInt32 *ramdParms = 0;
1c79356b
A
455
456 UInt32 flags = 0;
2d21ac55 457 int mnr, mjr;
55e303ae 458 bool findHFSChild = false;
91447636 459 char * mediaProperty = 0;
1c79356b
A
460 char * rdBootVar;
461 enum { kMaxPathBuf = 512, kMaxBootVar = 128 };
462 char * str;
463 const char * look = 0;
464 int len;
465 bool forceNet = false;
0b4e3aa0 466 bool debugInfoPrintedOnce = false;
91447636 467 const char * uuidStr = NULL;
1c79356b
A
468
469 static int mountAttempts = 0;
55e303ae 470
91447636 471 int xchar, dchar;
55e303ae 472
1c79356b
A
473
474 if( mountAttempts++)
475 IOSleep( 5 * 1000 );
476
477 str = (char *) IOMalloc( kMaxPathBuf + kMaxBootVar );
478 if( !str)
479 return( kIOReturnNoMemory );
480 rdBootVar = str + kMaxPathBuf;
481
2d21ac55
A
482 if (!PE_parse_boot_argn("rd", rdBootVar, kMaxBootVar )
483 && !PE_parse_boot_argn("rootdev", rdBootVar, kMaxBootVar ))
1c79356b
A
484 rdBootVar[0] = 0;
485
486 do {
91447636 487 if( (regEntry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ))) {
0c530ab8
A
488 data = OSDynamicCast(OSData, regEntry->getProperty( "root-matching" ));
489 if (data) {
490 matching = OSDynamicCast(OSDictionary, OSUnserializeXML((char *)data->getBytesNoCopy()));
491 if (matching) {
492 continue;
493 }
494 }
495
91447636
A
496 data = (OSData *) regEntry->getProperty( "boot-uuid" );
497 if( data) {
498 uuidStr = (const char*)data->getBytesNoCopy();
499 OSString *uuidString = OSString::withCString( uuidStr );
500
501 // match the boot-args boot-uuid processing below
502 if( uuidString) {
503 IOLog("rooting via boot-uuid from /chosen: %s\n", uuidStr);
504 IOService::publishResource( "boot-uuid", uuidString );
505 uuidString->release();
506 matching = IOUUIDMatching();
507 mediaProperty = "boot-uuid-media";
508 regEntry->release();
509 continue;
510 } else {
511 uuidStr = NULL;
55e303ae 512 }
91447636
A
513 }
514
515 // else try for an OF Path
516 data = (OSData *) regEntry->getProperty( "rootpath" );
517 regEntry->release();
518 if( data) continue;
519 }
1c79356b 520 if( (regEntry = IORegistryEntry::fromPath( "/options", gIODTPlane ))) {
91447636
A
521 data = (OSData *) regEntry->getProperty( "boot-file" );
522 regEntry->release();
523 if( data) continue;
524 }
1c79356b
A
525 } while( false );
526
91447636 527 if( data && !uuidStr)
1c79356b
A
528 look = (const char *) data->getBytesNoCopy();
529
530 if( rdBootVar[0] == '*') {
531 look = rdBootVar + 1;
55e303ae 532 forceNet = false;
1c79356b
A
533 } else {
534 if( (regEntry = IORegistryEntry::fromPath( "/", gIODTPlane ))) {
535 forceNet = (0 != regEntry->getProperty( "net-boot" ));
55e303ae
A
536 regEntry->release();
537 }
de355530 538 }
d7e50217 539
55e303ae
A
540
541
542//
543// See if we have a RAMDisk property in /chosen/memory-map. If so, make it into a device.
544// It will become /dev/mdx, where x is 0-f.
545//
546
547 if(!didRam) { /* Have we already build this ram disk? */
548 didRam = 1; /* Remember we did this */
549 if((regEntry = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane ))) { /* Find the map node */
550 data = (OSData *)regEntry->getProperty("RAMDisk"); /* Find the ram disk, if there */
551 if(data) { /* We found one */
552
553 ramdParms = (UInt32 *)data->getBytesNoCopy(); /* Point to the ram disk base and size */
554 (void)mdevadd(-1, ramdParms[0] >> 12, ramdParms[1] >> 12, 0); /* Initialize it and pass back the device number */
555 }
556 regEntry->release(); /* Toss the entry */
557 }
558 }
559
560//
561// Now check if we are trying to root on a memory device
562//
563
564 if((rdBootVar[0] == 'm') && (rdBootVar[1] == 'd') && (rdBootVar[3] == 0)) {
565 dchar = xchar = rdBootVar[2]; /* Get the actual device */
566 if((xchar >= '0') && (xchar <= '9')) xchar = xchar - '0'; /* If digit, convert */
567 else {
568 xchar = xchar & ~' '; /* Fold to upper case */
569 if((xchar >= 'A') && (xchar <= 'F')) { /* Is this a valid digit? */
570 xchar = (xchar & 0xF) + 9; /* Convert the hex digit */
571 dchar = dchar | ' '; /* Fold to lower case */
572 }
573 else xchar = -1; /* Show bogus */
574 }
575 if(xchar >= 0) { /* Do we have a valid memory device name? */
576 *root = mdevlookup(xchar); /* Find the device number */
577 if(*root >= 0) { /* Did we find one? */
578
579 rootName[0] = 'm'; /* Build root name */
580 rootName[1] = 'd'; /* Build root name */
581 rootName[2] = dchar; /* Build root name */
582 rootName[3] = 0; /* Build root name */
583 IOLog("BSD root: %s, major %d, minor %d\n", rootName, major(*root), minor(*root));
584 *oflags = 0; /* Show that this is not network */
585 goto iofrootx; /* Join common exit... */
586 }
587 panic("IOFindBSDRoot: specified root memory device, %s, has not been configured\n", rdBootVar); /* Not there */
588 }
589 }
590
1c79356b
A
591 if( look) {
592 // from OpenFirmware path
593 IOLog("From path: \"%s\", ", look);
594
0c530ab8
A
595 if (!matching) {
596 if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) ) {
597 matching = IONetworkMatching( look, str, kMaxPathBuf );
598 } else {
599 matching = IODiskMatching( look, str, kMaxPathBuf );
600 }
0b4e3aa0 601 }
1c79356b 602 }
55e303ae
A
603
604 if( (!matching) && rdBootVar[0] ) {
1c79356b
A
605 // by BSD name
606 look = rdBootVar;
607 if( look[0] == '*')
608 look++;
609
0b4e3aa0
A
610 if ( strncmp( look, "en", strlen( "en" )) == 0 ) {
611 matching = IONetworkNamePrefixMatching( "en" );
55e303ae
A
612 } else if ( strncmp( look, "cdrom", strlen( "cdrom" )) == 0 ) {
613 matching = IOCDMatching();
614 findHFSChild = true;
91447636
A
615 } else if ( strncmp( look, "uuid", strlen( "uuid" )) == 0 ) {
616 char *uuid;
617 OSString *uuidString;
618
619 uuid = (char *)IOMalloc( kMaxBootVar );
620
621 if ( uuid ) {
2d21ac55 622 if (!PE_parse_boot_argn( "boot-uuid", uuid, kMaxBootVar )) {
91447636
A
623 panic( "rd=uuid but no boot-uuid=<value> specified" );
624 }
625 uuidString = OSString::withCString( uuid );
626 if ( uuidString ) {
627 IOService::publishResource( "boot-uuid", uuidString );
628 uuidString->release();
629 IOLog( "\nWaiting for boot volume with UUID %s\n", uuid );
630 matching = IOUUIDMatching();
631 mediaProperty = "boot-uuid-media";
632 }
633 IOFree( uuid, kMaxBootVar );
634 }
0b4e3aa0
A
635 } else {
636 matching = IOBSDNameMatching( look );
637 }
1c79356b
A
638 }
639
640 if( !matching) {
2d21ac55
A
641 OSString * astring;
642 // Match any HFS media
643
1c79356b 644 matching = IOService::serviceMatching( "IOMedia" );
55e303ae 645 astring = OSString::withCStringNoCopy("Apple_HFS");
1c79356b 646 if ( astring ) {
0b4e3aa0 647 matching->setObject("Content", astring);
1c79356b
A
648 astring->release();
649 }
650 }
651
652 if( true && matching) {
653 OSSerialize * s = OSSerialize::withCapacity( 5 );
654
655 if( matching->serialize( s )) {
656 IOLog( "Waiting on %s\n", s->text() );
657 s->release();
658 }
659 }
660
1c79356b
A
661 do {
662 t.tv_sec = ROOTDEVICETIMEOUT;
663 t.tv_nsec = 0;
664 matching->retain();
665 service = IOService::waitForService( matching, &t );
666 if( (!service) || (mountAttempts == 10)) {
667 PE_display_icon( 0, "noroot");
668 IOLog( "Still waiting for root device\n" );
0b4e3aa0
A
669
670 if( !debugInfoPrintedOnce) {
671 debugInfoPrintedOnce = true;
672 if( gIOKitDebug & kIOLogDTree) {
673 IOLog("\nDT plane:\n");
674 IOPrintPlane( gIODTPlane );
675 }
676 if( gIOKitDebug & kIOLogServiceTree) {
677 IOLog("\nService plane:\n");
678 IOPrintPlane( gIOServicePlane );
679 }
680 if( gIOKitDebug & kIOLogMemory)
681 IOPrintMemory();
682 }
1c79356b
A
683 }
684 } while( !service);
685 matching->release();
686
55e303ae
A
687 if ( service && findHFSChild ) {
688 bool waiting = true;
689 // wait for children services to finish registering
690 while ( waiting ) {
691 t.tv_sec = ROOTDEVICETIMEOUT;
692 t.tv_nsec = 0;
693 if ( service->waitQuiet( &t ) == kIOReturnSuccess ) {
694 waiting = false;
695 } else {
696 IOLog( "Waiting for child registration\n" );
697 }
698 }
699 // look for a subservice with an Apple_HFS child
700 IOService * subservice = IOFindMatchingChild( service );
701 if ( subservice ) service = subservice;
91447636 702 } else if ( service && mediaProperty ) {
0c530ab8 703 service = (IOService *)service->getProperty(mediaProperty);
55e303ae
A
704 }
705
2d21ac55
A
706 mjr = 0;
707 mnr = 0;
1c79356b
A
708
709 // If the IOService we matched to is a subclass of IONetworkInterface,
710 // then make sure it has been registered with BSD and has a BSD name
711 // assigned.
712
713 if ( service
714 && service->metaCast( "IONetworkInterface" )
0b4e3aa0 715 && !IORegisterNetworkInterface( service ) )
1c79356b
A
716 {
717 service = 0;
718 }
1c79356b
A
719
720 if( service) {
721
722 len = kMaxPathBuf;
723 service->getPath( str, &len, gIOServicePlane );
724 IOLog( "Got boot device = %s\n", str );
725
726 iostr = (OSString *) service->getProperty( kIOBSDNameKey );
727 if( iostr)
728 strcpy( rootName, iostr->getCStringNoCopy() );
729 off = (OSNumber *) service->getProperty( kIOBSDMajorKey );
730 if( off)
2d21ac55 731 mjr = off->unsigned32BitValue();
1c79356b
A
732 off = (OSNumber *) service->getProperty( kIOBSDMinorKey );
733 if( off)
2d21ac55 734 mnr = off->unsigned32BitValue();
1c79356b
A
735
736 if( service->metaCast( "IONetworkInterface" ))
737 flags |= 1;
738
739 } else {
740
741 IOLog( "Wait for root failed\n" );
742 strcpy( rootName, "en0");
743 flags |= 1;
744 }
745
746 IOLog( "BSD root: %s", rootName );
2d21ac55
A
747 if( mjr)
748 IOLog(", major %d, minor %d\n", mjr, mnr );
1c79356b
A
749 else
750 IOLog("\n");
751
2d21ac55 752 *root = makedev( mjr, mnr );
1c79356b
A
753 *oflags = flags;
754
755 IOFree( str, kMaxPathBuf + kMaxBootVar );
756
55e303ae 757iofrootx:
0b4e3aa0 758 if( (gIOKitDebug & (kIOLogDTree | kIOLogServiceTree | kIOLogMemory)) && !debugInfoPrintedOnce) {
1c79356b 759
0b4e3aa0 760 IOService::getPlatform()->waitQuiet();
1c79356b
A
761 if( gIOKitDebug & kIOLogDTree) {
762 IOLog("\nDT plane:\n");
763 IOPrintPlane( gIODTPlane );
764 }
765 if( gIOKitDebug & kIOLogServiceTree) {
766 IOLog("\nService plane:\n");
767 IOPrintPlane( gIOServicePlane );
768 }
769 if( gIOKitDebug & kIOLogMemory)
770 IOPrintMemory();
771 }
772
773 return( kIOReturnSuccess );
774}
775
2d21ac55
A
776void IOSecureBSDRoot(const char * rootName)
777{
778#if CONFIG_EMBEDDED
779 IOPlatformExpert *pe;
780 const OSSymbol *functionName = OSSymbol::withCStringNoCopy("SecureRootName");
781
782 while ((pe = IOService::getPlatform()) == 0) IOSleep(1 * 1000);
783
784 pe->callPlatformFunction(functionName, false, (void *)rootName, (void *)0, (void *)0, (void *)0);
785
786 functionName->release();
787#endif
788}
789
9bccf70c
A
790void *
791IOBSDRegistryEntryForDeviceTree(char * path)
792{
793 return (IORegistryEntry::fromPath(path, gIODTPlane));
794}
795
796void
797IOBSDRegistryEntryRelease(void * entry)
798{
799 IORegistryEntry * regEntry = (IORegistryEntry *)entry;
800
801 if (regEntry)
802 regEntry->release();
803 return;
804}
805
806const void *
807IOBSDRegistryEntryGetData(void * entry, char * property_name,
808 int * packet_length)
809{
810 OSData * data;
811 IORegistryEntry * regEntry = (IORegistryEntry *)entry;
812
813 data = (OSData *) regEntry->getProperty(property_name);
814 if (data) {
815 *packet_length = data->getLength();
816 return (data->getBytesNoCopy());
817 }
818 return (NULL);
819}
820
2d21ac55
A
821kern_return_t IOBSDGetPlatformUUID( uuid_t uuid, mach_timespec_t timeout )
822{
823 IOService * resources;
824 OSString * string;
825
826 resources = IOService::waitForService( IOService::resourceMatching( kIOPlatformUUIDKey ), &timeout );
827 if ( resources == 0 ) return KERN_OPERATION_TIMED_OUT;
828
829 string = ( OSString * ) IOService::getPlatform( )->getProvider( )->getProperty( kIOPlatformUUIDKey );
830 if ( string == 0 ) return KERN_NOT_SUPPORTED;
831
832 uuid_parse( string->getCStringNoCopy( ), uuid );
833
834 return KERN_SUCCESS;
835}
836
1c79356b 837} /* extern "C" */