X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/55e303ae13a4cf49d70f2294092726f2fffb9ef2..3a60a9f5b85abb8c2cf24e1926c5c7b3f608a5e2:/iokit/bsddev/IOKitBSDInit.cpp diff --git a/iokit/bsddev/IOKitBSDInit.cpp b/iokit/bsddev/IOKitBSDInit.cpp index b6d87543d..d93930dd0 100644 --- a/iokit/bsddev/IOKitBSDInit.cpp +++ b/iokit/bsddev/IOKitBSDInit.cpp @@ -3,22 +3,19 @@ * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -29,8 +26,6 @@ #include #include -#include - extern "C" { #include @@ -78,6 +73,12 @@ OSDictionary * IOBSDNameMatching( const char * name ) return( 0 ); } +OSDictionary * IOUUIDMatching( void ) +{ + return IOService::resourceMatching( "boot-uuid-media" ); +} + + OSDictionary * IOCDMatching( void ) { OSDictionary * dict; @@ -258,7 +259,6 @@ OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen ) long partition = -1; long lun = -1; char c; - const char * partitionSep = NULL; // scan the tail of the path for "@unit:partition" do { @@ -272,24 +272,12 @@ OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen ) if( *(--look) == c) { if( c == ':') { partition = strtol( look + 1, 0, 0 ); - partitionSep = look; c = '@'; } else if( c == '@') { - int diff = -1; - - unit = strtol( look + 1, 0, 16 ); - - diff = (int)partitionSep - (int)look; - if ( diff > 0 ) { - - for ( ; diff > 0; diff-- ) - { - if( look[diff] == ',' ) - { - lun = strtol ( &look[diff + 1], 0, 16 ); - break; - } - } + unit = strtol( look + 1, &comp, 16 ); + + if( *comp == ',') { + lun = strtol( comp + 1, 0, 16 ); } c = '/'; @@ -346,11 +334,53 @@ OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen ) OSDictionary * IOOFPathMatching( const char * path, char * buf, int maxLen ) { + OSDictionary * matching; + OSString * str; + char * comp; + int len; + /* need to look up path, get device type, call matching help based on device type */ - return( IODiskMatching( path, buf, maxLen )); + matching = IODiskMatching( path, buf, maxLen ); + if( matching) + return( matching ); + + do { + len = strlen( kIODeviceTreePlane ":" ); + maxLen -= len; + if( maxLen < 0) + continue; + + strcpy( buf, kIODeviceTreePlane ":" ); + comp = buf + len; + + len = strlen( path ); + maxLen -= len; + if( maxLen < 0) + continue; + strncpy( comp, path, len ); + comp[ len ] = 0; + + matching = OSDictionary::withCapacity( 1 ); + if( !matching) + continue; + + str = OSString::withCString( buf ); + if( !str) + continue; + matching->setObject( kIOPathMatchKey, str ); + str->release(); + + return( matching ); + + } while( false ); + + if( matching) + matching->release(); + + return( 0 ); } IOService * IOFindMatchingChild( IOService * service ) @@ -406,6 +436,7 @@ kern_return_t IOFindBSDRoot( char * rootName, UInt32 flags = 0; int minor, major; bool findHFSChild = false; + char * mediaProperty = 0; char * rdBootVar; enum { kMaxPathBuf = 512, kMaxBootVar = 128 }; char * str; @@ -413,10 +444,11 @@ kern_return_t IOFindBSDRoot( char * rootName, int len; bool forceNet = false; bool debugInfoPrintedOnce = false; + const char * uuidStr = NULL; static int mountAttempts = 0; - int xchar, dchar; + int xchar, dchar; if( mountAttempts++) @@ -432,19 +464,39 @@ kern_return_t IOFindBSDRoot( char * rootName, rdBootVar[0] = 0; do { - if( (regEntry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ))) { - data = (OSData *) regEntry->getProperty( "rootpath" ); - regEntry->release(); - if( data) continue; + if( (regEntry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ))) { + data = (OSData *) regEntry->getProperty( "boot-uuid" ); + if( data) { + uuidStr = (const char*)data->getBytesNoCopy(); + OSString *uuidString = OSString::withCString( uuidStr ); + + // match the boot-args boot-uuid processing below + if( uuidString) { + IOLog("rooting via boot-uuid from /chosen: %s\n", uuidStr); + IOService::publishResource( "boot-uuid", uuidString ); + uuidString->release(); + matching = IOUUIDMatching(); + mediaProperty = "boot-uuid-media"; + regEntry->release(); + continue; + } else { + uuidStr = NULL; } + } + + // else try for an OF Path + data = (OSData *) regEntry->getProperty( "rootpath" ); + regEntry->release(); + if( data) continue; + } if( (regEntry = IORegistryEntry::fromPath( "/options", gIODTPlane ))) { - data = (OSData *) regEntry->getProperty( "boot-file" ); - regEntry->release(); - if( data) continue; - } + data = (OSData *) regEntry->getProperty( "boot-file" ); + regEntry->release(); + if( data) continue; + } } while( false ); - if( data) + if( data && !uuidStr) look = (const char *) data->getBytesNoCopy(); if( rdBootVar[0] == '*') { @@ -530,6 +582,26 @@ kern_return_t IOFindBSDRoot( char * rootName, } else if ( strncmp( look, "cdrom", strlen( "cdrom" )) == 0 ) { matching = IOCDMatching(); findHFSChild = true; + } else if ( strncmp( look, "uuid", strlen( "uuid" )) == 0 ) { + char *uuid; + OSString *uuidString; + + uuid = (char *)IOMalloc( kMaxBootVar ); + + if ( uuid ) { + if (!PE_parse_boot_arg( "boot-uuid", uuid )) { + panic( "rd=uuid but no boot-uuid= specified" ); + } + uuidString = OSString::withCString( uuid ); + if ( uuidString ) { + IOService::publishResource( "boot-uuid", uuidString ); + uuidString->release(); + IOLog( "\nWaiting for boot volume with UUID %s\n", uuid ); + matching = IOUUIDMatching(); + mediaProperty = "boot-uuid-media"; + } + IOFree( uuid, kMaxBootVar ); + } } else { matching = IOBSDNameMatching( look ); } @@ -596,6 +668,8 @@ kern_return_t IOFindBSDRoot( char * rootName, // look for a subservice with an Apple_HFS child IOService * subservice = IOFindMatchingChild( service ); if ( subservice ) service = subservice; + } else if ( service && mediaProperty ) { + service = service->getProperty(mediaProperty); } major = 0;