Annotation of XNU/iokit/bsddev/IOKitBSDInit.cpp, revision 1.1.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.