Annotation of XNU/iokit/bsddev/IOKitBSDInit.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: #include <IOKit/IOBSD.h>
        !            23: #include <IOKit/IOLib.h>
        !            24: #include <IOKit/IOService.h>
        !            25: #include <IOKit/IODeviceTreeSupport.h>
        !            26: #include <IOKit/IOKitKeys.h>
        !            27: #include <IOKit/storage/IOMedia.h>
        !            28: 
        !            29: #include <sys/disklabel.h>
        !            30: 
        !            31: extern "C" {
        !            32: 
        !            33: #include <pexpert/pexpert.h>
        !            34: #include <kern/clock.h>
        !            35: 
        !            36: // how long to wait for matching root device, secs
        !            37: #define ROOTDEVICETIMEOUT      60
        !            38: 
        !            39: 
        !            40: kern_return_t
        !            41: IOKitBSDInit( void )
        !            42: {
        !            43:     IOLog("IOKitBSDInit\n");
        !            44: 
        !            45:     IOService::publishResource("IOBSD");
        !            46:  
        !            47:     return( kIOReturnSuccess );
        !            48: }
        !            49: 
        !            50: OSDictionary * IOBSDNameMatching( const char * name )
        !            51: {
        !            52:     OSDictionary *     dict;
        !            53:     const OSSymbol *   str = 0;
        !            54: 
        !            55:     do {
        !            56: 
        !            57:        dict = IOService::serviceMatching( gIOServiceKey );
        !            58:        if( !dict)
        !            59:            continue;
        !            60:         str = OSSymbol::withCString( name );
        !            61:        if( !str)
        !            62:            continue;
        !            63:         dict->setObject( kIOBSDName, (OSObject *) str );
        !            64:         str->release();
        !            65: 
        !            66:         return( dict );
        !            67: 
        !            68:     } while( false );
        !            69: 
        !            70:     if( dict)
        !            71:        dict->release();
        !            72:     if( str)
        !            73:        str->release();
        !            74: 
        !            75:     return( 0 );
        !            76: }
        !            77: 
        !            78: OSDictionary * IONetworkMatching(  const char * path,
        !            79:                                   char * buf, int maxLen )
        !            80: {
        !            81:     OSDictionary *     matching = 0;
        !            82:     OSDictionary *     dict;
        !            83:     OSString *         str;
        !            84:     char *             comp;
        !            85:     const char *       skip;
        !            86:     int                        len;
        !            87: 
        !            88:     do {
        !            89: 
        !            90:        len = strlen( kIODeviceTreePlane ":" );
        !            91:        maxLen -= len;
        !            92:        if( maxLen < 0)
        !            93:            continue;
        !            94: 
        !            95:        strcpy( buf, kIODeviceTreePlane ":" );
        !            96:        comp = buf + len;
        !            97: 
        !            98:         // remove parameters following ':' from the path
        !            99:         skip = strchr( path, ':');
        !           100:        if( !skip)
        !           101:            continue;
        !           102: 
        !           103:         len = skip - path;
        !           104:        maxLen -= len;
        !           105:        if( maxLen < 0)
        !           106:            continue;
        !           107:         strncpy( comp, path, len );
        !           108:         comp[ len ] = 0;
        !           109: 
        !           110:        matching = IOService::serviceMatching( "IONetworkInterface" );
        !           111:        if( !matching)
        !           112:            continue;
        !           113:        dict = IOService::addLocation( matching );
        !           114:        if( !dict)
        !           115:            continue;
        !           116: 
        !           117:        str = OSString::withCString( buf );
        !           118:        if( !str)
        !           119:            continue;
        !           120:         dict->setObject( kIOPathMatchKey, str );
        !           121:        str->release();
        !           122: 
        !           123:        return( matching );
        !           124: 
        !           125:     } while( false );
        !           126: 
        !           127:     if( matching)
        !           128:         matching->release();
        !           129: 
        !           130:     return( 0 );
        !           131: }
        !           132: 
        !           133: OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen )
        !           134: {
        !           135:     OSDictionary *     matching = 0;
        !           136:     const char *       look;
        !           137:     const char *       skip;
        !           138:     const char *       alias;
        !           139:     char *             comp;
        !           140:     UInt32             unit = 0x99;
        !           141:     UInt32             partition = 0xaa;
        !           142:     int                        len;
        !           143:     char               c;
        !           144: 
        !           145:     // scan the tail of the path for "@unit:partition"
        !           146:     do {
        !           147:         // Have to get the full path to the controller - an alias may
        !           148:         // tell us next to nothing, like "hd:8"
        !           149:         skip = path;
        !           150:         alias = IORegistryEntry::dealiasPath( &skip, gIODTPlane );
        !           151: 
        !           152:         look = skip + strlen( skip);
        !           153:         c = ':';
        !           154:         while( c && (look != skip)) {
        !           155:             if( *(--look) == c) {
        !           156:                 if( c == ':') {
        !           157:                     partition = strtol( look + 1, 0, 0 );
        !           158:                     c = '@';
        !           159:                 } else if( c == '@') {
        !           160:                     unit = strtol( look + 1, 0, 16 );
        !           161:                     c = '/';
        !           162:                 } else if( c == '/')
        !           163:                    c = 0;
        !           164:             }
        !           165: 
        !           166:            if( alias && (look == skip)) {
        !           167:                skip = alias;
        !           168:                look = skip + strlen( skip);
        !           169:                alias = 0;
        !           170:            }
        !           171:         }
        !           172:        if( c)
        !           173:            continue;
        !           174: 
        !           175: #define diskMatch1                     \
        !           176: "{"                                    \
        !           177:     kIOProviderClassKey"=IOMedia;"     \
        !           178:     "'IOPath Separator'=':';"          \
        !           179:     "'IOPath Extension'='%ld';"                \
        !           180:     kIOLocationMatchKey"={"            \
        !           181:         "IOUnit=%ld:32;"               \
        !           182:         kIOLocationMatchKey"={"                \
        !           183:             kIOPathMatchKey"='"
        !           184: #define diskMatch2                     \
        !           185:                       "';"             \
        !           186:         "};"                           \
        !           187:     "};"                               \
        !           188: "}"
        !           189: 
        !           190:         sprintf( buf, diskMatch1, partition, unit );
        !           191: 
        !           192:         len = strlen( buf );
        !           193:         comp = buf + len;
        !           194: 
        !           195:         maxLen -= len;
        !           196:        maxLen -= (look - skip) + strlen( kIODeviceTreePlane) + 1;
        !           197:        if( alias) {
        !           198:            len = strlen( alias );
        !           199:            maxLen -= len;
        !           200:        }
        !           201:        if( maxLen > 0) {
        !           202:            strcpy( comp, kIODeviceTreePlane);
        !           203:            comp += strlen( kIODeviceTreePlane);
        !           204:            *(comp++) = ':';
        !           205:            if( alias) {
        !           206:                 strcpy( comp, alias );
        !           207:                comp += len;
        !           208:            }
        !           209:            len = look - skip;
        !           210:            strncpy( comp, skip, len);
        !           211:            comp += len;
        !           212:        } else
        !           213:             continue;
        !           214: 
        !           215:         strcpy( comp, diskMatch2 );
        !           216: 
        !           217:         matching = OSDynamicCast(OSDictionary, OSUnserialize( buf, 0 ));
        !           218:         if (!matching)
        !           219:             continue;
        !           220: 
        !           221:        return( matching );
        !           222: 
        !           223:     } while( false );
        !           224: 
        !           225:     if( matching)
        !           226:         matching->release();
        !           227: 
        !           228:     return( 0 );
        !           229: }
        !           230: 
        !           231: kern_return_t IOFindBSDRoot( char * rootName,
        !           232:                                dev_t * root, u_int32_t * oflags )
        !           233: {
        !           234:     mach_timespec_t    t;
        !           235:     IOService *                service;
        !           236:     IORegistryEntry *  regEntry;
        !           237:     OSDictionary *     matching = 0;
        !           238:     OSString *         iostr;
        !           239:     OSNumber *         off;
        !           240:     OSData *           data = 0;
        !           241: 
        !           242:     UInt32             flags = 0;
        !           243:     int                        minor, major;
        !           244:     char *             rdBootVar;
        !           245:     enum {             kMaxPathBuf = 512, kMaxBootVar = 128 };
        !           246:     char *             str;
        !           247:     const char *       look = 0;
        !           248:     int                        len;
        !           249:     bool               forceNet = false;
        !           250: 
        !           251:     static int         mountAttempts = 0;
        !           252: 
        !           253:     if( mountAttempts++)
        !           254:        IOSleep( 5 * 1000 );
        !           255: 
        !           256:     str = (char *) IOMalloc( kMaxPathBuf + kMaxBootVar );
        !           257:     if( !str)
        !           258:        return( kIOReturnNoMemory );
        !           259:     rdBootVar = str + kMaxPathBuf;
        !           260: 
        !           261:     if (!PE_parse_boot_arg("rd", rdBootVar )
        !           262:      && !PE_parse_boot_arg("rootdev", rdBootVar ))
        !           263:        rdBootVar[0] = 0;
        !           264: 
        !           265:     do {
        !           266:         if( (regEntry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ))) {
        !           267:            data = (OSData *) regEntry->getProperty( "rootpath" );
        !           268:            regEntry->release();
        !           269:            if( data)
        !           270:            continue;
        !           271:        }
        !           272:         if( (regEntry = IORegistryEntry::fromPath( "/options", gIODTPlane ))) {
        !           273:            data = (OSData *) regEntry->getProperty( "boot-file" );
        !           274:            regEntry->release();
        !           275:            if( data)
        !           276:            continue;
        !           277:        }
        !           278:     } while( false );
        !           279: 
        !           280:     if( data)
        !           281:         look = (const char *) data->getBytesNoCopy();
        !           282: 
        !           283:     if( rdBootVar[0] == '*') {
        !           284:         look = rdBootVar + 1;
        !           285:        forceNet = false;
        !           286:     } else {
        !           287:         if( (regEntry = IORegistryEntry::fromPath( "/", gIODTPlane ))) {
        !           288:             forceNet = (0 != regEntry->getProperty( "net-boot" ));
        !           289:            regEntry->release();
        !           290:        }
        !           291:     }
        !           292: 
        !           293:     if( look) {
        !           294:        // from OpenFirmware path
        !           295:        IOLog("From path: \"%s\", ", look);
        !           296: 
        !           297:        if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) )
        !           298:            matching = IONetworkMatching( look, str, kMaxPathBuf );
        !           299:         else
        !           300:             matching = IODiskMatching( look, str, kMaxPathBuf );
        !           301:     }
        !           302: 
        !           303:     if( (!matching) && rdBootVar[0] ) {
        !           304:        // by BSD name
        !           305:        look = rdBootVar;
        !           306:        if( look[0] == '*')
        !           307:            look++;
        !           308:        matching = IOBSDNameMatching( look );
        !           309:     }
        !           310: 
        !           311:     if( !matching) {
        !           312:         OSString * astring;
        !           313:        // any UFS
        !           314:         matching = IOService::serviceMatching( "IOMedia" );
        !           315:         astring = OSString::withCStringNoCopy("Apple_UFS");
        !           316:         if ( astring ) {
        !           317:             matching->setObject(kIOMediaContent, astring);
        !           318:             astring->release(); // XXX -- svail: added.
        !           319:         }
        !           320:     }
        !           321: 
        !           322:     if( true && matching) {
        !           323:         OSSerialize * s = OSSerialize::withCapacity( 5 );
        !           324: 
        !           325:         if( matching->serialize( s )) {
        !           326:             IOLog( "Waiting on %s\n", s->text() );
        !           327:             s->release();
        !           328:         }
        !           329:     }
        !           330: 
        !           331:     IOService::waitForService(IOService::serviceMatching("IOMediaBSDClient"));
        !           332: 
        !           333:     do {
        !           334:         t.tv_sec = ROOTDEVICETIMEOUT;
        !           335:         t.tv_nsec = 0;
        !           336:        matching->retain();
        !           337:         service = IOService::waitForService( matching, &t );
        !           338:        if( (!service) || (mountAttempts == 10)) {
        !           339:             PE_display_icon( 0, "noroot");
        !           340:             IOLog( "Still waiting for root device\n" );
        !           341:        }
        !           342:     } while( !service);
        !           343:     matching->release();
        !           344: 
        !           345:     major = 0;
        !           346:     minor = 0;
        !           347: 
        !           348:     if( service) {
        !           349: 
        !           350:        len = kMaxPathBuf;
        !           351:        service->getPath( str, &len, gIOServicePlane );
        !           352:        IOLog( "Got boot device = %s\n", str );
        !           353: 
        !           354:        iostr = (OSString *) service->getProperty( kIOBSDName );
        !           355:        if( iostr)
        !           356:            strcpy( rootName, iostr->getCStringNoCopy() );
        !           357:        off = (OSNumber *) service->getProperty( kIOBSDMajor );
        !           358:        if( off)
        !           359:            major = off->unsigned32BitValue();
        !           360:        off = (OSNumber *) service->getProperty( kIOBSDMinor );
        !           361:        if( off)
        !           362:            minor = off->unsigned32BitValue();
        !           363: 
        !           364:        if( service->metaCast( "IONetworkInterface" ))
        !           365:            flags |= 1;
        !           366: 
        !           367:     } else {
        !           368: 
        !           369:        IOLog( "Wait for root failed\n" );
        !           370:         strcpy( rootName, "en0");
        !           371:         flags |= 1;
        !           372:     }
        !           373: 
        !           374:     IOLog( "BSD root: %s", rootName );
        !           375:     if( major)
        !           376:        IOLog(", major %d, minor %d\n", major, minor );
        !           377:     else
        !           378:        IOLog("\n");
        !           379: 
        !           380:     *root = makedev( major, minor );
        !           381:     *oflags = flags;
        !           382: 
        !           383:     IOFree( str,  kMaxPathBuf + kMaxBootVar );
        !           384: 
        !           385:     if( gIOKitDebug & (kIOLogDTree | kIOLogServiceTree | kIOLogMemory)) {
        !           386: 
        !           387:        IOSleep(10 * 1000);
        !           388: //     IOService::getPlatform()->waitQuiet();
        !           389:         if( gIOKitDebug & kIOLogDTree) {
        !           390:             IOLog("\nDT plane:\n");
        !           391:             IOPrintPlane( gIODTPlane );
        !           392:         }
        !           393:         if( gIOKitDebug & kIOLogServiceTree) {
        !           394:             IOLog("\nService plane:\n");
        !           395:             IOPrintPlane( gIOServicePlane );
        !           396:         }
        !           397:         if( gIOKitDebug & kIOLogMemory)
        !           398:             IOPrintMemory();
        !           399:     }
        !           400: 
        !           401:     return( kIOReturnSuccess );
        !           402: }
        !           403: 
        !           404: } /* extern "C" */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.