1 /* 2 * Copyright (c) 1998-2000 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 */ 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> 33 #include <IOKit/IOPlatformExpert.h> 34 35 extern "C" { 36 37 #include <pexpert/pexpert.h> 38 #include <kern/clock.h> 39 #include <uuid/uuid.h> 40 41 // how long to wait for matching root device, secs 42 #define ROOTDEVICETIMEOUT 60 43 44 extern dev_t mdevadd(int devid, ppnum_t base, unsigned int size, int phys); 45 extern dev_t mdevlookup(int devid); 46 47 kern_return_t 48 IOKitBSDInit( void ) 49 { 50 IOService::publishResource("IOBSD"); 51 52 return( kIOReturnSuccess ); 53 } 54 55 OSDictionary * 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 83 OSDictionary * IOUUIDMatching( void ) 84 { 85 return IOService::resourceMatching( "boot-uuid-media" ); 86 } 87 88 89 OSDictionary * IOCDMatching( void ) 90 { 91 OSDictionary * dict; 92 const OSSymbol * str; 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 ); 109 } 110 111 OSDictionary * 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 166 OSDictionary * IONetworkNamePrefixMatching( const char * prefix ) 167 { 168 OSDictionary * matching; 169 OSDictionary * propDict = 0; 170 const OSSymbol * str = 0; 171 char networkType[128]; 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 186 propDict->setObject( "IOInterfaceNamePrefix", (OSObject *) str ); 187 str->release(); 188 str = 0; 189 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 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 220 static bool IORegisterNetworkInterface( IOService * netif ) 221 { 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 }; 236 237 do { 238 stack = IOService::waitForService( 239 IOService::serviceMatching("IONetworkStack") ); 240 if ( stack == 0 ) break; 241 242 dict = OSDictionary::withCapacity(3); 243 if ( dict == 0 ) break; 244 245 zero = OSNumber::withNumber((UInt64) 0, 32); 246 if ( zero == 0 ) break; 247 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 ); 271 } 272 273 OSDictionary * 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; 280 long lun = -1; 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 ); 288 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 == '@') { 297 unit = strtol( look + 1, &comp, 16 ); 298 299 if( *comp == ',') { 300 lun = strtol( comp + 1, 0, 16 ); 301 } 302 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; 318 319 maxLen -= strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" ); 320 maxLen -= ( alias ? strlen( alias ) : 0 ) + (look - path); 321 maxLen -= strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" ); 322 323 if( maxLen > 0) { 324 sprintf( buf, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" ); 325 comp = buf + strlen( buf ); 326 327 if( alias) { 328 strcpy( comp, alias ); 329 comp += strlen( alias ); 330 } 331 332 if ( (look - path)) { 333 strncpy( comp, path, look - path); 334 comp += look - path; 335 } 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 } 345 } else 346 continue; 347 348 return( OSDynamicCast(OSDictionary, OSUnserialize( buf, 0 )) ); 349 350 } while( false ); 351 352 return( 0 ); 353 } 354 355 OSDictionary * IOOFPathMatching( const char * path, char * buf, int maxLen ) 356 { 357 OSDictionary * matching; 358 OSString * str; 359 char * comp; 360 int len; 361 362 /* need to look up path, get device type, 363 call matching help based on device type */ 364 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 ); 399 400 if( matching) 401 matching->release(); 402 403 return( 0 ); 404 } 405 406 IOService * 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 442 static int didRam = 0; 443 444 kern_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; 454 UInt32 *ramdParms = 0; 455 456 UInt32 flags = 0; 457 int mnr, mjr; 458 bool findHFSChild = false; 459 char * mediaProperty = 0; 460 char * rdBootVar; 461 enum { kMaxPathBuf = 512, kMaxBootVar = 128 }; 462 char * str; 463 const char * look = 0; 464 int len; 465 bool forceNet = false; 466 bool debugInfoPrintedOnce = false; 467 const char * uuidStr = NULL; 468 469 static int mountAttempts = 0; 470 471 int xchar, dchar; 472 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 482 if (!PE_parse_boot_argn("rd", rdBootVar, kMaxBootVar ) 483 && !PE_parse_boot_argn("rootdev", rdBootVar, kMaxBootVar )) 484 rdBootVar[0] = 0; 485 486 do { 487 if( (regEntry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ))) { 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 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; 512 } 513 } 514 515 // else try for an OF Path 516 data = (OSData *) regEntry->getProperty( "rootpath" ); 517 regEntry->release(); 518 if( data) continue; 519 } 520 if( (regEntry = IORegistryEntry::fromPath( "/options", gIODTPlane ))) { 521 data = (OSData *) regEntry->getProperty( "boot-file" ); 522 regEntry->release(); 523 if( data) continue; 524 } 525 } while( false ); 526 527 if( data && !uuidStr) 528 look = (const char *) data->getBytesNoCopy(); 529 530 if( rdBootVar[0] == '*') { 531 look = rdBootVar + 1; 532 forceNet = false; 533 } else { 534 if( (regEntry = IORegistryEntry::fromPath( "/", gIODTPlane ))) { 535 forceNet = (0 != regEntry->getProperty( "net-boot" )); 536 regEntry->release(); 537 } 538 } 539 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 591 if( look) { 592 // from OpenFirmware path 593 IOLog("From path: \"%s\", ", look); 594 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 } 601 } 602 } 603 604 if( (!matching) && rdBootVar[0] ) { 605 // by BSD name 606 look = rdBootVar; 607 if( look[0] == '*') 608 look++; 609 610 if ( strncmp( look, "en", strlen( "en" )) == 0 ) { 611 matching = IONetworkNamePrefixMatching( "en" ); 612 } else if ( strncmp( look, "cdrom", strlen( "cdrom" )) == 0 ) { 613 matching = IOCDMatching(); 614 findHFSChild = true; 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 ) { 622 if (!PE_parse_boot_argn( "boot-uuid", uuid, kMaxBootVar )) { 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 } 635 } else { 636 matching = IOBSDNameMatching( look ); 637 } 638 } 639 640 if( !matching) { 641 OSString * astring; 642 // Match any HFS media 643 644 matching = IOService::serviceMatching( "IOMedia" ); 645 astring = OSString::withCStringNoCopy("Apple_HFS"); 646 if ( astring ) { 647 matching->setObject("Content", astring); 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 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" ); 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 } 683 } 684 } while( !service); 685 matching->release(); 686 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; 702 } else if ( service && mediaProperty ) { 703 service = (IOService *)service->getProperty(mediaProperty); 704 } 705 706 mjr = 0; 707 mnr = 0; 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" ) 715 && !IORegisterNetworkInterface( service ) ) 716 { 717 service = 0; 718 } 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) 731 mjr = off->unsigned32BitValue(); 732 off = (OSNumber *) service->getProperty( kIOBSDMinorKey ); 733 if( off) 734 mnr = off->unsigned32BitValue(); 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 ); 747 if( mjr) 748 IOLog(", major %d, minor %d\n", mjr, mnr ); 749 else 750 IOLog("\n"); 751 752 *root = makedev( mjr, mnr ); 753 *oflags = flags; 754 755 IOFree( str, kMaxPathBuf + kMaxBootVar ); 756 757 iofrootx: 758 if( (gIOKitDebug & (kIOLogDTree | kIOLogServiceTree | kIOLogMemory)) && !debugInfoPrintedOnce) { 759 760 IOService::getPlatform()->waitQuiet(); 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 776 void 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 790 void * 791 IOBSDRegistryEntryForDeviceTree(char * path) 792 { 793 return (IORegistryEntry::fromPath(path, gIODTPlane)); 794 } 795 796 void 797 IOBSDRegistryEntryRelease(void * entry) 798 { 799 IORegistryEntry * regEntry = (IORegistryEntry *)entry; 800 801 if (regEntry) 802 regEntry->release(); 803 return; 804 } 805 806 const void * 807 IOBSDRegistryEntryGetData(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 821 kern_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 837 } /* extern "C" */ 838