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