bool FileNVRAM::start(IOService *provider) { bool earlyInit = false; LOG(NOTICE, "start() called (%d)\n", mInitComplete); //start is called upon wake for some reason. if (mInitComplete) { return true; } if (!super::start(provider)) { return false; } LOG(NOTICE, "start() called (%d)\n", mInitComplete); // mFilePath = NULL; // no know file mLoggingLevel = NOTICE; // start with logging disabled, can be update for debug mInitComplete = false; // Don't resync anything that's already in the file system. mSafeToSync = false; // Don't sync untill later // We should be root right now... cache this for later. mCtx = vfs_context_current(); // Register Power modes PMinit(); registerPowerDriver(this, sPowerStates, sizeof(sPowerStates) / sizeof(IOPMPowerState)); provider->joinPMtree(this); IORegistryEntry* bootnvram = IORegistryEntry::fromPath(NVRAM_FILE_DT_LOCATION, gIODTPlane); IORegistryEntry* root = IORegistryEntry::fromPath("/", gIODTPlane); // Create the command gate. mCommandGate = IOCommandGate::commandGate( this, dispatchCommand); getWorkLoop()->addEventSource( mCommandGate ); // Replace the IOService dicionary with an empty one, clean out variables we don't want. OSDictionary* dict = OSDictionary::withCapacity(1); if (!dict) { return false; } setPropertyTable(dict); if (bootnvram) { copyEntryProperties(NULL, bootnvram); bootnvram->detachFromParent(root, gIODTPlane); } else { IOTimerEventSource* mTimer = IOTimerEventSource::timerEventSource(this, timeoutOccurred); if (mTimer) { getWorkLoop()->addEventSource( mTimer); mTimer->setTimeoutMS(50); // callback isn't being setup right, causes a panic mSafeToSync = false; } else { earlyInit = true; } } // We don't have initial NVRAM data from the bootloader, or we couldn't schedule a // timer to read in /Extra/NVRAM/nvram.plist, so start up immediately. if (earlyInit == true) { mSafeToSync = true; registerNVRAM(); } mInitComplete = true; return true; }