X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b0d623f7f2ae71ed96e60569f61f9a9a27016e80..04b8595b18b1b41ac7a206e4b3d51a635f8413d7:/iokit/bsddev/IOKitBSDInit.cpp diff --git a/iokit/bsddev/IOKitBSDInit.cpp b/iokit/bsddev/IOKitBSDInit.cpp index 98c68da18..9b08bb834 100644 --- a/iokit/bsddev/IOKitBSDInit.cpp +++ b/iokit/bsddev/IOKitBSDInit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Apple Inc. All rights reserved. + * Copyright (c) 1998-2011 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ extern "C" { #include #include #include +#include // how long to wait for matching root device, secs #if DEBUG @@ -45,9 +47,10 @@ extern "C" { #define ROOTDEVICETIMEOUT 60 #endif -extern dev_t mdevadd(int devid, ppnum_t base, unsigned int size, int phys); +extern dev_t mdevadd(int devid, uint64_t base, unsigned int size, int phys); extern dev_t mdevlookup(int devid); extern void mdevremoveall(void); +extern void di_root_ramfile(IORegistryEntry * entry); kern_return_t IOKitBSDInit( void ) @@ -57,6 +60,69 @@ IOKitBSDInit( void ) return( kIOReturnSuccess ); } +void +IOServicePublishResource( const char * property, boolean_t value ) +{ + if ( value) + IOService::publishResource( property, kOSBooleanTrue ); + else + IOService::getResourceService()->removeProperty( property ); +} + +boolean_t +IOServiceWaitForMatchingResource( const char * property, uint64_t timeout ) +{ + OSDictionary * dict = 0; + IOService * match = 0; + boolean_t found = false; + + do { + + dict = IOService::resourceMatching( property ); + if( !dict) + continue; + match = IOService::waitForMatchingService( dict, timeout ); + if ( match) + found = true; + + } while( false ); + + if( dict) + dict->release(); + if( match) + match->release(); + + return( found ); +} + +boolean_t +IOCatalogueMatchingDriversPresent( const char * property ) +{ + OSDictionary * dict = 0; + OSOrderedSet * set = 0; + SInt32 generationCount = 0; + boolean_t found = false; + + do { + + dict = OSDictionary::withCapacity(1); + if( !dict) + continue; + dict->setObject( property, kOSBooleanTrue ); + set = gIOCatalogue->findDrivers( dict, &generationCount ); + if ( set && (set->getCount() > 0)) + found = true; + + } while( false ); + + if( dict) + dict->release(); + if( set) + set->release(); + + return( found ); +} + OSDictionary * IOBSDNameMatching( const char * name ) { OSDictionary * dict; @@ -90,83 +156,6 @@ OSDictionary * IOUUIDMatching( void ) return IOService::resourceMatching( "boot-uuid-media" ); } - -OSDictionary * IOCDMatching( void ) -{ - OSDictionary * dict; - const OSSymbol * str; - - dict = IOService::serviceMatching( "IOMedia" ); - if( dict == 0 ) { - IOLog("Unable to find IOMedia\n"); - return 0; - } - - str = OSSymbol::withCString( "CD_ROM_Mode_1" ); - if( str == 0 ) { - dict->release(); - return 0; - } - - dict->setObject( "Content Hint", (OSObject *)str ); - str->release(); - return( dict ); -} - -OSDictionary * IONetworkMatching( const char * path, - char * buf, int maxLen ) -{ - OSDictionary * matching = 0; - OSDictionary * dict; - OSString * str; - char * comp; - const char * skip; - int len; - - do { - - len = strlen( kIODeviceTreePlane ":" ); - maxLen -= len; - if( maxLen <= 0) - continue; - - strlcpy( buf, kIODeviceTreePlane ":", len + 1 ); - comp = buf + len; - - // remove parameters following ':' from the path - skip = strchr( path, ':'); - if( !skip) - continue; - - len = skip - path; - maxLen -= len; - if( maxLen <= 0) - continue; - strlcpy( comp, path, len + 1 ); - - matching = IOService::serviceMatching( "IONetworkInterface" ); - if( !matching) - continue; - dict = IOService::addLocation( matching ); - if( !dict) - continue; - - str = OSString::withCString( buf ); - if( !str) - continue; - dict->setObject( kIOPathMatchKey, str ); - str->release(); - - return( matching ); - - } while( false ); - - if( matching) - matching->release(); - - return( 0 ); -} - OSDictionary * IONetworkNamePrefixMatching( const char * prefix ) { OSDictionary * matching; @@ -274,121 +263,13 @@ static bool IORegisterNetworkInterface( IOService * netif ) return ( netif->getProperty( kIOBSDNameKey ) != 0 ); } -OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen ) -{ - const char * look; - const char * alias; - char * comp; - long unit = -1; - long partition = -1; - long lun = -1; - char c; - int len; - - // scan the tail of the path for "@unit:partition" - do { - // Have to get the full path to the controller - an alias may - // tell us next to nothing, like "hd:8" - alias = IORegistryEntry::dealiasPath( &path, gIODTPlane ); - - look = path + strlen( path); - c = ':'; - while( look != path) { - if( *(--look) == c) { - if( c == ':') { - partition = strtol( look + 1, 0, 0 ); - c = '@'; - } else if( c == '@') { - unit = strtol( look + 1, &comp, 16 ); - - if( *comp == ',') { - lun = strtol( comp + 1, 0, 16 ); - } - - c = '/'; - } else if( c == '/') { - c = 0; - break; - } - } - - if( alias && (look == path)) { - path = alias; - look = path + strlen( path); - alias = 0; - } - } - if( c || unit == -1 || partition == -1) - continue; - - len = strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" ); - maxLen -= len; - if( maxLen <= 0) - continue; - - snprintf( buf, len + 1, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" ); - comp = buf + len; - - if( alias) { - len = strlen( alias ); - maxLen -= len; - if( maxLen <= 0) - continue; - - strlcpy( comp, alias, len + 1 ); - comp += len; - } - - if ( (look - path)) { - len = (look - path); - maxLen -= len; - if( maxLen <= 0) - continue; - - strlcpy( comp, path, len + 1 ); - comp += len; - } - - if ( lun != -1 ) - { - len = strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" ); - maxLen -= len; - if( maxLen <= 0) - continue; - - snprintf( comp, len + 1, "/@%lx,%lx:%ld';}", unit, lun, partition ); - } - else - { - len = strlen( "/@hhhhhhhh:dddddddddd';}" ); - maxLen -= len; - if( maxLen <= 0) - continue; - - snprintf( comp, len + 1, "/@%lx:%ld';}", unit, partition ); - } - - return( OSDynamicCast(OSDictionary, OSUnserialize( buf, 0 )) ); - - } while( false ); - - return( 0 ); -} - OSDictionary * IOOFPathMatching( const char * path, char * buf, int maxLen ) { - OSDictionary * matching; + OSDictionary * matching = NULL; OSString * str; char * comp; int len; - /* need to look up path, get device type, - call matching help based on device type */ - - matching = IODiskMatching( path, buf, maxLen ); - if( matching) - return( matching ); - do { len = strlen( kIODeviceTreePlane ":" ); @@ -425,43 +306,8 @@ OSDictionary * IOOFPathMatching( const char * path, char * buf, int maxLen ) return( 0 ); } -IOService * IOFindMatchingChild( IOService * service ) -{ - // find a matching child service - IOService * child = 0; - OSIterator * iter = service->getClientIterator(); - if ( iter ) { - while( ( child = (IOService *) iter->getNextObject() ) ) { - OSDictionary * dict = OSDictionary::withCapacity( 1 ); - if( dict == 0 ) { - iter->release(); - return 0; - } - const OSSymbol * str = OSSymbol::withCString( "Apple_HFS" ); - if( str == 0 ) { - dict->release(); - iter->release(); - return 0; - } - dict->setObject( "Content", (OSObject *)str ); - str->release(); - if ( child->compareProperty( dict, "Content" ) ) { - dict->release(); - break; - } - dict->release(); - IOService * subchild = IOFindMatchingChild( child ); - if ( subchild ) { - child = subchild; - break; - } - } - iter->release(); - } - return child; -} - static int didRam = 0; +enum { kMaxPathBuf = 512, kMaxBootVar = 128 }; kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, dev_t * root, u_int32_t * oflags ) @@ -473,18 +319,14 @@ kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, OSString * iostr; OSNumber * off; OSData * data = 0; - UInt32 *ramdParms = 0; UInt32 flags = 0; int mnr, mjr; - bool findHFSChild = false; - char * mediaProperty = 0; + const char * mediaProperty = 0; char * rdBootVar; - enum { kMaxPathBuf = 512, kMaxBootVar = 128 }; char * str; const char * look = 0; int len; - bool forceNet = false; bool debugInfoPrintedOnce = false; const char * uuidStr = NULL; @@ -507,6 +349,7 @@ kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, do { if( (regEntry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ))) { + di_root_ramfile(regEntry); data = OSDynamicCast(OSData, regEntry->getProperty( "root-matching" )); if (data) { matching = OSDynamicCast(OSDictionary, OSUnserializeXML((char *)data->getBytesNoCopy())); @@ -533,34 +376,10 @@ kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, 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; } } while( false ); - if( data && !uuidStr) - look = (const char *) data->getBytesNoCopy(); - - if( rdBootVar[0] == '*') { - look = rdBootVar + 1; - forceNet = false; - } else { - if( (regEntry = IORegistryEntry::fromPath( "/", gIODTPlane ))) { - forceNet = (0 != regEntry->getProperty( "net-boot" )); - regEntry->release(); - } - } - - - // // See if we have a RAMDisk property in /chosen/memory-map. If so, make it into a device. // It will become /dev/mdx, where x is 0-f. @@ -571,8 +390,8 @@ kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, if((regEntry = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane ))) { /* Find the map node */ data = (OSData *)regEntry->getProperty("RAMDisk"); /* Find the ram disk, if there */ if(data) { /* We found one */ - - ramdParms = (UInt32 *)data->getBytesNoCopy(); /* Point to the ram disk base and size */ + uintptr_t *ramdParms; + ramdParms = (uintptr_t *)data->getBytesNoCopy(); /* Point to the ram disk base and size */ (void)mdevadd(-1, ml_static_ptovirt(ramdParms[0]) >> 12, ramdParms[1] >> 12, 0); /* Initialize it and pass back the device number */ } regEntry->release(); /* Toss the entry */ @@ -610,19 +429,6 @@ kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, } } - if( look) { - // from OpenFirmware path - IOLog("From path: \"%s\", ", look); - - if (!matching) { - if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) ) { - matching = IONetworkMatching( look, str, kMaxPathBuf ); - } else { - matching = IODiskMatching( look, str, kMaxPathBuf ); - } - } - } - if( (!matching) && rdBootVar[0] ) { // by BSD name look = rdBootVar; @@ -631,10 +437,7 @@ kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, if ( strncmp( look, "en", strlen( "en" )) == 0 ) { matching = IONetworkNamePrefixMatching( "en" ); - } else if ( strncmp( look, "cdrom", strlen( "cdrom" )) == 0 ) { - matching = IOCDMatching(); - findHFSChild = true; - } else if ( strncmp( look, "uuid", strlen( "uuid" )) == 0 ) { + } else if ( strncmp( look, "uuid", strlen( "uuid" )) == 0 ) { char *uuid; OSString *uuidString; @@ -671,6 +474,11 @@ kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, } } + if( gIOKitDebug & kIOWaitQuietBeforeRoot ) { + IOLog( "Waiting for matching to complete\n" ); + IOService::getPlatform()->waitQuiet(); + } + if( true && matching) { OSSerialize * s = OSSerialize::withCapacity( 5 ); @@ -706,25 +514,7 @@ kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, } while( !service); matching->release(); - if ( service && findHFSChild ) { - bool waiting = true; - uint64_t timeoutNS; - - // wait for children services to finish registering - while ( waiting ) { - timeoutNS = ROOTDEVICETIMEOUT; - timeoutNS *= kSecondScale; - - if ( (service->waitQuiet(timeoutNS) ) == kIOReturnSuccess) { - waiting = false; - } else { - IOLog( "Waiting for child registration\n" ); - } - } - // look for a subservice with an Apple_HFS child - IOService * subservice = IOFindMatchingChild( service ); - if ( subservice ) service = subservice; - } else if ( service && mediaProperty ) { + if ( service && mediaProperty ) { service = (IOService *)service->getProperty(mediaProperty); } @@ -798,23 +588,20 @@ iofrootx: return( kIOReturnSuccess ); } +bool IORamDiskBSDRoot(void) +{ + char rdBootVar[kMaxBootVar]; + if (PE_parse_boot_argn("rd", rdBootVar, kMaxBootVar ) + || PE_parse_boot_argn("rootdev", rdBootVar, kMaxBootVar )) { + if((rdBootVar[0] == 'm') && (rdBootVar[1] == 'd') && (rdBootVar[3] == 0)) { + return true; + } + } + return false; +} + void IOSecureBSDRoot(const char * rootName) { -#if CONFIG_EMBEDDED - IOReturn result; - IOPlatformExpert *pe; - const OSSymbol *functionName = OSSymbol::withCStringNoCopy("SecureRootName"); - - while ((pe = IOService::getPlatform()) == 0) IOSleep(1 * 1000); - - // Returns kIOReturnNotPrivileged is the root device is not secure. - // Returns kIOReturnUnsupported if "SecureRootName" is not implemented. - result = pe->callPlatformFunction(functionName, false, (void *)rootName, (void *)0, (void *)0, (void *)0); - - functionName->release(); - - if (result == kIOReturnNotPrivileged) mdevremoveall(); -#endif } void * @@ -853,7 +640,7 @@ kern_return_t IOBSDGetPlatformUUID( uuid_t uuid, mach_timespec_t timeout ) IOService * resources; OSString * string; - resources = IOService::waitForService( IOService::resourceMatching( kIOPlatformUUIDKey ), &timeout ); + resources = IOService::waitForService( IOService::resourceMatching( kIOPlatformUUIDKey ), ( timeout.tv_sec || timeout.tv_nsec ) ? &timeout : 0 ); if ( resources == 0 ) return KERN_OPERATION_TIMED_OUT; string = ( OSString * ) IOService::getPlatform( )->getProvider( )->getProperty( kIOPlatformUUIDKey ); @@ -893,47 +680,6 @@ kern_return_t IOBSDGetPlatformSerialNumber( char *serial_number_str, u_int32_t l return KERN_SUCCESS; } -dev_t IOBSDGetMediaWithUUID( const char *uuid_cstring, char *bsd_name, int bsd_name_len, int timeout) -{ - dev_t dev = 0; - OSDictionary *dictionary; - OSString *uuid_string; - - if (bsd_name_len < 1) { - return 0; - } - bsd_name[0] = '\0'; - - dictionary = IOService::serviceMatching( "IOMedia" ); - if( dictionary ) { - uuid_string = OSString::withCString( uuid_cstring ); - if( uuid_string ) { - IOService *service; - mach_timespec_t tv = { timeout, 0 }; // wait up to "timeout" seconds for the device - - dictionary->setObject( "UUID", uuid_string ); - dictionary->retain(); - service = IOService::waitForService( dictionary, &tv ); - if( service ) { - OSNumber *dev_major = (OSNumber *) service->getProperty( kIOBSDMajorKey ); - OSNumber *dev_minor = (OSNumber *) service->getProperty( kIOBSDMinorKey ); - OSString *iostr = (OSString *) service->getProperty( kIOBSDNameKey ); - - if( iostr) - strlcpy( bsd_name, iostr->getCStringNoCopy(), bsd_name_len ); - - if ( dev_major && dev_minor ) - dev = makedev( dev_major->unsigned32BitValue(), dev_minor->unsigned32BitValue() ); - } - uuid_string->release(); - } - dictionary->release(); - } - - return dev; -} - - void IOBSDIterateMediaWithContent(const char *content_uuid_cstring, int (*func)(const char *bsd_dev_name, const char *uuid_str, void *arg), void *arg) { OSDictionary *dictionary;