bool CCSecureUserDefault::getBoolForKey(const char* pKey) {
	return getBoolForKey(pKey, false);
}
Exemple #2
0
//==========================================================================
// The 'main' function for the booter. Called by boot0 when booting
// from a block device, or by the network booter.
//
// arguments:
//   biosdev - Value passed from boot1/NBP to specify the device
//             that the booter was loaded from.
//
// If biosdev is kBIOSDevNetwork, then this function will return if
// booting was unsuccessful. This allows the PXE firmware to try the
// next boot device on its list.
void common_boot(int biosdev)
{
    int      status;
    char     *bootFile;
    unsigned long adler32;
    bool     quiet;
    bool     firstRun = true;
    bool     instantMenu;
    bool     rescanPrompt;
    unsigned int allowBVFlags = kBVFlagSystemVolume|kBVFlagForeignBoot;
    unsigned int denyBVFlags = kBVFlagEFISystem;

    // Set reminder to unload the PXE base code. Neglect to unload
    // the base code will result in a hang or kernel panic.
    gUnloadPXEOnExit = true;

    // Record the device that the booter was loaded from.
    gBIOSDev = biosdev & kBIOSDevMask;

    // Initialize boot info structure.
    initKernBootStruct();

    // Setup VGA text mode.
    // Not sure if it is safe to call setVideoMode() before the
    // config table has been loaded. Call video_mode() instead.
#if DEBUG
    printf("before video_mode\n");
#endif
    video_mode( 2 );  // 80x25 mono text mode.
#if DEBUG
    printf("after video_mode\n");
#endif

    // Scan and record the system's hardware information.
    scan_platform();

    // First get info for boot volume.
    scanBootVolumes(gBIOSDev, 0);
    bvChain = getBVChainForBIOSDev(gBIOSDev);
    setBootGlobals(bvChain);
    
    // Load boot.plist config file
    status = loadSystemConfig(&bootInfo->bootConfig);

    if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->bootConfig) && quiet) {
        gBootMode |= kBootModeQuiet;
    }

    // Override firstRun to get to the boot menu instantly by setting "Instant Menu"=y in system config
    if (getBoolForKey(kInsantMenuKey, &instantMenu, &bootInfo->bootConfig) && instantMenu) {
        firstRun = false;
    }

    // Loading preboot ramdisk if exists.
    loadPrebootRAMDisk();

    // Disable rescan option by default
    gEnableCDROMRescan = false;

    // Enable it with Rescan=y in system config
    if (getBoolForKey(kRescanKey, &gEnableCDROMRescan, &bootInfo->bootConfig) && gEnableCDROMRescan) {
        gEnableCDROMRescan = true;
    }

    // Ask the user for Rescan option by setting "Rescan Prompt"=y in system config.
    rescanPrompt = false;
    if (getBoolForKey(kRescanPromptKey, &rescanPrompt , &bootInfo->bootConfig) && rescanPrompt && biosDevIsCDROM(gBIOSDev)) {
        gEnableCDROMRescan = promptForRescanOption();
    }

    // Enable touching a single BIOS device only if "Scan Single Drive"=y is set in system config.
    if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->bootConfig) && gScanSingleDrive) {
        gScanSingleDrive = true;
    }

    // Create a list of partitions on device(s).
    if (gScanSingleDrive) {
      scanBootVolumes(gBIOSDev, &bvCount);
    } else {
      scanDisks(gBIOSDev, &bvCount);
    }

    // Create a separated bvr chain using the specified filters.
    bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);

    gBootVolume = selectBootVolume(bvChain);

#if DEBUG
    printf(" Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags);
    printf(" bt(0,0): %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n", gBIOSBootVolume, gBIOSBootVolume->biosdev, gBIOSBootVolume->part_no, gBIOSBootVolume->flags);
    getc();
#endif

	
	useGUI = TRUE;
	// Override useGUI default
	getBoolForKey(kGUIKey, &useGUI, &bootInfo->bootConfig);
 	
 	// Before initGui, patch the video bios with the correct resolution
 	
 	UInt32 params[4];
 	int count;
 	params[3] = 0;
 	
	
 	autoResolution = TRUE;
 	// Override AutoResolution default
 	getBoolForKey(kAutoResolutionKey, &autoResolution, &bootInfo->bootConfig);
 	
	vbios_map * map = open_vbios(CT_UNKWN);
	//Saving the bios in case we have to unpatch it
	save_vbios(map);
	
 	if (autoResolution == TRUE) {
		//Get Resolution from Graphics Mode key
 		count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4);
 		if ( count < 3 ){
			//If no Graphics Mode key, get from EDID
 			getResolution(&params[0], &params[1], &params[2]);
			verbose("EDID Resolution: %dx%d\n",params[0], params[1]);
 		}
	} else {
 			if ( params[2] == 256 ) params[2] = 8;
 			if ( params[2] == 555 ) params[2] = 16;
 			if ( params[2] == 888 ) params[2] = 32;
	}
 		
	if (params[0]!=0 && params[1]!=0) {	
  			
  			unlock_vbios(map);
  			
			patch_vbios(map, params[0], params[1], params[2], 0, 0);
  			
  			relock_vbios(map);
			#if AUTORES_DEBUG			
				printf("Press Any Key...\n");
			 	getc();
			#endif
	}
 	
		
    if (useGUI) {
        /* XXX AsereBLN handle error */
	initGUI();
    }

    setBootGlobals(bvChain);

    // Parse args, load and start kernel.
    while (1) {
        const char *val;
        int len;
        int trycache;
        long flags, cachetime, kerneltime, exttime, sleeptime, time;
        int ret = -1;
        void *binary = (void *)kLoadAddr;
        bool tryresume;
        bool tryresumedefault;
        bool forceresume;

        config_file_t    systemVersion;		// system.plist of booting partition

        // additional variable for testing alternate kernel image locations on boot helper partitions.
        char     bootFileSpec[512];
		
        // Initialize globals.

        sysConfigValid = false;
        gErrors        = false;

        status = getBootOptions(firstRun);
        firstRun = false;
        if (status == -1) continue;
		 
        status = processBootOptions();
        // Status==1 means to chainboot
        if ( status ==  1 ) break;
        // Status==-1 means that the config file couldn't be loaded or that gBootVolume is NULL
        if ( status == -1 )
        {
          // gBootVolume == NULL usually means the user hit escape.
          if(gBootVolume == NULL)
          {
            freeFilteredBVChain(bvChain);

            if (gEnableCDROMRescan)
              rescanBIOSDevice(gBIOSDev);
              
            bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
            setBootGlobals(bvChain);
          }
          continue;
        }
		
        // Other status (e.g. 0) means that we should proceed with boot.
		
		if( bootArgs->Video.v_display == GRAPHICS_MODE )
			drawBackground();
			
        // Found and loaded a config file. Proceed with boot.

		// Turn off any GUI elements
		if( bootArgs->Video.v_display == GRAPHICS_MODE )
		{
			gui.devicelist.draw = false;
			gui.bootprompt.draw = false;
			gui.menu.draw = false;
			gui.infobox.draw = false;
			drawBackground();
			updateVRAM();
		}
		
		/*
		 * AutoResolution - Reapply the patch or cancel if Graphics Mode was incorrect
		 *                  or EDID Info was insane
		 */	
	     getBoolForKey(kAutoResolutionKey, &autoResolution, &bootInfo->bootConfig);
		
		//Restore the vbios for Cancelation
		if ((autoResolution == FALSE) && map) {
			
			unlock_vbios(map);
			
			restore_vbios(map);
			
			relock_vbios(map);
			
			close_vbios(map);
			
		} 
		if ((autoResolution == TRUE) && map) {
			//Reapply patch in case resolution have changed
			
			count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4);
			if ( count < 3 ) {
				getResolution(&params[0], &params[1], &params[2]);
			}
			else 
			{
				if ( params[2] == 256 ) params[2] = 8;
				if ( params[2] == 555 ) params[2] = 16;
				if ( params[2] == 888 ) params[2] = 32;
			}
			
			if (params[0]!=0 && params[1]!=0) {
				
				unlock_vbios(map);
				
				patch_vbios(map, params[0], params[1], params[2], 0, 0);
				
				relock_vbios(map);
				
				close_vbios(map);
			}
		}
		
		// Find out which version mac os we're booting.
		if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion)) {
			if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) {	
				// getValueForKey uses const char for val
				// so copy it and trim
				strncpy(gMacOSVersion, val, MIN(len, 4));
				gMacOSVersion[MIN(len, 4)] = '\0';
			}
		}

		if (platformCPUFeature(CPU_FEATURE_EM64T)) {
			archCpuType = CPU_TYPE_X86_64;
		} else {
			archCpuType = CPU_TYPE_I386;
		}
		if (getValueForKey(karch, &val, &len, &bootInfo->bootConfig)) {
			if (strncmp(val, "i386", 4) == 0) {
				archCpuType = CPU_TYPE_I386;
			}
		}
		if (getValueForKey(k32BitModeFlag, &val, &len, &bootInfo->bootConfig)) {
			archCpuType = CPU_TYPE_I386;
		}
		
		if (!getBoolForKey (kWake, &tryresume, &bootInfo->bootConfig)) {
			tryresume = true;
			tryresumedefault = true;
		} else {
			tryresumedefault = false;
		}

		if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->bootConfig)) {
			forceresume = false;
		}
		
		if (forceresume) {
			tryresume = true;
			tryresumedefault = false;
		}
		
		while (tryresume) {
			const char *tmp;
			BVRef bvr;
			if (!getValueForKey(kWakeImage, &val, &len, &bootInfo->bootConfig))
				val="/private/var/vm/sleepimage";
			
			// Do this first to be sure that root volume is mounted
			ret = GetFileInfo(0, val, &flags, &sleeptime);

			if ((bvr = getBootVolumeRef(val, &tmp)) == NULL)
				break;
			
			// Can't check if it was hibernation Wake=y is required
			if (bvr->modTime == 0 && tryresumedefault)
				break;
			
			if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat))
				break;
			
			if (!forceresume && ((sleeptime+3)<bvr->modTime)) {
				printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n",bvr->modTime-sleeptime);
				break;
			}
				
			HibernateBoot((char *)val);
			break;
		}

        // Reset cache name.
        bzero(gCacheNameAdler + 64, sizeof(gCacheNameAdler) - 64);

        sprintf(gCacheNameAdler + 64, "%s,%s", gRootDevice, bootInfo->bootFile);

        adler32 = Adler32((unsigned char *)gCacheNameAdler, sizeof(gCacheNameAdler));

        if (getValueForKey(kKernelCacheKey, &val, &len, &bootInfo->bootConfig)) {
            strlcpy(gBootKernelCacheFile, val, len+1);
        } else {
            sprintf(gBootKernelCacheFile, "%s.%08lX", kDefaultCachePath, adler32);
        }

        // Check for cache file.
        trycache = (((gBootMode & kBootModeSafe) == 0) &&
                    !gOverrideKernel &&
                    (gBootFileType == kBlockDeviceType) &&
                    (gMKextName[0] == '\0') &&
                    (gBootKernelCacheFile[0] != '\0'));

		verbose("Loading Darwin %s\n", gMacOSVersion);
		
        if (trycache) do {
      
            // if we haven't found the kernel yet, don't use the cache
            ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime);
            if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
                trycache = 0;
                break;
            }
            ret = GetFileInfo(NULL, gBootKernelCacheFile, &flags, &cachetime);
            if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)
                || (cachetime < kerneltime)) {
                trycache = 0;
                break;
            }
            ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime);
            if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)
                && (cachetime < exttime)) {
                trycache = 0;
                break;
            }
            if (kerneltime > exttime) {
                exttime = kerneltime;
            }
            if (cachetime != (exttime + 1)) {
                trycache = 0;
                break;
            }
        } while (0);

        do {
            if (trycache) {
                bootFile = gBootKernelCacheFile;
                verbose("Loading kernel cache %s\n", bootFile);
                ret = LoadFile(bootFile);
                binary = (void *)kLoadAddr;
                if (ret >= 0) {
                    break;
                }
            }
            bootFile = bootInfo->bootFile;

            // Try to load kernel image from alternate locations on boot helper partitions.
            sprintf(bootFileSpec, "com.apple.boot.P/%s", bootFile);
            ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); 
  	  	    if (ret == -1)
  	  	    {
              sprintf(bootFileSpec, "com.apple.boot.R/%s", bootFile);
              ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); 
              if (ret == -1)
              {
                sprintf(bootFileSpec, "com.apple.boot.S/%s", bootFile);
                ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); 
                if (ret == -1)
                {
                  // Not found any alternate locations, using the original kernel image path.
                  strcpy(bootFileSpec, bootFile);
                }
              }
            }
            			
            verbose("Loading kernel %s\n", bootFileSpec);
            ret = LoadThinFatFile(bootFileSpec, &binary);
            if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
            {
              archCpuType = CPU_TYPE_I386;
              ret = LoadThinFatFile(bootFileSpec, &binary);				
            }
			
        } while (0);

        clearActivityIndicator();
#if DEBUG
        printf("Pausing...");
        sleep(8);
#endif

        if (ret <= 0) {
			printf("Can't find %s\n", bootFile);

			if(gui.initialised) {
				sleep(1);
				drawBackground();
				gui.devicelist.draw = true;
				gui.redraw = true;
			}
            if (gBootFileType == kNetworkDeviceType) {
                // Return control back to PXE. Don't unload PXE base code.
                gUnloadPXEOnExit = false;
                break;
            }
        } else {
            /* Won't return if successful. */
            ret = ExecKernel(binary);
        }
    }
    
    // chainboot
    if (status==1) {
	if (getVideoMode() == GRAPHICS_MODE) {	// if we are already in graphics-mode,
		setVideoMode(VGA_TEXT_MODE, 0);	// switch back to text mode
	}
    }
	
    if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit) {
	nbpUnloadBaseCode();
    }
}
bool UserDefaultManager::getFirstTimeModifySql(){
    return !getBoolForKey(kFirstTimeModify);
}
Exemple #4
0
int getBootOptions(bool firstRun)
{
	int     i;
	int     key;
	int     nextRow;
	int     timeout;
	int     bvCount;
	BVRef   bvr;
	BVRef   menuBVR;
	bool    showPrompt, newShowPrompt, isCDROM;

	// Initialize default menu selection entry.
	gBootVolume = menuBVR = selectBootVolume(bvChain);

	if (biosDevIsCDROM(gBIOSDev)) {
		isCDROM = true;
	} else {
		isCDROM = false;
	}

	// ensure we're in graphics mode if gui is setup
	if (firstRun && gui.initialised && bootArgs->Video.v_display == VGA_TEXT_MODE)
	{
		setVideoMode(GRAPHICS_MODE, 0);
	}

	// Clear command line boot arguments
	clearBootArgs();

	// Allow user to override default timeout.
	if (multiboot_timeout_set) {
		timeout = multiboot_timeout;
	} else if (!getIntForKey(kTimeoutKey, &timeout, &bootInfo->chameleonConfig)) {
		/*  If there is no timeout key in the file use the default timeout
		    which is different for CDs vs. hard disks.  However, if not booting
		    a CD and no config file could be loaded set the timeout
		    to zero which causes the menu to display immediately.
		    This way, if no partitions can be found, that is the disk is unpartitioned
		    or simply cannot be read) then an empty menu is displayed.
		    If some partitions are found, for example a Windows partition, then
		    these will be displayed in the menu as foreign partitions.
		 */
		if (isCDROM) {
			timeout = kCDBootTimeout;
		} else {
			timeout = sysConfigValid ? kBootTimeout : 0;
		}
	}

	if (timeout < 0) {
		gBootMode |= kBootModeQuiet;
	}

	// If the user is holding down a modifier key, enter safe mode.
	if ((readKeyboardShiftFlags() & 0x0F) != 0) {
		gBootMode |= kBootModeSafe;
	}

	// Checking user pressed keys
	bool f8press = false, spress = false, vpress = false;
	while (readKeyboardStatus()) {
		key = bgetc ();
		if (key == 0x4200) f8press = true;
		if ((key & 0xff) == 's' || (key & 0xff) == 'S') spress = true;
		if ((key & 0xff) == 'v' || (key & 0xff) == 'V') vpress = true;
	}
	// If user typed F8, abort quiet mode, and display the menu.
	if (f8press) {
		gBootMode &= ~kBootModeQuiet;
		timeout = 0;
	}
	// If user typed 'v' or 'V', boot in verbose mode.
	if ((gBootMode & kBootModeQuiet) && firstRun && vpress) {
		addBootArg(kVerboseModeFlag);
	}
	// If user typed 's' or 'S', boot in single user mode.
	if ((gBootMode & kBootModeQuiet) && firstRun && spress) {
		addBootArg(kSingleUserModeFlag);
	}

	if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
		setCursorPosition(0, 0, 0);
		clearScreenRows(0, kScreenLastRow);
		if (!(gBootMode & kBootModeQuiet)) {
			// Display banner and show hardware info.
			printf(bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024);
			printf(getVBEInfoString());
		}
		changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
		verbose("Scanning device %x...", gBIOSDev);
	}

	// When booting from CD, default to hard drive boot when possible. 
	if (isCDROM && firstRun) {
		const char *val;
		char *prompt = NULL;
		char *name = NULL;
		int cnt;
		int optionKey;

		if (getValueForKey(kCDROMPromptKey, &val, &cnt, &bootInfo->chameleonConfig)) {
			prompt = malloc(cnt + 1);
			strncat(prompt, val, cnt);
		} else {
			name = malloc(80);
			getBootVolumeDescription(gBootVolume, name, 79, false);
			prompt = malloc(256);
			sprintf(prompt, "Press any key to start up from %s, or press F8 to enter startup options.", name);
			free(name);
		}

		if (getIntForKey( kCDROMOptionKey, &optionKey, &bootInfo->chameleonConfig )) {
			// The key specified is a special key.
		} else {
			// Default to F8.
			optionKey = 0x4200;
		}

		// If the timeout is zero then it must have been set above due to the
		// early catch of F8 which means the user wants to set boot options
		// which we ought to interpret as meaning he wants to boot the CD.
		if (timeout != 0) {
			key = countdown(prompt, kMenuTopRow, timeout);
		} else {
			key = optionKey;
		}

		if (prompt != NULL) {
			free(prompt);
		}

		clearScreenRows( kMenuTopRow, kMenuTopRow + 2 );

		// Hit the option key ?
		if (key == optionKey) {
			gBootMode &= ~kBootModeQuiet;
			timeout = 0;
		} else {
			key = key & 0xFF;

			// Try booting hard disk if user pressed 'h'
			if (biosDevIsCDROM(gBIOSDev) && key == 'h') {
				BVRef bvr;

				// Look at partitions hosting OS X other than the CD-ROM
				for (bvr = bvChain; bvr; bvr=bvr->next) {
					if ((bvr->flags & kBVFlagSystemVolume) && bvr->biosdev != gBIOSDev) {
						gBootVolume = bvr;
					}
				}
			}
			goto done;
		}
	}

	if (gBootMode & kBootModeQuiet) {
		// No input allowed from user.
		goto done;
	}

	if (firstRun && timeout > 0 && countdown("Press any key to enter startup options.", kMenuTopRow, timeout) == 0) {
		// If the user is holding down a modifier key,
		// enter safe mode.
		if ((readKeyboardShiftFlags() & 0x0F) != 0) {
			gBootMode |= kBootModeSafe;
		}
		goto done;
	}

	if (gDeviceCount > 0) {
		// Allocate memory for an array of menu items.
		menuItems = malloc(sizeof(MenuItem) * gDeviceCount);
		if (menuItems == NULL) {
			goto done;
		}

		// Associate a menu item for each BVRef.
		for (bvr=bvChain, i=gDeviceCount-1, selectIndex=-1; bvr; bvr=bvr->next) {
			if (bvr->visible) {
				getBootVolumeDescription(bvr, menuItems[i].name, sizeof(menuItems[i].name) - 1, true);
				menuItems[i].param = (void *) bvr;
				if (bvr == menuBVR) {
					selectIndex = i;
				}
				i--;
			}
		}
		// Jief : In case the default partition (returned by selectBootVolume) is not in the menu
		if ( selectIndex == -1 )
		{
			selectIndex = 0;

			// gDeviceCount is actually > 0, so menuItems[selectIndex] exists
			menuBVR = (BVRef)(menuItems[selectIndex].param);
			// what happen is bvChain is empty ?
		}
	}

	if (bootArgs->Video.v_display != VGA_TEXT_MODE) {
		// redraw the background buffer
		gui.logo.draw = true;
		drawBackground();
		gui.devicelist.draw = true;
		gui.redraw = true;
		if (!(gBootMode & kBootModeQuiet)) {
 
			// Check if "Boot Banner"=N switch is present in config file.
			getBoolForKey(kBootBannerKey, &showBootBanner, &bootInfo->chameleonConfig); 
			if (showBootBanner) {
				// Display banner and show hardware info.
				gprintf(&gui.screen, bootBanner + 1, (bootInfo->convmem + bootInfo->extmem) / 1024);
			}

			// redraw background
			memcpy(gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4);
		}
	} else {
		// Clear screen and hide the blinking cursor.
		clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
		changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);
	}

	nextRow = kMenuTopRow;
	showPrompt = true;

	if (gDeviceCount) {
		if( bootArgs->Video.v_display == VGA_TEXT_MODE ) {
			printf("Use \30\31 keys to select the startup volume.");
		}
		showMenu( menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems );
		nextRow += MIN( gDeviceCount, kMenuMaxItems ) + 3;
	}

	// Show the boot prompt.
	showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
	showBootPrompt( nextRow, showPrompt );
	
	do {
		if (bootArgs->Video.v_display != VGA_TEXT_MODE) {
			// redraw background
			memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
			// reset cursor co-ords
			gui.debug.cursor = pos( gui.screen.width - 160 , 10 );
		}
		key = getchar();
		updateMenu( key, (void **) &menuBVR );
		newShowPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);

		if (newShowPrompt != showPrompt) {
			showPrompt = newShowPrompt;
			showBootPrompt( nextRow, showPrompt );
		}

		if (showPrompt) {
			updateBootArgs(key);
		}

		switch (key) {
		case KEY_ENTER:
			if (gui.menu.draw) { 
				key=0;
				break;
			}
			if (*gBootArgs == '?') {
				char * argPtr = gBootArgs;

				// Skip the leading "?" character.
				argPtr++;
				getNextArg(&argPtr, booterCommand);
				getNextArg(&argPtr, booterParam);

				/*
				* TODO: this needs to be refactored.
				*/
				if (strcmp( booterCommand, "video" ) == 0) {
					if (bootArgs->Video.v_display != VGA_TEXT_MODE) {
						showInfoBox(getVBEInfoString(), getVBEModeInfoString());
					} else {
						printVBEModeInfo();
					}
				} else if ( strcmp( booterCommand, "memory" ) == 0) {
					if (bootArgs->Video.v_display != VGA_TEXT_MODE ) {
						showInfoBox("Memory Map", getMemoryInfoString());
					} else {
						printMemoryInfo();
					}
				} else if (strcmp(booterCommand, "lspci") == 0) {
					lspci();
				} else if (strcmp(booterCommand, "log") == 0) {
			                showTextBuffer(msgbuf, strlen(msgbuf));
				} else if (strcmp(booterCommand, "more") == 0) {
					showTextFile(booterParam);
				} else if (strcmp(booterCommand, "rd") == 0) {
					processRAMDiskCommand(&argPtr, booterParam);
				} else if (strcmp(booterCommand, "norescan") == 0) {
					if (gEnableCDROMRescan) {
						gEnableCDROMRescan = false;
						break;
					}
				} else {
					showHelp();
				}
				key = 0;
				showBootPrompt(nextRow, showPrompt);
				break;
			}
			gBootVolume = menuBVR;
			setRootVolume(menuBVR);
			gBIOSDev = menuBVR->biosdev;
			break;

		case KEY_ESC:
			clearBootArgs();
			break;

		case KEY_F5:
			// New behavior:
			// Clear gBootVolume to restart the loop
			// if the user enabled rescanning the optical drive.
			// Otherwise boot the default boot volume.
			if (gEnableCDROMRescan) {
				gBootVolume = NULL;
				clearBootArgs();
			}
			break;

		case KEY_F10:
			gScanSingleDrive = false;
			scanDisks(gBIOSDev, &bvCount);
			gBootVolume = NULL;
			clearBootArgs();
			break;

		case KEY_TAB:
			// New behavior:
			// Switch between text & graphic interfaces
			// Only Permitted if started in graphics interface
			if (useGUI) {
				if (bootArgs->Video.v_display != VGA_TEXT_MODE) {
					setVideoMode(VGA_TEXT_MODE, 0);

					setCursorPosition(0, 0, 0);
					clearScreenRows(0, kScreenLastRow);

					// Display banner and show hardware info.
					printf(bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024);
					printf(getVBEInfoString());

					clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
					changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);

					nextRow = kMenuTopRow;
					showPrompt = true;

					if (gDeviceCount) {
						printf("Use \30\31 keys to select the startup volume.");
						showMenu(menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems);
						nextRow += MIN(gDeviceCount, kMenuMaxItems) + 3;
					}

					showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
					showBootPrompt(nextRow, showPrompt);
					//changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 );
				} else {
					gui.redraw = true;
					setVideoMode(GRAPHICS_MODE, 0);
					updateVRAM();
                    			updateGraphicBootPrompt();
				}
			}
			key = 0;
			break;

		default:
			key = 0;
			break;
		}
	} while (0 == key);

done:
	if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
		clearScreenRows(kMenuTopRow, kScreenLastRow);
		changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
	}
	shouldboot = false;
	gui.menu.draw = false;
	if (menuItems) {
		free(menuItems);
		menuItems = NULL;
	}
	execute_hook("BootOptions", gBootArgs, gBootArgsPtr, NULL, NULL);
	return 0;
}
int mountRAMDisk(const char * param)
{
	int fh = 0, ramDiskSize;
	int error = 0;

	// Get file handle for ramdisk file.
	fh = open(param, 0);
	if (fh != -1)
	{
		printf("\nreading ramdisk image: %s", param);

		ramDiskSize = file_size(fh);
		if (ramDiskSize > 0)
		{
			// Unmount previously mounted image if exists.
			umountRAMDisk();

			// Read new ramdisk image contents into PREBOOT_DATA area.
			if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1;
		}
		else error = -1;

		close(fh);
	}
	else error = -1;

	if (error == 0)
	{
		// Save filename in gRAMDiskFile to display information.
		strcpy(gRAMDiskFile, param);

		// Set gMI as well for the multiboot ramdisk driver hook.
		gMI = gRAMDiskMI = malloc(sizeof(multiboot_info));
		struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module));

		// Fill in multiboot info and module structures.
		if (gRAMDiskMI != NULL && ramdisk_module != NULL)
		{
			gRAMDiskMI->mi_mods_count = 1;
			gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module;
			ramdisk_module->mm_mod_start = PREBOOT_DATA;
			ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize;

			// Set ramdisk driver hooks.
			p_get_ramdisk_info = &multiboot_get_ramdisk_info;
			p_ramdiskReadBytes = &multibootRamdiskReadBytes;

			int partCount; // unused
			// Save bvr of the mounted image.
			gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount);
			if(gRAMDiskVolume == NULL)
			{
				umountRAMDisk();
				printf("\nRamdisk contains no partitions.");
			}
			else
			{
				char dirSpec[128];

				// Reading ramdisk configuration.
				strcpy(dirSpec, RAMDISKCONFIG_FILENAME);

				if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0)
				{
					getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig);
				}
				else
				{
					printf("\nno ramdisk config...\n");
				}

				printf("\nmounting: done");
			}
		}
	}

	return error;
}
Exemple #6
0
void setup_pci_devs(pci_dt_t *pci_dt)
{
	char *devicepath;
	bool do_eth_devprop, do_gfx_devprop, do_enable_hpet, do_igp_devprop;
	pci_dt_t *current = pci_dt;

	do_eth_devprop = do_gfx_devprop = do_enable_hpet = false;

	getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->chameleonConfig);
	getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->chameleonConfig);
    getBoolForKey(kIGPEnabler, &do_igp_devprop, &bootInfo->chameleonConfig);
	getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->chameleonConfig);

	while (current)
	{
		devicepath = get_pci_dev_path(current);

		switch (current->class_id)
		{
			case PCI_CLASS_BRIDGE_HOST:
					if (current->dev.addr == PCIADDR(0, 0, 0))
						dram_controller_dev = current;
				break;
				
			case PCI_CLASS_NETWORK_ETHERNET: 
				if (do_eth_devprop)
					set_eth_builtin(current);
				break;
				
			case PCI_CLASS_DISPLAY_VGA:
				if (do_gfx_devprop){
					switch (current->vendor_id)
					{
						case PCI_VENDOR_ID_ATI:
							setup_ati_devprop(current); 
							break;
					
						case PCI_VENDOR_ID_INTEL:
							setup_gma_devprop(current);
							break;
					
						case PCI_VENDOR_ID_NVIDIA: 
							setup_nvidia_devprop(current);
							break;
					}
				break;
                } else if (do_igp_devprop){
                        setup_gma_devprop(current);
                        break;
                }

			case PCI_CLASS_SERIAL_USB:
				notify_usb_dev(current);
				break;

			case PCI_CLASS_BRIDGE_ISA:
				if (do_enable_hpet)
					force_enable_hpet(current);
				break;
		}
		
		execute_hook("PCIDevice", current, NULL, NULL, NULL);
		
		setup_pci_devs(current->children);
		current = current->next;
	}
}
Exemple #7
0
void decodeSMBIOSTable(SMBEntryPoint *eps)
{
	uint8_t *ptr = (uint8_t *)eps->dmi.tableAddress;
	SMBStructHeader *structHeader = (SMBStructHeader *)ptr;

	minorVersion = eps->minorVersion;
	majorVersion = eps->majorVersion;
	bcdRevisionHi = eps->dmi.bcdRevision >> 4;
	bcdRevisionLo = eps->dmi.bcdRevision & 0x0F;

	getBoolForKey(kPrivateData, &privateData, &bootInfo->chameleonConfig);  // Bungo: chek if mask some data

	DBG("\n");
	DBG("SMBIOS rev.: %d.%d, DMI rev.: %d.%d\n", majorVersion, minorVersion, bcdRevisionHi, bcdRevisionLo);
	DBG("\n");
	for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
	{
		switch (structHeader->type)
		{
			case kSMBTypeBIOSInformation: // Type 0
				decodeBIOSInformation(structHeader);
				break;

			case kSMBTypeSystemInformation: // Type 1
				decodeSystemInformation(structHeader);
				break;

			case kSMBTypeBaseBoard: // Type 2
				decodeBaseBoard(structHeader);
				break;

			case kSMBTypeSystemEnclosure: // Type 3
				decodeSystemEnclosure(structHeader);
				break;

			case kSMBTypeProcessorInformation: // Type 4
				decodeProcessorInformation(structHeader);
				break;

			//case kSMBTypeMemoryModule: // Type 6
			//	decodeMemoryModule(structHeader);
			//	break;

			//case kSMBTypeSystemSlot: // Type 9
			//	decodeSMBTypeSystemSlot(structHeader);
			//	break;

			case kSMBOEMStrings: // Type 11
				decodeSMBOEMStrings(structHeader);
				break;

			case kSMBTypeMemoryDevice: // Type 17
				decodeMemoryDevice(structHeader);
				break;

			//kSMBTypeMemoryArrayMappedAddress: // Type 19
			//	break;

			/* Skip all Apple Specific Structures */
			// case kSMBTypeFirmwareVolume: // Type 128
			// case kSMBTypeMemorySPD: // Type 130
			//	break;

			case kSMBTypeOemProcessorType: // Type 131
				decodeOemProcessorType(structHeader);
				break;

			case kSMBTypeOemProcessorBusSpeed: // Type 132
				decodeOemProcessorBusSpeed(structHeader);
				break;

			//kSMBTypeOemPlatformFeature: // Type 133
			//	decodeOemPlatformFeature(structHeader);
			//	break;

			case kSMBTypeEndOfTable: // Type 127
				DBG("Handle 0x%04x, DMI type %d, %d  bytes\n", structHeader->handle, structHeader->type, structHeader->length);
				DBG("End of Table\n");
				break;

			default:
				break;
		}

		ptr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
		for (; ((uint16_t *)ptr)[0] != 0; ptr++);

		if (((uint16_t *)ptr)[0] == 0) {
			ptr += 2;
		}

		structHeader = (SMBStructHeader *)ptr;
	}
	DBG("\n");
}
Exemple #8
0
Fichier : boot.c Projet : aosm/boot
void boot(int biosdev)
{
    int      status;
    char     *bootFile;
    unsigned long adler32;
    BOOL     quiet;
    BOOL     firstRun = YES;
    BVRef    bvChain;

    zeroBSS();

    // Initialize malloc

    malloc_init(0, 0, 0, malloc_error);

    // Enable A20 gate before accessing memory above 1Mb.

    enableA20();

    // Set reminder to unload the PXE base code. Neglect to unload
    // the base code will result in a hang or kernel panic.

    gUnloadPXEOnExit = 1;

    // Record the device that the booter was loaded from.

    gBIOSDev = biosdev & kBIOSDevMask;

    // Initialize boot info structure.

    initKernBootStruct( gBIOSDev );

    // Setup VGA text mode.
    // Not sure if it is safe to call setVideoMode() before the
    // config table has been loaded. Call video_mode() instead.

    video_mode( 2 );  // 80x25 mono text mode.

    // Scan hardware configuration.

    scanHardware();

    // First get info for boot volume.
    bvChain = scanBootVolumes(gBIOSDev, 0);

    // Record default boot device.
    gBootVolume = selectBootVolume(bvChain);
    bootArgs->kernDev = MAKEKERNDEV(gBIOSDev,
                                    BIOS_DEV_UNIT(gBootVolume),
                                    gBootVolume->part_no );

    // Load default config file from boot device.
    status = loadSystemConfig(0, 0);

    if ( getBoolForKey( kQuietBootKey, &quiet ) && quiet ) {
        gBootMode |= kBootModeQuiet;
    }

    // Parse args, load and start kernel.

    while (1)
    {
        const char *val;
        int len;
        int trycache;
        long flags, cachetime, kerneltime, exttime;
        int ret = -1;

        // Initialize globals.

        sysConfigValid = 0;
        gErrors        = 0;

        status = getBootOptions(firstRun);
        firstRun = NO;
        if (status == -1) continue;

        status = processBootOptions();
        if ( status ==  1 ) break;
        if ( status == -1 ) continue;

        // Found and loaded a config file. Proceed with boot.


        // Reset cache name.
        bzero(gCacheNameAdler, sizeof(gCacheNameAdler));

        if ( getValueForKey( kRootDeviceKey, &val, &len ) == YES ) {
            if (*val == '*') {
                val++;
                len--;
            }
            strncpy( gCacheNameAdler + 64, val, len );
            sprintf(gCacheNameAdler + 64 + len, ",%s", bootArgs->bootFile);
        } else {
            strcpy(gCacheNameAdler + 64, bootArgs->bootFile);
        }
        adler32 = Adler32(gCacheNameAdler, sizeof(gCacheNameAdler));

        if (getValueForKey(kKernelCacheKey, &val, &len) == YES) {
            strlcpy(gBootKernelCacheFile, val, len+1);
        } else {
            sprintf(gBootKernelCacheFile, "%s.%08lX", kDefaultCachePath, adler32);
        }

        // Check for cache file.


        trycache = (((gBootMode & kBootModeSafe) == 0) &&
                    (gOverrideKernel == NO) &&
                    (gBootFileType == kBlockDeviceType) &&
                    (gMKextName[0] == '\0') &&
                    (gBootKernelCacheFile[0] != '\0'));

        printf("Loading Darwin/x86\n");

        if (trycache) do {
      
            // if we haven't found the kernel yet, don't use the cache
            ret = GetFileInfo(NULL, bootArgs->bootFile, &flags, &kerneltime);
            if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
                trycache = 0;
                break;
            }
            ret = GetFileInfo(NULL, gBootKernelCacheFile, &flags, &cachetime);
            if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat)
                || (cachetime < kerneltime)) {
                trycache = 0;
                break;
            }
            ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime);
            if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)
                && (cachetime < exttime)) {
                trycache = 0;
                break;
            }
            if (kerneltime > exttime) {
                exttime = kerneltime;
            }
            if (cachetime != (exttime + 1)) {
                trycache = 0;
                break;
            }
        } while (0);

        do {
            if (trycache) {
                bootFile = gBootKernelCacheFile;
                verbose("Loading kernel cache %s\n", bootFile);
                ret = LoadFile(bootFile);
                if (ret >= 0) {
                    break;
                }
            }
            bootFile = bootArgs->bootFile;
            verbose("Loading kernel %s\n", bootFile);
            ret = LoadFile(bootFile);
        } while (0);

        clearActivityIndicator();
#if DEBUG
        printf("Pausing...");
        sleep(8);
#endif

        if (ret < 0) {
            error("Can't find %s\n", bootFile);

            if ( gBootFileType == kBIOSDevTypeFloppy )
            {
                // floppy in drive, but failed to load kernel.
                gBIOSDev = kBIOSDevTypeHardDrive;
                initKernBootStruct( gBIOSDev );
                printf("Attempting to load from hard drive...");
            }
            else if ( gBootFileType == kNetworkDeviceType )
            {
                // Return control back to PXE. Don't unload PXE base code.
                gUnloadPXEOnExit = 0;
                break;
            }
        } else {
            /* Won't return if successful. */
            ret = ExecKernel((void *)kLoadAddr);
        }

    } /* while(1) */
    
    if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit) {
	nbpUnloadBaseCode();
    }
}
Exemple #9
0
/** Compute necessary space requirements for new smbios */
static struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
{
	struct SMBEntryPoint	*ret;
	char			*smbiostables;
	char			*tablesptr;
	int			origsmbiosnum;
	int			i, j;
	int			tablespresent[256];
	bool			do_auto=true;

	bzero(tablespresent, sizeof(tablespresent));

	getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);

	ret = (struct SMBEntryPoint *)AllocateKernelMemory(sizeof(struct SMBEntryPoint));
	if (origsmbios) {
		smbiostables = (char *)origsmbios->dmi.tableAddress;
		origsmbiosnum = origsmbios->dmi.structureCount;
	} else {
		smbiostables = NULL;
		origsmbiosnum = 0;
	}

	// _SM_
	ret->anchor[0] = 0x5f;
	ret->anchor[1] = 0x53;
	ret->anchor[2] = 0x4d;
	ret->anchor[3] = 0x5f; 
	ret->entryPointLength = sizeof(*ret);
	ret->majorVersion = 2;
	ret->minorVersion = 1;
	ret->maxStructureSize = 0; // will be calculated later in this function
	ret->entryPointRevision = 0;
	for (i=0;i<5;i++) {
		ret->formattedArea[i] = 0;
	}
	//_DMI_
	ret->dmi.anchor[0] = 0x5f;
	ret->dmi.anchor[1] = 0x44;
	ret->dmi.anchor[2] = 0x4d;
	ret->dmi.anchor[3] = 0x49;
	ret->dmi.anchor[4] = 0x5f;
	ret->dmi.tableLength = 0;  // will be calculated later in this function
	ret->dmi.tableAddress = 0; // will be initialized in smbios_real_run()
	ret->dmi.structureCount = 0; // will be calculated later in this function
	ret->dmi.bcdRevision = 0x21;
	tablesptr = smbiostables;

        // add stringlen of overrides to original stringlen, update maxStructure size adequately, 
        // update structure count and tablepresent[type] with count of type. 
	if (smbiostables) {
		for (i=0; i<origsmbiosnum; i++) {
			struct smbios_table_header	*cur = (struct smbios_table_header *)tablesptr;
			char				*stringsptr;
			int				stringlen;

			tablesptr += cur->length;
			stringsptr = tablesptr;
			for (; tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++);
			tablesptr += 2;
			stringlen = tablesptr - stringsptr - 1;
			if (stringlen == 1) {
				stringlen = 0;
			}
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				char		altname[40];

				sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[cur->type] + 1);				
				if (smbios_properties[j].table_type == cur->type &&
				    smbios_properties[j].value_type == SMSTRING &&
				    (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig) ||
				     getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
				{
					stringlen += size + 1;
				} else if (smbios_properties[j].table_type == cur->type &&
				           smbios_properties[j].value_type == SMSTRING &&
				           do_auto && smbios_properties[j].auto_str)
				{
					stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[cur->type])) + 1;
				}
			}
			if (stringlen == 0) {
				stringlen = 1;
			}
			stringlen++;
			if (ret->maxStructureSize < cur->length+stringlen) {
				ret->maxStructureSize=cur->length+stringlen;
			}
			ret->dmi.tableLength += cur->length+stringlen;
			ret->dmi.structureCount++;
			tablespresent[cur->type]++;
		}
	}
        // Add eventually table types whose detected count would be < required count, and update ret header with:
        // new stringlen addons, structure count, and tablepresent[type] count adequately
	for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
		int	numnec=-1;
		char	buffer[40];

		sprintf(buffer, "SMtable%d", i);
		if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
			numnec = -1;
		}
		if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc) {
			numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
		}
		while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
			int	stringlen = 0;
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				char		altname[40];

				sprintf(altname, "%s_%d",smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type] + 1);
				if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
				    smbios_properties[j].value_type == SMSTRING &&
				    (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
				     getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)))
				{
					stringlen += size + 1;
				} else if (smbios_properties[j].table_type == smbios_table_descriptions[i].type &&
				           smbios_properties[j].value_type==SMSTRING &&
				           do_auto && smbios_properties[j].auto_str)
				{
					stringlen += strlen(smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[smbios_table_descriptions[i].type])) + 1;
				}
			}
			if (stringlen == 0) {
				stringlen = 1;
			}
			stringlen++;
			if (ret->maxStructureSize < smbios_table_descriptions[i].len+stringlen) {
				ret->maxStructureSize = smbios_table_descriptions[i].len + stringlen;
			}
			ret->dmi.tableLength += smbios_table_descriptions[i].len + stringlen;
			ret->dmi.structureCount++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}
	return ret;
}
Exemple #10
0
void boot(int biosdev)
{
    zeroBSS();
    mallocInit(0, 0, 0, mallocError);

#if MUST_ENABLE_A20
    // Enable A20 gate before accessing memory above 1 MB.
	if (fastEnableA20() != 0)
	{
		enableA20(); // Fast enable failed. Try legacy method.
	}
#endif

	bool	haveCABootPlist	= false;
	bool	quietBootMode	= true;

	void *fileLoadBuffer = (void *)kLoadAddr;

	char bootFile[256];
	char rootUUID[37];

	char * kernelFlags = NULL;

	const char * val;

	int length	= 0;
	int kernelFlagsLength = 0;

	bootFile[0] = '\0';
	rootUUID[0] = '\0';

#if PRE_LINKED_KERNEL_SUPPORT
	bool	mayUseKernelCache	= false;

	long flags, cachetime;
#endif

	initPlatform(biosdev);	// Passing on the boot drive.

#if DEBUG_STATE_ENABLED
	// Don't switch graphics mode / show boot logo when DEBUG is set to 1.
	printf("\ngArchCPUType (CPU): %s\n", (gArchCPUType == CPU_TYPE_X86_64) ? "x86_64" : "i386");
	sleep(3); // Silent sleep.
#else
	showBootLogo();
#endif

	// A bit ugly maybe, but this will be changed sometime soon.
	while (readKeyboardStatus())
	{
		int key = (bgetc() & 0xff);

		if ((key |= 0x20) == 'r')
		{
			gPlatform.BootRecoveryHD = true;
		}
	}

	initPartitionChain();

	#define loadCABootPlist() loadSystemConfig(&bootInfo->bootConfig)

	// Loading: /Library/Preferences/SystemConfiguration/com.apple.Boot.plist
	// TODO: Check if everything works <i>without</i> having this plist.
	if (loadCABootPlist() == STATE_SUCCESS)
	{
		_BOOT_DEBUG_DUMP("com.apple.Boot.plist located.\n");

		// Load successful. Change state accordantly.
		haveCABootPlist = true;	// Checked <i>before</i> calling key functions.

		// Check the value of <key>Kernel Flags</key> for stuff we are interested in.
		// Note: We need to know about: arch= and the boot flags: -s, -v, -f and -x

		if (getValueForKey(kKernelFlagsKey, &val, &kernelFlagsLength, &bootInfo->bootConfig))
		{
			// "Kernel Flags" key found. Check length to see if we have anything to work with.
			if (kernelFlagsLength)
			{
				kernelFlagsLength++;

				// Yes. Allocate memory for it and copy the kernel flags into it.
				kernelFlags = malloc(kernelFlagsLength);
				strlcpy(kernelFlags, val, kernelFlagsLength);

				// Is 'arch=<i386/x86_64>' specified as kernel flag?
				if (getValueForBootKey(kernelFlags, "arch", &val, &length)) //  && len >= 4)
				{
					gArchCPUType = (strncmp(val, "x86_64", 6) == 0) ? CPU_TYPE_X86_64 : CPU_TYPE_I386;

					_BOOT_DEBUG_DUMP("gArchCPUType (c.a.B.plist): %s\n",  (gArchCPUType == CPU_TYPE_X86_64) ? "x86_64" : "i386");
				}
				
				// Check for -v (verbose) and -s (single user mode) flags.
				gVerboseMode =	getValueForBootKey(kernelFlags, kVerboseModeFlag, &val, &length) || 
								getValueForBootKey(kernelFlags, kSingleUserModeFlag, &val, &length);
				
				if (gVerboseMode)
				{
#if DEBUG_BOOT == false
					setVideoMode(VGA_TEXT_MODE);
#endif
				}

				// Check for -x (safe) and -f (flush cache) flags.
				if (getValueForBootKey(kernelFlags, kSafeModeFlag, &val, &length) || 
					getValueForBootKey(kernelFlags, kIgnoreCachesFlag, &val, &length))
				{
					gBootMode = kBootModeSafe;
				}

				// Is 'boot-uuid=<value>' specified as kernel flag?
				if (getValueForBootKey(kernelFlags, kBootUUIDKey, &val, &length) && length == 36)
				{
					_BOOT_DEBUG_DUMP("Target boot-uuid=<%s>\n", val);

					// Yes. Copy its value into rootUUID.
					strlcpy(rootUUID, val, 37);
				}
				/* else
				{
					strlcpy(rootUUID, "3453E0E5-017B-38AD-A0AA-D0BBD8565D6", 37);
					_BOOT_DEBUG_DUMP("Target boot-uuid=<%s>\n", rootUUID);
				} */
			}
		}

#if PRE_LINKED_KERNEL_SUPPORT
		/* Look for 'Kernel Cache' key. */
		if (getValueForKey(kKernelCacheKey, &val, &length, &bootInfo->bootConfig))
		{
			_BOOT_DEBUG_DUMP("Kernel Cache set to: %s\n", val);

			// Key found. Check if the given filepath/name exists.
			if (length && GetFileInfo(NULL, val, &flags, &cachetime) == 0)
			{
				// File located. Init kernelCacheFile so that we can use it as boot file.
				gPlatform.KernelCachePath = strdup(val);

				// Set flag to inform the load process to skip parts of the code.
				gPlatform.KernelCacheSpecified = true;

				_BOOT_DEBUG_DUMP("kernelcache file found.\n");
			}

			_BOOT_DEBUG_ELSE_DUMP("Error: kernelcache file not found.\n");
		}

		// _BOOT_DEBUG_ELSE_DUMP("No 'Kernel Cache' key given.\n");
#endif
		/* Enable touching of a single BIOS device by setting 'Scan Single Drive' to yes.
		if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->bootConfig) && gScanSingleDrive)
		{
			gScanSingleDrive = true;
		} */
	}
	else
	{
		_BOOT_DEBUG_DUMP("No com.apple.Boot.plist found.\n");
	}
	
	// Was a target drive (per UUID) specified in com.apple.Boot.plist?
	if (rootUUID[0] == '\0')
	{
		_BOOT_DEBUG_DUMP("No UUID specified in com.apple.Boot.plist\n");

		// No, so are we booting from a System Volume?
		if (gPlatform.BootVolume->flags & kBVFlagSystemVolume)
		{
			_BOOT_DEBUG_DUMP("Booting from a System Volume, getting UUID.\n");

			// Yes, then let's get the UUID.
			if (HFSGetUUID(gPlatform.BootVolume, rootUUID) == STATE_SUCCESS)
			{
				_BOOT_DEBUG_DUMP("Success [%s]\n", rootUUID);
			}
		}
		else // Booting from USB-stick or SDboot media.
		{
			_BOOT_DEBUG_DUMP("Booting from a Non System Volume, getting UUID.\n");

			// Get target System Volume and UUID in one go.
			BVRef rootVolume = getTargetRootVolume(rootUUID);

			if (rootVolume)
			{
				_BOOT_DEBUG_DUMP("Success [%s]\n", rootUUID);

				gPlatform.RootVolume = rootVolume;
			}
		}

		// This should never happen, but just to be sure.
		if (rootUUID[0] == '\0')
		{
			_BOOT_DEBUG_DUMP("Failed to get UUID for System Volume.\n");

			if (!gVerboseMode)
			{
				// Force verbose mode when we didn't find a UUID, so 
				// that people see what is going on in times of trouble.
				gVerboseMode = true;
			}
		}
	}

	/*
	 * At this stage we know exactly what boot mode we're in, and which disk to boot from
	 * any of which may or may not have been set/changed (in com.apple.Boot.plist) into a 
	 * non-default system setting and thus is this the place to update our EFI tree.
	 */

    updateEFITree(rootUUID);

	if (haveCABootPlist) // Check boolean before doing more time consuming tasks.
	{
		if (getBoolForKey(kQuietBootKey, &quietBootMode, &bootInfo->bootConfig) && !quietBootMode)
		{
			gBootMode = kBootModeNormal; // Reversed from: gBootMode |= kBootModeQuiet;
		}
	}

    // Parse args, load and start kernel.
    while (1)
    {
		// Initialize globals.

		sysConfigValid = 0;
		gErrors        = 0;

		int retStatus = -1;

		getAndProcessBootArguments(kernelFlags);

		// Initialize bootFile (defaults to: mach_kernel).
		strcpy(bootFile, bootInfo->bootFile);

#if PRE_LINKED_KERNEL_SUPPORT

		_BOOT_DEBUG_DUMP("gBootMode = %d\n", gBootMode);

		// Preliminary checks to prevent us from doing useless things.
		mayUseKernelCache = ((gBootMode & kBootModeSafe) == 0);

		_BOOT_DEBUG_DUMP("mayUseKernelCache = %s\n", mayUseKernelCache ? "true" : "false");

		/* 
		 * A pre-linked kernel, or kernelcache, requires you to have all essential kexts for your
		 * configuration, including FakeSMC.kext in: /System/Library/Extensions/ 
		 * Not in /Extra/Extensions/ because this directory will be ignored, completely when a 
		 * pre-linked kernel or kernelcache is used!
		 *
		 * Note: Not following this word of advise will render your system incapable of booting!
		 */
		
		if (mayUseKernelCache == false)
		{
			_BOOT_DEBUG_DUMP("Warning: kernelcache will be ignored!\n");

			// True when 'Kernel Cache' is set in com.apple.Boot.plist
			if (gPlatform.KernelCacheSpecified == true)
			{
				sprintf(bootFile, "%s", bootInfo->bootFile);
			}
		}
		else
		{
			// True when 'Kernel Cache' is set in com.apple.Boot.plist
			if (gPlatform.KernelCacheSpecified == true)
			{
				_BOOT_DEBUG_DUMP("kernelcache: %s\n", gPlatform.KernelCachePath);

				/*
				 * Starting with Lion, we can take a shortcut by simply pointing 
				 * the 'bootFile' to the kernel cache and we are done.
				 */

				sprintf(bootFile, "%s", gPlatform.KernelCachePath);
			}

			/*
			 * We might have been fired up from a USB thumbdrive (kickstart boot) and 
			 * thus we have to check the kernel cache path first (might not be there).
			 */

			else if (GetFileInfo(NULL, gPlatform.KernelCachePath, &flags, &cachetime) == 0)
			{

#if ((MAKE_TARGET_OS & LION) == LION) // Also for Mountain Lion, which has bit 2 set like Lion.

				_BOOT_DEBUG_DUMP("Checking for kernelcache...\n");

				if (GetFileInfo(gPlatform.KernelCachePath, (char *)kKernelCache, &flags, &cachetime) == 0)
				{
					sprintf(bootFile, "%s/%s", gPlatform.KernelCachePath, kKernelCache);

					_BOOT_DEBUG_DUMP("Kernelcache located.\n");
				}

				_BOOT_DEBUG_ELSE_DUMP("Failed to locate the kernelcache. Will load: %s!\n", bootInfo->bootFile);
			}

			_BOOT_DEBUG_ELSE_DUMP("Failed to locate the kernelcache (directory)!\n");
		}
#else // Not for (Mountain) Lion, go easy with the Snow Leopard.

				static char preLinkedKernelPath[128];
				static char adler32Key[PLATFORM_NAME_LEN + ROOT_PATH_LEN];

				unsigned long adler32 = 0;

				preLinkedKernelPath[0] = '\0';

				_BOOT_DEBUG_DUMP("Checking for pre-linked kernel...\n");

				// Zero out platform info (name and kernel root path).
				bzero(adler32Key, sizeof(adler32Key));
				
				// Construct key for the pre-linked kernel checksum (generated by adler32). 
				sprintf(adler32Key, gPlatform.ModelID);
				sprintf(adler32Key + PLATFORM_NAME_LEN, "%s", BOOT_DEVICE_PATH);
				sprintf(adler32Key + (PLATFORM_NAME_LEN + 38), "%s", bootInfo->bootFile);
				
				adler32 = Adler32((unsigned char *)adler32Key, sizeof(adler32Key));
				
				_BOOT_DEBUG_DUMP("adler32: %08X\n", adler32);
				
				// Create path to pre-linked kernel.
				sprintf(preLinkedKernelPath, "%s/%s_%s.%08lX", gPlatform.KernelCachePath, kKernelCache, 
						((gArchCPUType == CPU_TYPE_X86_64) ? "x86_64" : "i386"), adler32);

				// Check if this file exists.
				if ((GetFileInfo(NULL, preLinkedKernelPath, &flags, &cachetime) == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
				{
					_BOOT_DEBUG_DUMP("Pre-linked kernel cache located!\nLoading pre-linked kernel: %s\n", preLinkedKernelPath);
					
					// Returns -1 on error, or the actual filesize.
					if (LoadFile((const char *)preLinkedKernelPath))
					{
						retStatus = 1;
						fileLoadBuffer = (void *)kLoadAddr;
						bootFile[0] = 0;
					}

					_BOOT_DEBUG_ELSE_DUMP("Failed to load the pre-linked kernel. Will load: %s!\n", bootInfo->bootFile);
				}

				_BOOT_DEBUG_ELSE_DUMP("Failed to locate the pre-linked kernel!\n");
			}

			_BOOT_DEBUG_ELSE_DUMP("Failed to locate the cache directory!\n");
		}
Exemple #11
0
Fichier : boot.c Projet : aosm/boot
static int ExecKernel(void *binary)
{
    entry_t                   kernelEntry;
    int                       ret;
#ifdef APM_SUPPORT
    BOOL                      apm;
#endif /* APM_SUPPORT */
    BOOL                      bootGraphics;

    bootArgs->kaddr = bootArgs->ksize = 0;

    ret = DecodeKernel(binary,
                       &kernelEntry,
                       (char **) &bootArgs->kaddr,
                       &bootArgs->ksize );

    if ( ret != 0 )
        return ret;

    // Reserve space for boot args
    reserveKernBootStruct();

    // Load boot drivers from the specifed root path.

    if (!gHaveKernelCache) {
          LoadDrivers("/");
    }

    clearActivityIndicator();

    if (gErrors) {
        printf("Errors encountered while starting up the computer.\n");
        printf("Pausing %d seconds...\n", kBootErrorTimeout);
        sleep(kBootErrorTimeout);
    }

    printf("Starting Darwin/x86");

    turnOffFloppy();

#ifdef APM_SUPPORT
    // Connect to APM BIOS.

    if ( getBoolForKey("APM", &apm) && apm == YES )
    {
        if ( APMPresent() ) APMConnect32();
    }
#endif /* APM_SUPPORT */

    // Cleanup the PXE base code.

    if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit ) {
		if ( (ret = nbpUnloadBaseCode()) != nbpStatusSuccess )
        {
        	printf("nbpUnloadBaseCode error %d\n", (int) ret);
            sleep(2);
        }
    }

    // Unless Boot Graphics = No, Always switch to graphics mode
    // just before starting the kernel.

    if (!getBoolForKey(kBootGraphicsKey, &bootGraphics)) {
        bootGraphics = YES;
    }

    if (bootGraphics) {
        if (bootArgs->graphicsMode == TEXT_MODE) {
            // If we were in text mode, switch to graphics mode.
            // This will draw the boot graphics.
            setVideoMode( GRAPHICS_MODE );
        } else {
            // If we were already in graphics mode, clear the screen.
            drawBootGraphics();
        }
    } else {
        if (bootArgs->graphicsMode == GRAPHICS_MODE) {
            setVideoMode( TEXT_MODE );
        }
    }

    // Jump to kernel's entry point. There's no going back now.

    startprog( kernelEntry, bootArgs );

    // Not reached

    return 0;
}
Exemple #12
0
void setup_pci_devs(pci_dt_t *pci_dt)
{
	char *devicepath;
	bool do_eth_devprop, do_gfx_devprop, do_enable_hpet;
	pci_dt_t *current = pci_dt;

	do_eth_devprop = do_gfx_devprop = do_enable_hpet = false;

	getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->bootConfig);
	getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->bootConfig);
	getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig);

	while (current)
	{
		devicepath = get_pci_dev_path(current);

		switch (current->class_id)
		{
			case PCI_CLASS_BRIDGE_HOST:
					dram_controller_dev = current;
				break;
				
			case PCI_CLASS_NETWORK_ETHERNET: 
				if (do_eth_devprop)
					set_eth_builtin(current);
				break;
				
			case PCI_CLASS_DISPLAY_VGA:
				if (do_gfx_devprop)
					switch (current->vendor_id)
					{
						case PCI_VENDOR_ID_ATI:
							setup_ati_devprop(current); 
							break;
					
						case PCI_VENDOR_ID_INTEL: 
							/* message to be removed once support for these cards is added */
							verbose("Intel VGA Controller [%04x:%04x] :: %s (currently NOT SUPPORTED)\n", 
								current->vendor_id, current->device_id, devicepath);
							break;
					
						case PCI_VENDOR_ID_NVIDIA: 
							setup_nvidia_devprop(current);
							break;
					}
				break;

			case PCI_CLASS_SERIAL_USB:
				notify_usb_dev(current);
				break;

			case PCI_CLASS_BRIDGE_ISA:
				if (do_enable_hpet)
					force_enable_hpet(current);
				break;
		}
		
		setup_pci_devs(current->children);
		current = current->next;
	}
}
Exemple #13
0
void setup_pci_devs(pci_dt_t *pci_dt)
{
	char *devicepath;
	BOOL do_eth_devprop, do_gfx_devprop, fix_ehci, fix_uhci, fix_usb, do_enable_hpet;
	pci_dt_t *current = pci_dt;

	do_eth_devprop = do_gfx_devprop = fix_ehci = fix_uhci = fix_usb = do_enable_hpet = false;

	getBoolForKey("EthernetBuiltIn", &do_eth_devprop, &bootInfo->bootConfig);
	getBoolForKey("GraphicsEnabler", &do_gfx_devprop, &bootInfo->bootConfig);
	if (getBoolForKey("USBBusFix", &fix_usb, &bootInfo->bootConfig) && fix_usb)
		fix_ehci = fix_uhci = true;
	else
	{
		getBoolForKey("EHCIacquire", &fix_ehci, &bootInfo->bootConfig);
		getBoolForKey("UHCIreset", &fix_uhci, &bootInfo->bootConfig);
	}
	getBoolForKey("ForceHPET", &do_enable_hpet, &bootInfo->bootConfig);

	while (current)
	{
		devicepath = get_pci_dev_path(current);

		switch (current->class_id)
		{
			case PCI_CLASS_NETWORK_ETHERNET: 
				if (do_eth_devprop)
					set_eth_builtin(current);
				break;
				
			case PCI_CLASS_DISPLAY_VGA:
				if (do_gfx_devprop)
					switch (current->vendor_id)
					{
						case PCI_VENDOR_ID_ATI:
							verbose("ATI VGA Controller [%04x:%04x] :: %s \n", 
							current->vendor_id, current->device_id, devicepath);
							setup_ati_devprop(current); 
							break;
					
							case PCI_VENDOR_ID_INTEL:
								verbose("Intel Graphics Controller [%04x:%04x] :: %s \n", 
								current->vendor_id, current->device_id, devicepath);
								setup_gma_devprop(current); 
								break;
					
						case PCI_VENDOR_ID_NVIDIA: 
							setup_nvidia_devprop(current);
							break;
					}
				break;

			case PCI_CLASS_SERIAL_USB:
				switch (pci_config_read8(current->dev.addr, PCI_CLASS_PROG))
				{
					/* EHCI */
					case 0x20:
				    	if (fix_ehci)
							ehci_acquire(current);
						break;

					/* UHCI */
					case 0x00:
				    	if (fix_uhci)
							uhci_reset(current);
						break;
				}
				break;

			case PCI_CLASS_BRIDGE_ISA:
				if (do_enable_hpet)
					force_enable_hpet(current);
				break;
		}
		
		setup_pci_devs(current->children);
		current = current->next;
	}
}
Exemple #14
0
void setup_pci_devs(pci_dt_t *pci_dt)
{
    char *devicepath;
    bool doit, do_eth_devprop, do_wifi_devprop, /*do_usb_devprop,*/ do_gfx_devprop, do_enable_hpet, do_hda_devprop = false;
    pci_dt_t *current = pci_dt;

    getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->chameleonConfig);
    getBoolForKey(kEnableWifi, &do_wifi_devprop, &bootInfo->chameleonConfig);
    getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->chameleonConfig);
//	getBoolForKey(kUsbInject, &do_usb_devprop, &bootInfo->chameleonConfig);
    getBoolForKey(kHDAEnabler, &do_hda_devprop, &bootInfo->chameleonConfig);
    getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->chameleonConfig);

    while (current)
    {
        devicepath = get_pci_dev_path(current);

        switch (current->class_id)
        {
        case PCI_CLASS_BRIDGE_HOST:
            //DBG("Setup BRIDGE_HOST \n");
            if (current->dev.addr == PCIADDR(0, 0, 0))
            {
                dram_controller_dev = current;
            }
            break;

        case PCI_CLASS_NETWORK_ETHERNET:
            //DBG("Setup ETHERNET %s enabled\n", do_eth_devprop?"":"no");
            if (do_eth_devprop)
            {
                setup_eth_builtin(current);
            }
            break;

        case PCI_CLASS_NETWORK_OTHER:
            //DBG("Setup WIRELESS %s enabled\n", do_wifi_devprop?"":"no");
            if (do_wifi_devprop)
            {
                setup_wifi_airport(current);
            }
            break;

        case PCI_CLASS_DISPLAY_VGA:
            //DBG("GraphicsEnabler %s enabled\n", do_gfx_devprop?"":"no");
            if (do_gfx_devprop)
            {
                switch (current->vendor_id)
                {
                case PCI_VENDOR_ID_ATI:
                    if (getBoolForKey(kSkipAtiGfx, &doit, &bootInfo->chameleonConfig) && doit)
                    {
                        verbose("Skip ATi/AMD gfx device!\n");
                    }
                    else
                    {
                        setup_ati_devprop(current);
                    }
                    break;

                case PCI_VENDOR_ID_INTEL:
                    if (getBoolForKey(kSkipIntelGfx, &doit, &bootInfo->chameleonConfig) && doit)
                    {
                        verbose("Skip Intel gfx device!\n");
                    }
                    else
                    {
                        setup_gma_devprop(current);
                    }
                    break;

                case PCI_VENDOR_ID_NVIDIA:
                    if (getBoolForKey(kSkipNvidiaGfx, &doit, &bootInfo->chameleonConfig) && doit)
                    {
                        verbose("Skip Nvidia gfx device!\n");
                    }
                    else
                    {
                        setup_nvidia_devprop(current);
                    }
                    break;
                }
            }
            break;

        case PCI_CLASS_MULTIMEDIA_AUDIO_DEV:
            //DBG("Setup HDEF %s enabled\n", do_hda_devprop?"":"no");
            if (do_hda_devprop)
            {
                setup_hda_devprop(current);
            }
            break;

        case PCI_CLASS_SERIAL_USB:
            //DBG("USB fix \n");
            notify_usb_dev(current);
            /*if (do_usb_devprop)
            {
            		set_usb_devprop(current);
            	}*/
            break;

        case PCI_CLASS_BRIDGE_ISA:
            //DBG("Force HPET %s enabled\n", do_enable_hpet?"":"no");
            if (do_enable_hpet)
            {
                force_enable_hpet(current);
            }
            break;
        }

        execute_hook("PCIDevice", current, NULL, NULL, NULL);
        //DBG("setup_pci_devs current devID=%08x\n", current->device_id);
        setup_pci_devs(current->children);
        current = current->next;
    }
}
Exemple #15
0
//==========================================================================
// The 'main' function for the booter. Called by boot0 when booting
// from a block device, or by the network booter.
//
// arguments:
//	 biosdev - Value passed from boot1/NBP to specify the device
//			   that the booter was loaded from.
//
// If biosdev is kBIOSDevNetwork, then this function will return if
// booting was unsuccessful. This allows the PXE firmware to try the
// next boot device on its list.
void common_boot(int biosdev)
{
	bool	 		quiet;
	bool	 		firstRun = true;
	bool	 		instantMenu;
	bool	 		rescanPrompt;
	int				status;
	unsigned int	allowBVFlags = kBVFlagSystemVolume | kBVFlagForeignBoot;
	unsigned int	denyBVFlags = kBVFlagEFISystem;

	// Set reminder to unload the PXE base code. Neglect to unload
	// the base code will result in a hang or kernel panic.
	gUnloadPXEOnExit = true;

	// Record the device that the booter was loaded from.
	gBIOSDev = biosdev & kBIOSDevMask;

	// Initialize boot-log
	initBooterLog();

	// Initialize boot info structure.
	initKernBootStruct();

	// Setup VGA text mode.
	// Not sure if it is safe to call setVideoMode() before the
	// config table has been loaded. Call video_mode() instead.
#if DEBUG
	printf("before video_mode\n");
#endif
	video_mode( 2 );  // 80x25 mono text mode.
#if DEBUG
	printf("after video_mode\n");
#endif

	// Scan and record the system's hardware information.
	scan_platform();

	// First get info for boot volume.
	scanBootVolumes(gBIOSDev, 0);
	bvChain = getBVChainForBIOSDev(gBIOSDev);
	setBootGlobals(bvChain);

	// Load boot.plist config file
	status = loadChameleonConfig(&bootInfo->chameleonConfig, bvChain);

	if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->chameleonConfig) && quiet) {
		gBootMode |= kBootModeQuiet;
	}

	// Override firstRun to get to the boot menu instantly by setting "Instant Menu"=y in system config
	if (getBoolForKey(kInstantMenuKey, &instantMenu, &bootInfo->chameleonConfig) && instantMenu) {
		firstRun = false;
	}

	// Loading preboot ramdisk if exists.
	loadPrebootRAMDisk();

	// Disable rescan option by default
	gEnableCDROMRescan = false;

	// Enable it with Rescan=y in system config
	if (getBoolForKey(kRescanKey, &gEnableCDROMRescan, &bootInfo->chameleonConfig)
		&& gEnableCDROMRescan) {
		gEnableCDROMRescan = true;
	}

	// Ask the user for Rescan option by setting "Rescan Prompt"=y in system config.
	rescanPrompt = false;
	if (getBoolForKey(kRescanPromptKey, &rescanPrompt , &bootInfo->chameleonConfig)
		&& rescanPrompt && biosDevIsCDROM(gBIOSDev))
	{
		gEnableCDROMRescan = promptForRescanOption();
	}

	// Enable touching a single BIOS device only if "Scan Single Drive"=y is set in system config.
	if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->chameleonConfig)
		&& gScanSingleDrive) {
		gScanSingleDrive = true;
	}

	// Create a list of partitions on device(s).
	if (gScanSingleDrive) {
		scanBootVolumes(gBIOSDev, &bvCount);
	} else {
		scanDisks(gBIOSDev, &bvCount);
	}

	// Create a separated bvr chain using the specified filters.
	bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);

	gBootVolume = selectBootVolume(bvChain);

	// Intialize module system
	init_module_system();

#if DEBUG
	printf(" Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n",
			 gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags);
	printf(" bt(0,0): %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n",
			 gBIOSBootVolume, gBIOSBootVolume->biosdev, gBIOSBootVolume->part_no, gBIOSBootVolume->flags);
	getchar();
#endif

	useGUI = true;
	// Override useGUI default
	getBoolForKey(kGUIKey, &useGUI, &bootInfo->chameleonConfig);
	if (useGUI && initGUI())
	{
		// initGUI() returned with an error, disabling GUI.
		useGUI = false;
	}

	setBootGlobals(bvChain);

	// Parse args, load and start kernel.
	while (1)
	{
		bool		tryresume, tryresumedefault, forceresume;
		bool		useKernelCache = true; // by default try to use the prelinked kernel
		const char	*val;
		int			len, ret = -1;
		long		flags, sleeptime, time;
		void		*binary = (void *)kLoadAddr;

		char        bootFile[sizeof(bootInfo->bootFile)];
		char		bootFilePath[512];
		char		kernelCacheFile[512];

		// Initialize globals.
		sysConfigValid = false;
		gErrors		   = false;

		status = getBootOptions(firstRun);
		firstRun = false;
		if (status == -1) continue;

		status = processBootOptions();
		// Status == 1 means to chainboot
		if ( status ==	1 ) break;
		// Status == -1 means that the config file couldn't be loaded or that gBootVolume is NULL
		if ( status == -1 )
		{
			// gBootVolume == NULL usually means the user hit escape.
			if (gBootVolume == NULL)
			{
				freeFilteredBVChain(bvChain);

				if (gEnableCDROMRescan)
					rescanBIOSDevice(gBIOSDev);

				bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
				setBootGlobals(bvChain);
				setupDeviceList(&bootInfo->themeConfig);
			}
			continue;
		}

		// Other status (e.g. 0) means that we should proceed with boot.

		// Turn off any GUI elements
		if ( bootArgs->Video.v_display == GRAPHICS_MODE )
		{
			gui.devicelist.draw = false;
			gui.bootprompt.draw = false;
			gui.menu.draw = false;
			gui.infobox.draw = false;
			gui.logo.draw = false;
			drawBackground();
			updateVRAM();
		}

		// Find out which version mac os we're booting.
		getOSVersion();

		if (platformCPUFeature(CPU_FEATURE_EM64T)) {
			archCpuType = CPU_TYPE_X86_64;
		} else {
			archCpuType = CPU_TYPE_I386;
		}

		if (getValueForKey(karch, &val, &len, &bootInfo->chameleonConfig)) {
			if (strncmp(val, "i386", 4) == 0) {
				archCpuType = CPU_TYPE_I386;
			}
		}

		if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig)) {
			if (strncmp(val, "i386", 4) == 0) {
				archCpuType = CPU_TYPE_I386;
			}
		}

		// Notify modules that we are attempting to boot
		execute_hook("PreBoot", NULL, NULL, NULL, NULL);

		if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig)) {
			tryresume = true;
			tryresumedefault = true;
		} else {
			tryresumedefault = false;
		}

		if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->chameleonConfig)) {
			forceresume = false;
		}

		if (forceresume) {
			tryresume = true;
			tryresumedefault = false;
		}

		while (tryresume) {
			const char *tmp;
			BVRef bvr;
			if (!getValueForKey(kWakeImage, &val, &len, &bootInfo->chameleonConfig))
				val = "/private/var/vm/sleepimage";

			// Do this first to be sure that root volume is mounted
			ret = GetFileInfo(0, val, &flags, &sleeptime);

			if ((bvr = getBootVolumeRef(val, &tmp)) == NULL)
				break;

			// Can't check if it was hibernation Wake=y is required
			if (bvr->modTime == 0 && tryresumedefault)
				break;

			if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat))
				break;

			if (!forceresume && ((sleeptime+3)<bvr->modTime)) {
#if DEBUG
				printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n",
						bvr->modTime-sleeptime);
#endif
				break;
			}

			HibernateBoot((char *)val);
			break;
		}

		getBoolForKey(kUseKernelCache, &useKernelCache, &bootInfo->chameleonConfig);
		if (useKernelCache) do {

			// Determine the name of the Kernel Cache
			if (getValueForKey(kKernelCacheKey, &val, &len, &bootInfo->bootConfig)) {
				if (val[0] == '\\')
				{
					len--;
					val++;
				}
				/* FIXME: check len vs sizeof(kernelCacheFile) */
				strlcpy(kernelCacheFile, val, len + 1);
			} else {
				kernelCacheFile[0] = 0; // Use default kernel cache file
			}

			if (gOverrideKernel && kernelCacheFile[0] == 0) {
				DBG("Using a non default kernel (%s) without specifying 'Kernel Cache' path, KernelCache will not be used\n", bootInfo->bootFile);
				useKernelCache = false;
				break;
			}
			if (gMKextName[0] != 0) {
				DBG("Using a specific MKext Cache (%s), KernelCache will not be used\n",
						gMKextName);
				useKernelCache = false;
				break;
			}
			if (gBootFileType != kBlockDeviceType)
				useKernelCache = false;

		} while(0);

		do {
			if (useKernelCache) {
				ret = LoadKernelCache(kernelCacheFile, &binary);
				if (ret >= 0)
					break;
			}

			bool bootFileWithDevice = false;
			// Check if bootFile start with a device ex: bt(0,0)/Extra/mach_kernel
			if (strncmp(bootInfo->bootFile,"bt(",3) == 0 ||
				strncmp(bootInfo->bootFile,"hd(",3) == 0 ||
				strncmp(bootInfo->bootFile,"rd(",3) == 0)
				bootFileWithDevice = true;

			// bootFile must start with a / if it not start with a device name
			if (!bootFileWithDevice && (bootInfo->bootFile)[0] != '/')
			{
				snprintf(bootFile, sizeof(bootFile), "/%s", bootInfo->bootFile); // append a leading /
			} else {
				strlcpy(bootFile, bootInfo->bootFile, sizeof(bootFile));
			}

			// Try to load kernel image from alternate locations on boot helper partitions.
			ret = -1;
			if ((gBootVolume->flags & kBVFlagBooter) && !bootFileWithDevice) {
				snprintf(bootFilePath, sizeof(bootFilePath), "com.apple.boot.P%s", bootFile);
				ret = GetFileInfo(NULL, bootFilePath, &flags, &time);
				if (ret == -1)
				{
					snprintf(bootFilePath, sizeof(bootFilePath), "com.apple.boot.R%s", bootFile);
					ret = GetFileInfo(NULL, bootFilePath, &flags, &time);
					if (ret == -1)
					{
						snprintf(bootFilePath, sizeof(bootFilePath), "com.apple.boot.S%s", bootFile);
						ret = GetFileInfo(NULL, bootFilePath, &flags, &time);
					}
				}
			}
			if (ret == -1) {
				// No alternate location found, using the original kernel image path.
				strlcpy(bootFilePath, bootFile, sizeof(bootFilePath));
			}

			DBG("Loading kernel: '%s'\n", bootFilePath);
			ret = LoadThinFatFile(bootFilePath, &binary);
			if (ret <= 0 && archCpuType == CPU_TYPE_X86_64)
			{
				archCpuType = CPU_TYPE_I386;
				ret = LoadThinFatFile(bootFilePath, &binary);
			}
		} while (0);

		clearActivityIndicator();

#if DEBUG
		printf("Pausing...");
		sleep(8);
#endif

		if (ret <= 0)
		{
			printf("Can't find %s\n", bootFile);
			sleep(1);

			if (gBootFileType == kNetworkDeviceType) {
				// Return control back to PXE. Don't unload PXE base code.
				gUnloadPXEOnExit = false;
				break;
			}
			pause();

		} else {
			/* Won't return if successful. */
			ret = ExecKernel(binary);
		}
	}

	// chainboot
	if (status == 1) {
		// if we are already in graphics-mode,
		if (getVideoMode() == GRAPHICS_MODE) {
			setVideoMode(VGA_TEXT_MODE, 0); // switch back to text mode.
		}
	}

	if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit) {
		nbpUnloadBaseCode();
	}
}
Exemple #16
0
/** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint 
 * struct has been created by smbios_dry_run, update each table struct content of new smbios
 * int the new allocated table address of size newsmbios->tablelength.
 */
static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
{
	char *smbiostables;
	char *tablesptr, *newtablesptr;
	int origsmbiosnum;
	// bitmask of used handles
	uint8_t handles[8192]; 
	uint16_t nexthandle=0;
	int i, j;
	int tablespresent[256];
	bool do_auto=true;
        
        extern void dumpPhysAddr(const char * title, void * a, int len);

	bzero(tablespresent, sizeof(tablespresent));
	bzero(handles, sizeof(handles));

	getBoolForKey(kSMBIOSdefaults, &do_auto, &bootInfo->bootConfig);
	
	newsmbios->dmi.tableAddress = (uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
	if (origsmbios) {
		smbiostables = (char *)origsmbios->dmi.tableAddress;
		origsmbiosnum = origsmbios->dmi.structureCount;
	} else {
		smbiostables = NULL;
		origsmbiosnum = 0;
	}
	tablesptr = smbiostables;
	newtablesptr = (char *)newsmbios->dmi.tableAddress;

        // if old smbios exists then update new smbios  with old smbios original content first
	if (smbiostables) {
		for (i=0; i<origsmbiosnum; i++) {
			struct smbios_table_header	*oldcur = (struct smbios_table_header *) tablesptr;
			struct smbios_table_header	*newcur = (struct smbios_table_header *) newtablesptr;
			char				*stringsptr;
			int				nstrings = 0;

			handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);

                        // copy table length from old table to new table but not the old strings
			memcpy(newcur,oldcur, oldcur->length);

			tablesptr += oldcur->length;
			stringsptr = tablesptr;
			newtablesptr += oldcur->length;

                        // calculate the number of strings in the old content
			for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
				if (tablesptr[0] == 0) {
					nstrings++;
				}
			}
			if (tablesptr != stringsptr) {
				nstrings++;
			}
			tablesptr += 2;

                        // copy the old strings to new table
			memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);

 			// point to next possible space for a string (deducting the second 0 char at the end)
			newtablesptr += tablesptr - stringsptr - 1;
                            if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator
				newtablesptr--;
			}

                        // now for each property in the table update the overrides if any (auto or user)
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				int		num;
				char		altname[40];

				sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
				if (smbios_properties[j].table_type == newcur->type) {
					switch (smbios_properties[j].value_type) {
					case SMSTRING:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						} else if (do_auto && smbios_properties[j].auto_str) {
							str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size = strlen(str);
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						}
						break;

					case SMOWORD:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							int		k=0, t=0, kk=0;
							const char	*ptr = str;
							memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
								ptr++;
							}
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
								ptr += 2;
							}
							for (;ptr-str<size && *ptr && k<16;ptr++) {
								if (*ptr>='0' && *ptr<='9') {
									(t=(t<<4)|(*ptr-'0')),kk++;
								}
								if (*ptr>='a' && *ptr<='f') {
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								}
								if (*ptr>='A' && *ptr<='F') {
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								}
								if (kk == 2) {
									*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
									k++;
									kk = 0;
									t = 0;
								}
							}
						}
						break;

					case SMBYTE:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);							
						}
						break;

					case SMWORD:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
					}
				}
			}
			if (nstrings == 0) {
				newtablesptr[0] = 0;
				newtablesptr++;
			}
			newtablesptr[0] = 0;
			newtablesptr++;
			tablespresent[newcur->type]++;
		}
	}

        // for each eventual complementary table not present in the original smbios, do the overrides
	for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
		int	numnec = -1;
		char	buffer[40];

		sprintf(buffer, "SMtable%d", i);
		if (!getIntForKey(buffer, &numnec, &bootInfo->smbiosConfig)) {
			numnec = -1;
		}
		if (numnec == -1 && do_auto && smbios_table_descriptions[i].numfunc) {
			numnec = smbios_table_descriptions[i].numfunc(smbios_table_descriptions[i].type);
		}
		while (tablespresent[smbios_table_descriptions[i].type] < numnec) {
			struct smbios_table_header	*newcur = (struct smbios_table_header *) newtablesptr;
			int				nstrings = 0;

			memset(newcur,0, smbios_table_descriptions[i].len);
			while (handles[(nexthandle)/8] & (1 << ((nexthandle) % 8))) {
				nexthandle++;
			}
			newcur->handle = nexthandle;
			handles[nexthandle / 8] |= 1 << (nexthandle % 8);
			newcur->type = smbios_table_descriptions[i].type;
			newcur->length = smbios_table_descriptions[i].len;
			newtablesptr += smbios_table_descriptions[i].len;
			for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
				const char	*str;
				int		size;
				int		num;
				char		altname[40];

				sprintf(altname, "%s_%d", smbios_properties[j].name, tablespresent[newcur->type] + 1);
				if (smbios_properties[j].table_type == newcur->type) {
					switch (smbios_properties[j].value_type) {
					case SMSTRING:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						} else if (do_auto && smbios_properties[j].auto_str) {
							str = smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size = strlen(str);
							memcpy(newtablesptr, str, size);
							newtablesptr[size] = 0;
							newtablesptr += size + 1;
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = ++nstrings;
						}
						break;

					case SMOWORD:
						if (getValueForKey(altname, &str, &size, &bootInfo->smbiosConfig) ||
						    getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig))
						{
							int		k=0, t=0, kk=0;
							const char	*ptr = str;

							memset(((char*)newcur) + smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n')) {
								ptr++;
							}
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X')) {
								ptr += 2;
							}
							for (;ptr-str<size && *ptr && k<16;ptr++) {
								if (*ptr>='0' && *ptr<='9') {
									(t=(t<<4)|(*ptr-'0')),kk++;
								}
								if (*ptr>='a' && *ptr<='f') {
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								}
								if (*ptr>='A' && *ptr<='F') {
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								}
								if (kk == 2) {
									*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset + k)) = t;
									k++;
									kk = 0;
									t = 0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint8_t*)(((char*)newcur) + smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
						
					case SMWORD:
						if (getIntForKey(altname, &num, &bootInfo->smbiosConfig) ||
						    getIntForKey(smbios_properties[j].name, &num, &bootInfo->smbiosConfig))
						{
							*((uint16_t*)(((char*)newcur) + smbios_properties[j].offset)) = num;
						} else if (do_auto && smbios_properties[j].auto_int) {
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset)) = smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						}
						break;
					}
				}
			}
			if (nstrings == 0) {
				newtablesptr[0] = 0;
				newtablesptr++;
			}
			newtablesptr[0] = 0;
			newtablesptr++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}

        // calculate new checksums
	newsmbios->dmi.checksum = 0;
	newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
	newsmbios->checksum = 0;
	newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
	verbose("Patched DMI Table\n");
}
Exemple #17
0
static void setupEfiDeviceTree(void)
{
	Node		*node;
	const char	*value;
	int		len;
	bool		doit;

	if ((node = DT__FindNode("/", false)) == NULL) {
		stop("Couldn't find EFI root node");
	}

	/* Export system-type. Allowed values are:
	 * 0x01 for desktop computer (default)
	 * 0x02 for portable computers
	 */
	SystemType[0] = 1;
	if (getValueForKey(kSystemType, &value, &len, &bootInfo->bootConfig) && value != NULL) {
		SystemType[0] = (unsigned char) strtoul(value, NULL, 10);
		if (SystemType[0] != 1 && SystemType[0] != 2) {
			verbose("Error: system-type must be 1 (desktop) or 2 (portable). Defaulting to 1!\n");
			SystemType[0] = 1;
		}
	}
	verbose("Using system-type=0x%02x\n", SystemType[0]);
	DT__AddProperty(node, SystemType_prop, sizeof(SystemType), &SystemType);

	/* We could also just do DT__FindNode("/efi/platform", true)
	 * But I think eventually we want to fill stuff in the efi node
	 * too so we might as well create it so we have a pointer for it too.
	 */
	node = DT__AddChild(node, "efi");

	DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
	DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_PROP_VALUE), (char*)FIRMWARE_ABI_PROP_VALUE);
	DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);

	/* TODO: Fill in other efi properties if necessary */

	/* Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
	 * is set up.  That is, name and table properties
	 */
	Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");

	/* The value of the table property is the 32-bit physical address for the RuntimeServices table.
	 * Sice the EFI system table already has a pointer to it, we simply use the address of that pointer
	 * for the pointer to the property data.  Warning.. DT finalization calls free on that but we're not
	 * the only thing to use a non-malloc'd pointer for something in the DT
	 */
	DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST->RuntimeServices);

	/* Set up the /efi/configuration-table node which will eventually have several child nodes for
	 * all of the configuration tables needed by various kernel extensions.
	 */
	gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");

	/* Now fill in the /efi/platform Node */
	Node *efiPlatformNode = DT__AddChild(node, "platform");

	/* NOTE WELL: If you do add FSB Frequency detection, make sure to store
	 * the value in the fsbFrequency global and not an malloc'd pointer
	 * because the DT_AddProperty function does not copy its args.
	 */
	if(Platform.CPU.FSBFrequency != 0) {
		DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency);
	}

	/* Export TSC and CPU frequencies for use by the kernel or KEXTs */
	if(Platform.CPU.TSCFrequency != 0) {
		DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency);
	}
	if(Platform.CPU.CPUFrequency != 0) {
		DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency);
	}

	/* Export system-id. Can be disabled with system-id=No in com.apple.Boot.plist */
	doit = true;
	getBoolForKey(kSystemID, &doit, &bootInfo->bootConfig);
	if (doit) {
		DT__AddProperty(efiPlatformNode, SystemID_prop, sizeof(SystemID), &SystemID);
	}
	/* Export SystemSerialNumber if present */
	if (SystemSerialLength > 0) {
		DT__AddProperty(efiPlatformNode, SystemSerial_prop, SystemSerialLength, &SystemSerial);
	}
	/* Export Model if present */
	if (ModelLength > 0) {
		DT__AddProperty(efiPlatformNode, Model_prop, ModelLength, &Model);
	}

	/* Fill /efi/device-properties node */
	setupDeviceProperties(node);
}
Exemple #18
0
/* Compute necessary space requirements for new smbios */
struct SMBEntryPoint *
smbios_dry_run (struct SMBEntryPoint * origsmbios)
{
	struct SMBEntryPoint *ret;
	char *smbiostables=0;
	char *tablesptr;
	int origsmbiosnum=0;
	int i, j;
	int tablespresent[256];
	BOOL do_auto=1;

	getBoolForKey("SMBIOSdefaults",&do_auto,&bootInfo->bootConfig);

	for (i=0;i<256;i++)
		tablespresent[i]=0;
	ret=(struct SMBEntryPoint *)AllocateKernelMemory(sizeof (struct SMBEntryPoint));
	if (origsmbios)
	{
		smbiostables=(char *)origsmbios->dmi.tableAddress;
		origsmbiosnum=origsmbios->dmi.structureCount;
    }
	// _SM_
	ret->anchor[0]=0x5f;
	ret->anchor[1]=0x53;
	ret->anchor[2]=0x4d;
	ret->anchor[3]=0x5f; 
	ret->entryPointLength=sizeof (*ret);
	ret->majorVersion=2;
	ret->minorVersion=1;
	ret->maxStructureSize=0; 
	ret->entryPointRevision=0;
	for (i=0;i<5;i++)
		ret->formattedArea[i]=0;
	//_DMI_
	ret->dmi.anchor[0]=0x5f;
	ret->dmi.anchor[1]=0x44;
	ret->dmi.anchor[2]=0x4d;
	ret->dmi.anchor[3]=0x49;
	ret->dmi.anchor[4]=0x5f;
	ret->dmi.tableLength=0; 
	ret->dmi.tableAddress=0; 
	ret->dmi.structureCount=0; 
	ret->dmi.bcdRevision=0x21;
	tablesptr=smbiostables;
	if (smbiostables)
		for (i=0;i<origsmbiosnum;i++)
		{
			struct smbios_table_header *cur
			=(struct smbios_table_header *) tablesptr;
			char *stringsptr;
			int stringlen;
			tablesptr+=cur->length;
			stringsptr=tablesptr;
			for (;tablesptr[0]!=0 || tablesptr[1]!=0;tablesptr++);
			tablesptr+=2;
			stringlen=tablesptr-stringsptr-1;
			if (stringlen==1)
				stringlen=0;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[cur->type]+1);				
				if (smbios_properties[j].table_type==cur->type 
					&& smbios_properties[j].value_type==SMSTRING
					&& (getValueForKey(smbios_properties[j].name, &str, &size, &bootInfo->smbiosConfig)
					    || getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)))
					stringlen+=size+1;
				else if (smbios_properties[j].table_type==cur->type 
						 && smbios_properties[j].value_type==SMSTRING
						 && do_auto && smbios_properties[j].auto_str)
					stringlen+=strlen(smbios_properties[j].auto_str(smbios_properties[j].name,tablespresent[cur->type]))+1;
			}
			if (stringlen==0)
				stringlen=1;
			stringlen++;
			if (ret->maxStructureSize<cur->length+stringlen)
				ret->maxStructureSize=cur->length+stringlen;
			ret->dmi.tableLength+=cur->length+stringlen;
			ret->dmi.structureCount++;
			tablespresent[cur->type]++;
		}
	for (i=0;i<sizeof (smbios_table_descriptions)
		 /sizeof(smbios_table_descriptions[0]);i++)
	{
		int numnec=-1;
		char buffer[40];
		sprintf (buffer, "SMtable%d", i);
		if (!getIntForKey(buffer,&numnec,&bootInfo->smbiosConfig))
			numnec=-1;
		if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc)
			numnec=smbios_table_descriptions[i].numfunc (smbios_table_descriptions[i].type);
		
		while (tablespresent[smbios_table_descriptions[i].type]<numnec)
		{
			int stringlen=0;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[smbios_table_descriptions[i].type]+1);
				if (smbios_properties[j].table_type
					==smbios_table_descriptions[i].type 
					&& smbios_properties[j].value_type==SMSTRING
					&& (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
						|| getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig)))
					stringlen+=size+1; 
				else if (smbios_properties[j].table_type
						 ==smbios_table_descriptions[i].type 
						 && smbios_properties[j].value_type==SMSTRING
						 && do_auto && smbios_properties[j].auto_str)
					stringlen+=strlen(smbios_properties[j].auto_str
									  (smbios_properties[j].name,
									   tablespresent[smbios_table_descriptions[i].type]))+1;
			}
			if (stringlen==0)
				stringlen=1;
			stringlen++;
			if (ret->maxStructureSize<smbios_table_descriptions[i].len+stringlen)
				ret->maxStructureSize=smbios_table_descriptions[i].len+stringlen;
			ret->dmi.tableLength+=smbios_table_descriptions[i].len+stringlen;
			ret->dmi.structureCount++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}
	return ret;
}
Exemple #19
0
bool GameInfoSave::isMan(int userid)
{
	string str = "gender";
	str.append(int2string(userid).c_str());
	return getBoolForKey(str.c_str(), true);
}
Exemple #20
0
void
smbios_real_run (struct SMBEntryPoint * origsmbios,
				 struct SMBEntryPoint * newsmbios)
{
	char *smbiostables=0;
	char *tablesptr, *newtablesptr;
	int origsmbiosnum=0;
	// bitmask of used handles
	uint8_t handles[8192]; 
	uint16_t nexthandle=0;
	int i, j;
	int tablespresent[256];
	BOOL do_auto=1;
	
	getBoolForKey("SMBIOSdefaults",&do_auto,&bootInfo->bootConfig);
	
	for (i=0;i<256;i++)
		tablespresent[i]=0;
	
	memset (handles,0,8192);
	newsmbios->dmi.tableAddress=(uint32_t)AllocateKernelMemory(newsmbios->dmi.tableLength);
	if (origsmbios)
    {
		smbiostables=(char *) origsmbios->dmi.tableAddress;
		origsmbiosnum=origsmbios->dmi.structureCount;
    }
	tablesptr=smbiostables;
	newtablesptr=(char *) newsmbios->dmi.tableAddress;
	if (smbiostables)
		for (i=0;i<origsmbiosnum;i++)
		{
			struct smbios_table_header *oldcur
			=(struct smbios_table_header *) tablesptr,
			*newcur=(struct smbios_table_header *) newtablesptr;
			char *stringsptr;
			int nstrings=0;
			
			handles[(oldcur->handle)/8]|=1<<((oldcur->handle)%8);
			
			memcpy (newcur,oldcur, oldcur->length);
			
			tablesptr+=oldcur->length;
			stringsptr=tablesptr;
			newtablesptr+=oldcur->length;
			for (;tablesptr[0]!=0 || tablesptr[1]!=0;tablesptr++)
				if (tablesptr[0]==0)
					nstrings++;
			if (tablesptr!=stringsptr)
				nstrings++;
			tablesptr+=2;
			memcpy (newtablesptr,stringsptr,tablesptr-stringsptr);
			//point to next possible space for a string
			newtablesptr+=tablesptr-stringsptr-1;
			if (nstrings==0)
				newtablesptr--;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				int num;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[newcur->type]+1);				
				
				if (smbios_properties[j].table_type==newcur->type)
					switch (smbios_properties[j].value_type)
				{
					case SMSTRING:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						else if (do_auto && smbios_properties[j].auto_str)
						{
							str=smbios_properties[j].auto_str(smbios_properties[j].name,tablespresent[newcur->type]);
							size=strlen (str);
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						
						break;
						
					case SMOWORD:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							int k=0, t=0, kk=0;
							const char *ptr=str;
							memset(((char*)newcur)+smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'))
								ptr++;
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X'))
								ptr+=2;
							for (;ptr-str<size && *ptr && k<16;ptr++)
							{
								if (*ptr>='0' && *ptr<='9')
									(t=(t<<4)|(*ptr-'0')),kk++;
								if (*ptr>='a' && *ptr<='f')
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								if (*ptr>='A' && *ptr<='F')
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								if (kk==2)
								{
									*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset+k))=t;
									k++;
									kk=0;
									t=0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);							
						break;
						
					case SMWORD:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
				}
			}
			if (nstrings==0)
			{
				newtablesptr[0]=0;
				newtablesptr++;
			}
			newtablesptr[0]=0;
			newtablesptr++;
			tablespresent[newcur->type]++;
		}
	for (i=0;i<sizeof (smbios_table_descriptions)
		 /sizeof(smbios_table_descriptions[0]);i++)
	{
		int numnec=-1;
		char buffer[40];
		sprintf (buffer, "SMtable%d", i);
		if (!getIntForKey(buffer,&numnec,&bootInfo->smbiosConfig))
			numnec=-1;
		if (numnec==-1 && do_auto && smbios_table_descriptions[i].numfunc)
			numnec=smbios_table_descriptions[i].numfunc (smbios_table_descriptions[i].type);
		
		while (tablespresent[smbios_table_descriptions[i].type]<numnec)
		{
			struct smbios_table_header *newcur=(struct smbios_table_header *) newtablesptr;
			int nstrings=0;
			
			memset (newcur,0, smbios_table_descriptions[i].len);
			while (handles[(nexthandle)/8]&(1<<((nexthandle)%8)))
				nexthandle++;
			newcur->handle=nexthandle;
			handles[nexthandle/8]|=1<<(nexthandle%8);
			newcur->type=smbios_table_descriptions[i].type;
			newcur->length=smbios_table_descriptions[i].len;
			newtablesptr+=smbios_table_descriptions[i].len;
			for (j=0;j<sizeof (smbios_properties)/sizeof(smbios_properties[0]);
				 j++)
			{
				const char *str;
				int size;
				int num;
				char altname[40];
				sprintf (altname, "%s_%d",smbios_properties[j].name,
						 tablespresent[newcur->type]+1);				
				
				if (smbios_properties[j].table_type==newcur->type)
					switch (smbios_properties[j].value_type)
				{
					case SMSTRING:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}
						else if (do_auto && smbios_properties[j].auto_str)
						{
							str=smbios_properties[j].auto_str(smbios_properties[j].name, tablespresent[newcur->type]);
							size=strlen (str);
							memcpy (newtablesptr, str,size);
							newtablesptr[size]=0;
							newtablesptr+=size+1;
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=++nstrings;
						}						
						break;
						
					case SMOWORD:
						if (getValueForKey(altname,&str, &size, &bootInfo->smbiosConfig)
							||getValueForKey(smbios_properties[j].name,&str, &size, &bootInfo->smbiosConfig))
						{
							int k=0, t=0, kk=0;
							const char *ptr=str;
							memset(((char*)newcur)+smbios_properties[j].offset, 0, 16);
							while (ptr-str<size && *ptr && (*ptr==' ' || *ptr=='\t' || *ptr=='\n'))
								ptr++;
							if (size-(ptr-str)>=2 && ptr[0]=='0' && (ptr[1]=='x' || ptr[1]=='X'))
								ptr+=2;
							for (;ptr-str<size && *ptr && k<16;ptr++)
							{
								if (*ptr>='0' && *ptr<='9')
									(t=(t<<4)|(*ptr-'0')),kk++;
								if (*ptr>='a' && *ptr<='f')
									(t=(t<<4)|(*ptr-'a'+10)),kk++;
								if (*ptr>='A' && *ptr<='F')
									(t=(t<<4)|(*ptr-'A'+10)),kk++;
								if (kk==2)
								{
									*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset+k))=t;
									k++;
									kk=0;
									t=0;
								}
							}
						}
						break;
						
					case SMBYTE:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint8_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
						
					case SMWORD:
						if (getIntForKey(altname,&num,&bootInfo->smbiosConfig)
							||getIntForKey(smbios_properties[j].name,&num,&bootInfo->smbiosConfig))
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))=num;
						else if (do_auto && smbios_properties[j].auto_int)
							*((uint16_t*)(((char*)newcur)+smbios_properties[j].offset))
							=smbios_properties[j].auto_int(smbios_properties[j].name, tablespresent[newcur->type]);
						break;
				}
			}
			if (nstrings==0)
			{
				newtablesptr[0]=0;
				newtablesptr++;
			}
			newtablesptr[0]=0;
			newtablesptr++;
			tablespresent[smbios_table_descriptions[i].type]++;
		}
	}
	newsmbios->dmi.checksum=0;
	newsmbios->dmi.checksum=256-checksum8 (&newsmbios->dmi,sizeof (newsmbios->dmi));
	newsmbios->checksum=0;
	newsmbios->checksum=256-checksum8 (newsmbios,sizeof (*newsmbios));
	verbose("Patched DMI Table.\n");
}
Exemple #21
0
void loadThemeValues(config_file_t *theme, BOOL overide)
{
	BOOL themeEnabled;

	if ( (getBoolForKey("Enabled", &themeEnabled, theme ) ) || ( overide ) )
	{
		unsigned int screen_width  = gui.screen.width;
		unsigned int screen_height = gui.screen.height;
		
		unsigned int pixel;
		
		int	alpha;				// transparency level 0 (obligue) - 255 (transparent)
		
		uint32_t color;			// color value formatted RRGGBB

		int val, len;
		const char *string;	
		
		/*
		 * Parse screen parameters
		 */
		
		if(getColorForKey("screen_bgcolor", &color, theme ))
			gui.screen.bgcolor = (color & 0x00FFFFFF);

		if(getIntForKey("screen_textmargin_h", &val, theme))
			gui.screen.hborder = MIN( gui.screen.width , val );
		
		if(getIntForKey("screen_textmargin_v", &val, theme))
			gui.screen.vborder = MIN( gui.screen.height , val );

		/*
		 * Parse background parameters
		 */
		
		if(getDimensionForKey("background_pos_x", &pixel, theme, screen_width , images[iBackground].image->width ) )
			gui.background.pos.x = pixel;

		if(getDimensionForKey("background_pos_y", &pixel, theme, screen_height , images[iBackground].image->height ) )
			gui.background.pos.y = pixel;
		
		/*
		 * Parse logo parameters
		 */

		if(getDimensionForKey("logo_pos_x", &pixel, theme, screen_width , images[iLogo].image->width ) )
			gui.logo.pos.x = pixel;
		
		if(getDimensionForKey("logo_pos_y", &pixel, theme, screen_height , images[iLogo].image->height ) )
			gui.logo.pos.y = pixel;

		/*
		 * Parse progress bar parameters
		 */
		
		if(getDimensionForKey("progressbar_pos_x", &pixel, theme, screen_width , 0 ) )
			gui.progressbar.pos.x = pixel;
		
		if(getDimensionForKey("progressbar_pos_y", &pixel, theme, screen_height , 0 ) )
			gui.progressbar.pos.y = pixel;

		/*
		 * Parse countdown text parameters
		 */
		
		if(getDimensionForKey("countdown_pos_x", &pixel, theme, screen_width , 0 ) )
			gui.countdown.pos.x = pixel;
		
		if(getDimensionForKey("countdown_pos_y", &pixel, theme, screen_height , 0 ) )
			gui.countdown.pos.y = pixel;
		
		/*
		 * Parse devicelist parameters
		 */
	
		if(getIntForKey("devices_max_visible", &val, theme ))
			gui.maxdevices = MIN( val, gDeviceCount );
		
		if(getIntForKey("devices_iconspacing", &val, theme ))
			gui.devicelist.iconspacing = val;
		
		// check layout for horizontal or vertical
		if(getValueForKey( "devices_layout", &string, &len, theme ) )
			if (!strcmp (string, "vertical"))		
				gui.layout = VerticalLayout;
			else
				gui.layout = HorizontalLayout;
		else
			gui.layout = HorizontalLayout;
		
		switch (gui.layout)
		{
				
			case VerticalLayout:
				gui.devicelist.height = ( ( images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing ) * MIN( gui.maxdevices, gDeviceCount ) + ( images[iDeviceScrollPrev].image->height + images[iDeviceScrollNext].image->height ) + gui.devicelist.iconspacing );
				gui.devicelist.width  = ( images[iSelection].image->width + gui.devicelist.iconspacing );
				
				if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , images[iSelection].image->width ) )
					gui.devicelist.pos.x = pixel;
				
				if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , gui.devicelist.height ) )
					gui.devicelist.pos.y = pixel;
				
				break;
				
			default:
				
			case HorizontalLayout:
				
				gui.devicelist.width = ( ( images[iSelection].image->width + gui.devicelist.iconspacing ) * MIN( gui.maxdevices, gDeviceCount ) + ( images[iDeviceScrollPrev].image->width + images[iDeviceScrollNext].image->width ) + gui.devicelist.iconspacing );
				gui.devicelist.height = ( images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing );
				
				if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , gui.devicelist.width ) )
					gui.devicelist.pos.x = pixel;
				else
					gui.devicelist.pos.x = ( gui.screen.width - gui.devicelist.width ) / 2;
				
				if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , images[iSelection].image->height ) )
					gui.devicelist.pos.y = pixel;
				else
					gui.devicelist.pos.y = ( gui.screen.height - gui.devicelist.height ) / 2;
				
				break;
		}

		if(getColorForKey("devices_bgcolor", &color, theme))
			gui.devicelist.bgcolor = (color & 0x00FFFFFF);
			
		if(getIntForKey("devices_transparency", &alpha, theme))
			gui.devicelist.bgcolor = gui.devicelist.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);

		/*
		 * Parse infobox parameters
		 */
		
		if(getIntForKey("infobox_width", &val, theme))
			gui.infobox.width = MIN( screen_width , val );
		
		if(getIntForKey("infobox_height", &val, theme))
			gui.infobox.height = MIN( screen_height , val );

		if(getDimensionForKey("infobox_pos_x", &pixel, theme, screen_width , gui.infobox.width ) )
			gui.infobox.pos.x = pixel;
		
		if(getDimensionForKey("infobox_pos_y", &pixel, theme, screen_height , gui.infobox.height ) )
			gui.infobox.pos.y = pixel;
		
		if(getIntForKey("infobox_textmargin_h", &val, theme))
			gui.infobox.hborder = MIN( gui.infobox.width , val );
		
		if(getIntForKey("infobox_textmargin_v", &val, theme))
			gui.infobox.vborder = MIN( gui.infobox.height , val );

		if(getColorForKey("infobox_bgcolor", &color, theme))
			gui.infobox.bgcolor = (color & 0x00FFFFFF);
		
		if(getIntForKey("infobox_transparency", &alpha, theme))
			gui.infobox.bgcolor = gui.infobox.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);
	
		/*
		 * Parse menu parameters
		 */
			
		if(getDimensionForKey("menu_width", &pixel, theme, gui.screen.width , 0 ) )
			gui.menu.width = pixel;
		else
			gui.menu.width = images[iMenuSelection].image->width;
		
		if(getDimensionForKey("menu_height", &pixel, theme, gui.screen.height , 0 ) )
			gui.menu.height = pixel;
		else
			gui.menu.height = (infoMenuItemsCount) * images[iMenuSelection].image->height;
	
		
		if(getDimensionForKey("menu_pos_x", &pixel, theme, screen_width , gui.menu.width ) )
			gui.menu.pos.x = pixel;
		
		if(getDimensionForKey("menu_pos_y", &pixel, theme, screen_height , gui.menu.height ) )
			gui.menu.pos.y = pixel;

		if(getIntForKey("menu_textmargin_h", &val, theme))
			gui.menu.hborder = MIN( gui.menu.width , val );
		
		if(getIntForKey("menu_textmargin_v", &val, theme))
			gui.menu.vborder = MIN( gui.menu.height , val );

		if(getColorForKey("menu_bgcolor", &color, theme))
			gui.menu.bgcolor = (color & 0x00FFFFFF);
		
		if(getIntForKey("menu_transparency", &alpha, theme))
			gui.menu.bgcolor = gui.menu.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);		
		
		/*
		 * Parse bootprompt parameters
		 */

		if(getDimensionForKey("bootprompt_width", &pixel, theme, screen_width , 0 ) )
			gui.bootprompt.width = pixel;
		
		if(getIntForKey("bootprompt_height", &val, theme))
			gui.bootprompt.height = MIN( screen_height , val );

		if(getDimensionForKey("bootprompt_pos_x", &pixel, theme, screen_width , gui.bootprompt.width ) )
			gui.bootprompt.pos.x = pixel;
		
		if(getDimensionForKey("bootprompt_pos_y", &pixel, theme, screen_height , gui.bootprompt.height ) )
			gui.bootprompt.pos.y = pixel;
		
		if(getIntForKey("bootprompt_textmargin_h", &val, theme))
			gui.bootprompt.hborder = MIN( gui.bootprompt.width , val );
	
		if(getIntForKey("bootprompt_textmargin_v", &val, theme))
			gui.bootprompt.vborder = MIN( gui.bootprompt.height , val );

		if(getColorForKey("bootprompt_bgcolor", &color, theme))
			gui.bootprompt.bgcolor = (color & 0x00FFFFFF);
			
		if(getIntForKey("bootprompt_transparency", &alpha, theme))
			gui.bootprompt.bgcolor = gui.bootprompt.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);
		
		if(getColorForKey("font_small_color", &color, theme))
			gui.screen.font_small_color = (color & 0x00FFFFFF);
		
		if(getColorForKey("font_console_color", &color, theme))
			gui.screen.font_console_color = (color & 0x00FFFFFF);
		
	}
	
}
Exemple #22
0
bool setup_hda_devprop(pci_dt_t *hda_dev)
{
	struct		DevPropDevice	*device = NULL;
	char		*devicepath = NULL;
	char		*controller_name = NULL;
	int		len;
	uint8_t		BuiltIn = 0x00;
	uint16_t	controller_vendor_id = hda_dev->vendor_id;
	uint16_t	controller_device_id = hda_dev->device_id;
	const char	*value;

	// Skip keys
	bool do_skip_n_devprop = false;
	bool do_skip_a_devprop = false;
	getBoolForKey(kSkipNvidiaGfx, &do_skip_n_devprop, &bootInfo->chameleonConfig);
	getBoolForKey(kSkipAtiGfx, &do_skip_a_devprop, &bootInfo->chameleonConfig);

	verbose("\tClass code: [%04X]\n", hda_dev->class_id);

	devicepath = get_pci_dev_path(hda_dev);
	controller_name = get_hda_controller_name(controller_device_id, controller_vendor_id);

	if (!string)
	{
		string = devprop_create_string();
		if (!string)
		{
			return 0;
		}
	}

	if (!devicepath)
	{
		return 0;
	}

	device = devprop_add_device(string, devicepath);
	if (!device)
	{
		return 0;
	}

	verbose("\tModel name: %s [%04x:%04x] (rev %02x)\n\tSubsystem: [%04x:%04x]\n\t%s\n",
		 controller_name, hda_dev->vendor_id, hda_dev->device_id, hda_dev->revision_id,
		hda_dev->subsys_id.subsys.vendor_id, hda_dev->subsys_id.subsys.device_id, devicepath);


	switch ((controller_device_id << 16) | controller_vendor_id)
	{

	/***********************************************************************
	* The above case are intended as for HDEF device at address 0x001B0000
	***********************************************************************/
		case HDA_INTEL_OAK:
		case HDA_INTEL_BAY:
		case HDA_INTEL_HSW1:
		case HDA_INTEL_HSW2:
		case HDA_INTEL_HSW3:
		case HDA_INTEL_BDW:
		case HDA_INTEL_CPT:
		case HDA_INTEL_PATSBURG:
		case HDA_INTEL_PPT1:
		case HDA_INTEL_BRASWELL:
		case HDA_INTEL_82801F:
		case HDA_INTEL_63XXESB:
		case HDA_INTEL_82801G:
		case HDA_INTEL_82801H:
		case HDA_INTEL_82801I:
		case HDA_INTEL_ICH9:
		case HDA_INTEL_82801JI:
		case HDA_INTEL_82801JD:
		case HDA_INTEL_PCH:
		case HDA_INTEL_PCH2:
		case HDA_INTEL_SCH:
		case HDA_INTEL_LPT1:
		case HDA_INTEL_LPT2:
		case HDA_INTEL_WCPT:
		case HDA_INTEL_WELLS1:
		case HDA_INTEL_WELLS2:
		case HDA_INTEL_WCPTLP:
		case HDA_INTEL_LPTLP1:
		case HDA_INTEL_LPTLP2:
		case HDA_INTEL_SRSPLP:
		case HDA_INTEL_SRSP:

			/* if the key value kHDEFLayoutID as a value set that value, if not will assign a default layout */
			if (getValueForKey(kHDEFLayoutID, &value, &len, &bootInfo->chameleonConfig) && len == HDEF_LEN * 2)
			{
				uint8_t new_HDEF_layout_id[HDEF_LEN];
				if (hex2bin(value, new_HDEF_layout_id, HDEF_LEN) == 0)
				{
					memcpy(default_HDEF_layout_id, new_HDEF_layout_id, HDEF_LEN);
					verbose("\tUsing user supplied HDEF layout-id: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
					default_HDEF_layout_id[0], default_HDEF_layout_id[1], default_HDEF_layout_id[2], default_HDEF_layout_id[3]);
				}
			}
			else
			{
				verbose("\tUsing default HDEF layout-id: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
					default_HDEF_layout_id[0], default_HDEF_layout_id[1], default_HDEF_layout_id[2], default_HDEF_layout_id[3]);
			}
			devprop_add_value(device, "layout-id", default_HDEF_layout_id, HDEF_LEN);
			devprop_add_value(device, "AAPL,slot-name", (uint8_t *)"Built-in", sizeof("Built-in")); // 0x09
			devprop_add_value(device, "name", (uint8_t *)"audio", 6); // 0x06
			devprop_add_value(device, "device-type", (uint8_t *)"High Definition Audio Controller", sizeof("High Definition Audio Controller"));
			devprop_add_value(device, "device_type", (uint8_t *)"Sound", sizeof("Sound"));
			devprop_add_value(device, "built-in", &BuiltIn, 1);
			devprop_add_value(device, "hda-gfx", (uint8_t *)"onboard-1", sizeof("onboard-1")); // 0x0a
			// "AFGLowPowerState" = <03000000>
			break;

	/*****************************************************************************************************************
	 * The above case are intended as for HDAU (NVIDIA) device onboard audio for GFX card with Audio controller HDMi *
	 *****************************************************************************************************************/
		case HDA_NVIDIA_GK107:
		case HDA_NVIDIA_GF110_1:
		case HDA_NVIDIA_GF110_2:
		case HDA_NVIDIA_GK106:
		case HDA_NVIDIA_GK104:
		case HDA_NVIDIA_GF119:
		case HDA_NVIDIA_GT116:
		case HDA_NVIDIA_GT104:
		case HDA_NVIDIA_GT108:
		case HDA_NVIDIA_GT106:
		case HDA_NVIDIA_GT100:
		case HDA_NVIDIA_0BE4:
		case HDA_NVIDIA_0BE3:
		case HDA_NVIDIA_0BE2:
			if ( do_skip_n_devprop )
			{
				verbose("Skip Nvidia audio device!\n");
			}
			else
			{
				/* if the key value kHDAULayoutID as a value set that value, if not will assign a default layout */
				if (getValueForKey(kHDAULayoutID, &value, &len, &bootInfo->chameleonConfig) && len == HDAU_LEN * 2)
				{
					uint8_t new_HDAU_layout_id[HDAU_LEN];
					if (hex2bin(value, new_HDAU_layout_id, HDAU_LEN) == 0)
					{
						memcpy(default_HDAU_layout_id, new_HDAU_layout_id, HDAU_LEN);
						verbose("\tUsing user supplied HDAU layout-id: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
							default_HDAU_layout_id[0], default_HDAU_layout_id[1], default_HDAU_layout_id[2], default_HDAU_layout_id[3]);
					}
				}
				else
				{
					verbose("\tUsing default HDAU layout-id: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
						default_HDAU_layout_id[0], default_HDAU_layout_id[1], default_HDAU_layout_id[2], default_HDAU_layout_id[3]);
				}

				devprop_add_value(device, "layout-id", default_HDAU_layout_id, HDAU_LEN); /*FIX ME*/
				devprop_add_value(device, "@0,connector-type", connector_type_value, 4);
				devprop_add_value(device, "@1,connector-type", connector_type_value, 4);
				devprop_add_value(device, "hda-gfx", (uint8_t *)"onboard-2", sizeof("onboard-2"));
				devprop_add_value(device, "built-in", &BuiltIn, 1);
			}
			break;

		/**************************************************************************************************************
		 * The above case are intended as for HDAU (ATi) device onboard audio for GFX card with Audio controller HDMi *
		 **************************************************************************************************************/
		case HDA_ATI_SB450:
		case HDA_ATI_SB600:
		case HDA_ATI_HUDSON:
		case HDA_ATI_RS600:
		case HDA_ATI_RS690:
		case HDA_ATI_RS780:
		case HDA_ATI_R600:
		case HDA_ATI_RV630:
		case HDA_ATI_RV610:
		case HDA_ATI_RV670:
		case HDA_ATI_RV635:
		case HDA_ATI_RV620:
		case HDA_ATI_RV770:
		case HDA_ATI_RV730:
		case HDA_ATI_RV710:
		case HDA_ATI_RV740:
		case HDA_ATI_RV870:
		case HDA_ATI_RV840:
		case HDA_ATI_RV830:
		case HDA_ATI_RV810:
		case HDA_ATI_RV970:
		case HDA_ATI_RV940:
		case HDA_ATI_RV930:
		case HDA_ATI_RV910:
		case HDA_ATI_R1000:
		case HDA_ATI_SI:
		case HDA_ATI_VERDE:
			if ( do_skip_a_devprop )
			{
				verbose("Skip ATi/AMD audio device!\n");
			}
			else
			{
				/* if the key value kHDAULayoutID as a value set that value, if not will assign a default layout */
				if (getValueForKey(kHDAULayoutID, &value, &len, &bootInfo->chameleonConfig) && len == HDAU_LEN * 2)
				{
					uint8_t new_HDAU_layout_id[HDAU_LEN];
					if (hex2bin(value, new_HDAU_layout_id, HDAU_LEN) == 0)
					{
						memcpy(default_HDAU_layout_id, new_HDAU_layout_id, HDAU_LEN);
						verbose("\tUsing user supplied HDAU layout-id: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
							default_HDAU_layout_id[0], default_HDAU_layout_id[1], default_HDAU_layout_id[2], default_HDAU_layout_id[3]);
					}
				}
				else
				{
					verbose("\tUsing default HDAU layout-id: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
						default_HDAU_layout_id[0], default_HDAU_layout_id[1], default_HDAU_layout_id[2], default_HDAU_layout_id[3]);
				}

				devprop_add_value(device, "layout-id", default_HDAU_layout_id, HDAU_LEN); /*FIX ME*/
				devprop_add_value(device, "hda-gfx", (uint8_t *)"onboard-2", 10);
				devprop_add_value(device, "built-in", &BuiltIn, 1);
			}
			break;

		default:
			break;
	}

	stringdata = malloc(sizeof(uint8_t) * string->length);
	memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
	stringlength = string->length;

	return true;
}
Exemple #23
0
int getBootOptions(bool firstRun)
{
	int     i;
	int     key;
	int     nextRow;
	int     timeout;
	int     bvCount;
	BVRef   bvr;
	BVRef   menuBVR;
	bool    showPrompt, newShowPrompt, isCDROM;

	// Initialize default menu selection entry.
	gBootVolume = menuBVR = selectBootVolume(bvChain);

	if (biosDevIsCDROM(gBIOSDev)) {
		isCDROM = true;
	} else {
		isCDROM = false;
	}

	// ensure we're in graphics mode if gui is setup
	if (gui.initialised && bootArgs->Video.v_display == VGA_TEXT_MODE)
	{
		setVideoMode(GRAPHICS_MODE, 0);
	}

	// Clear command line boot arguments
	clearBootArgs();

	// Allow user to override default timeout.
	if (multiboot_timeout_set) {
		timeout = multiboot_timeout;
	} else if (!getIntForKey(kTimeoutKey, &timeout, &bootInfo->bootConfig)) {
		/*  If there is no timeout key in the file use the default timeout
		    which is different for CDs vs. hard disks.  However, if not booting
		    a CD and no config file could be loaded set the timeout
		    to zero which causes the menu to display immediately.
		    This way, if no partitions can be found, that is the disk is unpartitioned
		    or simply cannot be read) then an empty menu is displayed.
		    If some partitions are found, for example a Windows partition, then
		    these will be displayed in the menu as foreign partitions.
		 */
		if (isCDROM) {
			timeout = kCDBootTimeout;
		} else {
			timeout = sysConfigValid ? kBootTimeout : 0;
		}
	}

	if (timeout < 0) {
		gBootMode |= kBootModeQuiet;
	}

	// If the user is holding down a modifier key, enter safe mode.
	if ((readKeyboardShiftFlags() & 0x0F) != 0) {
		gBootMode |= kBootModeSafe;
	}

	//	 18seven's Quick-args macro
		bool f8 = false, altf = false, shiftf = false, alts = false, 
		altv = false, altx = false; // x32 = false,  x64 = false;
		while (readKeyboardStatus())
		{
			key = bgetc ();
			if (key == 0x4200) f8 = true;
			if (key == 0x2100) altf = true;
			if (key == 0x0046) shiftf = true;
			if (key == 0x1F00) alts = true;
			if (key == 0x2F00) altv = true;
			if (key == 0x2D00) altx = true;
/*			if (key == 0x0004) x32 = true;
			if (key == 0x0007) x64 = true;
*/		}

	// If user typed F8, abort quiet mode, and display the menu.
	if (f8) {
		gBootMode &= ~kBootModeQuiet;
		timeout = 0;
	}

	// If user typed 'alt-v', boot in verbose mode.
	if ((gBootMode & kBootModeQuiet) && firstRun && altv) {
		addBootArg(kVerboseModeFlag);
	}

	// If user typed 'alt-s', boot in single user mode.
	if ((gBootMode & kBootModeQuiet) && firstRun && alts) {
		addBootArg(kSingleUserModeFlag);
	}

	if ((gBootMode & kBootModeQuiet) && firstRun && altf) {
		addBootArg(kIgnoreCachesFlag);
	}

	if ((gBootMode & kBootModeQuiet) && firstRun && shiftf) {
		addBootArg(kIgnoreBootFileFlag);
	}

	if ((gBootMode & kBootModeQuiet) && firstRun && altx) {
		addBootArg(kSafeModeFlag);
	}
/*
	if ((gBootMode & kBootModeQuiet) && firstRun && x32) {
		addBootArg(k32BitModeFlag);
	}

	if ((gBootMode & kBootModeQuiet) && firstRun && x64) {
		addBootArg(k64BitModeFlag);
	}
*/
	if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
		setCursorPosition(0, 0, 0);
		clearScreenRows(0, kScreenLastRow);
		if (!(gBootMode & kBootModeQuiet)) {
			// Display banner and show hardware info.
			printf(bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024);
			printf(getVBEInfoString());
		}
		changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
		verbose("Scanning device %x...", gBIOSDev);
	}

	// When booting from CD, default to hard drive boot when possible.
	if (isCDROM && firstRun) {
		const char *val;
		char *prompt = NULL;
		char *name = NULL;
		int cnt;
		int optionKey;

		if (getValueForKey(kCDROMPromptKey, &val, &cnt, &bootInfo->bootConfig)) {
			prompt = malloc(cnt + 1);
			strncat(prompt, val, cnt);
		} else {
			name = malloc(80);
			getBootVolumeDescription(gBootVolume, name, 79, false);
			prompt = malloc(256);
			sprintf(prompt, "Press any key to start up from %s, or press F8 to enter startup options.", name);
			free(name);
		}

		if (getIntForKey( kCDROMOptionKey, &optionKey, &bootInfo->bootConfig )) {
			// The key specified is a special key.
		} else {
			// Default to F8.
			optionKey = 0x4200;
		}

		// If the timeout is zero then it must have been set above due to the
		// early catch of F8 which means the user wants to set boot options
		// which we ought to interpret as meaning he wants to boot the CD.
		if (timeout != 0) {
			key = countdown(prompt, kMenuTopRow, timeout);
		} else {
			key = optionKey;
		}

		if (prompt != NULL) {
			free(prompt);
		}

		clearScreenRows( kMenuTopRow, kMenuTopRow + 2 );

		// Hit the option key ?
		if (key == optionKey) {
			gBootMode &= ~kBootModeQuiet;
			timeout = 0;
		} else {
			key = key & 0xFF;

			// Try booting hard disk if user pressed 'h'
			if (biosDevIsCDROM(gBIOSDev) && key == 'h') {
				BVRef bvr;

				// Look at partitions hosting OS X other than the CD-ROM
				for (bvr = bvChain; bvr; bvr=bvr->next) {
					if ((bvr->flags & kBVFlagSystemVolume) && bvr->biosdev != gBIOSDev) {
						gBootVolume = bvr;
					}
				}
			}
			goto done;
		}
	}

	if (gBootMode & kBootModeQuiet) {
		// No input allowed from user.
		goto done;
	}

	if (firstRun && timeout > 0 && countdown("Press any key to enter startup options.", kMenuTopRow, timeout) == 0) {
		// If the user is holding down a modifier key,
		// enter safe mode.
		if ((readKeyboardShiftFlags() & 0x0F) != 0) {
			gBootMode |= kBootModeSafe;
		}
		goto done;
	}

	if (gDeviceCount) {
		// Allocate memory for an array of menu items.
		menuItems = malloc(sizeof(MenuItem) * gDeviceCount);
		if (menuItems == NULL) {
			goto done;
		}

		// Associate a menu item for each BVRef.
		for (bvr=bvChain, i=gDeviceCount-1, selectIndex=0; bvr; bvr=bvr->next) {
			if (bvr->visible) {
				getBootVolumeDescription(bvr, menuItems[i].name, sizeof(menuItems[i].name) - 1, true);
				menuItems[i].param = (void *) bvr;
				if (bvr == menuBVR) {
					selectIndex = i;
				}
				i--;
			}
		}
	}

	if (bootArgs->Video.v_display == GRAPHICS_MODE) {
		// redraw the background buffer
		gui.logo.draw = true;
		drawBackground();
		gui.devicelist.draw = true;
		gui.redraw = true;
		if (!(gBootMode & kBootModeQuiet)) {
			bool showBootBanner = true;
 
			// Check if "Boot Banner"=N switch is present in config file.
			getBoolForKey(kBootBannerKey, &showBootBanner, &bootInfo->bootConfig); 
			if (showBootBanner) {
				// Display banner and show hardware info.
				gprintf(&gui.screen, bootBanner + 1, (bootInfo->convmem + bootInfo->extmem) / 1024);
			}

			// redraw background
			memcpy(gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4);
		}
	} else {
		// Clear screen and hide the blinking cursor.
		clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
		changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);
	}

	nextRow = kMenuTopRow;
	showPrompt = true;

	if (gDeviceCount) {
		if( bootArgs->Video.v_display == VGA_TEXT_MODE ) {
			printf("Use \30\31 keys to select the startup volume.");
		}
		showMenu( menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems );
		nextRow += min( gDeviceCount, kMenuMaxItems ) + 3;
	}

	// Show the boot prompt.
	showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
	showBootPrompt( nextRow, showPrompt );
	
	do {
		if (bootArgs->Video.v_display == GRAPHICS_MODE) {
			// redraw background
			memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
			// reset cursor co-ords
			gui.debug.cursor = pos( gui.screen.width - 160 , 10 );
		}
		key = getc();
		updateMenu( key, (void **) &menuBVR );
		newShowPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);

		if (newShowPrompt != showPrompt) {
			showPrompt = newShowPrompt;
			showBootPrompt( nextRow, showPrompt );
		}

		if (showPrompt) {
			updateBootArgs(key);
		}

		switch (key) {
		case kReturnKey:
			if (gui.menu.draw) { 
				key=0;
				break;
			}
			if (*gBootArgs == '?') {
				char * argPtr = gBootArgs;

				// Skip the leading "?" character.
				argPtr++;
				getNextArg(&argPtr, booterCommand);
				getNextArg(&argPtr, booterParam);

				/*
				* TODO: this needs to be refactored.
				*/
				if (strcmp( booterCommand, "video" ) == 0) {
					if (bootArgs->Video.v_display == GRAPHICS_MODE) {
						showInfoBox(getVBEInfoString(), getVBEModeInfoString());
					} else {
						printVBEModeInfo();
					}
				} else if ( strcmp( booterCommand, "memory" ) == 0) {
					if (bootArgs->Video.v_display == GRAPHICS_MODE ) {
						showInfoBox("Memory Map", getMemoryInfoString());
					} else {
						printMemoryInfo();
					}
				} else if (strcmp(booterCommand, "lspci") == 0) {
					lspci();
				} else if (strcmp(booterCommand, "more") == 0) {
					showTextFile(booterParam);
				} else if (strcmp(booterCommand, "rd") == 0) {
					processRAMDiskCommand(&argPtr, booterParam);
				} else if (strcmp(booterCommand, "norescan") == 0) {
					if (gEnableCDROMRescan) {
						gEnableCDROMRescan = false;
						break;
					}
				} else {
					showHelp();
				}
				key = 0;
				showBootPrompt(nextRow, showPrompt);
				break;
			}
			gBootVolume = menuBVR;
			setRootVolume(menuBVR);
			gBIOSDev = menuBVR->biosdev;
			break;

		case kEscapeKey:
			clearBootArgs();
			break;
		
		case kF2Key:
			
			/*
			 * AutoResolution - Reapply the patch if Graphics Mode was incorrect or EDID Info was insane
			 */
			
			if ((gAutoResolution == TRUE) && map)
			{
				// get the new Graphics Mode key
				processBootOptions();
				
				UInt32 params[4];
				params[3] = 0;
				//Has the target Resolution Changed ?
				int count = getNumberArrayFromProperty(kGraphicsModeKey, params, 4);
				if ( count < 3 )
					getResolution(params);
				
				if ((params[0] != 0) && (params[1] != 0)
				&& (params[0] != map->currentX) && (params[1] != map->currentY))
				{
				
					//Go back to TEXT mode while we change  the mode
					if (bootArgs->Video.v_display == GRAPHICS_MODE)
					{
						CursorState cursorState;
						
						setVideoMode(VGA_TEXT_MODE, 0);
						
						setCursorPosition(0, 0, 0);
						clearScreenRows(0, kScreenLastRow);
						changeCursor( 0, 0, kCursorTypeHidden, &cursorState );
						
						//Reapply patch in case resolution have changed
						
						patchVbios(map, params[0], params[1], params[2], 0, 0);
						
						if (useGUI && (gui.initialised == true))
							initGUI();
						// Make sure all values are set
						if (bootArgs->Video.v_display != GRAPHICS_MODE)
							bootArgs->Video.v_display = GRAPHICS_MODE;
						
						if (!useGUI)
							useGUI = true;
						
						// redraw the background buffer
						drawBackground();
						gui.devicelist.draw = true;
						gui.redraw = true;
						if (!(gBootMode & kBootModeQuiet))
						{
							bool showBootBanner = true;
							
							// Check config file.
							getBoolForKey(kBootBannerKey, &showBootBanner, &bootInfo->bootConfig); 
							if (showBootBanner)
								// Display banner and show hardware info.
								gprintf(&gui.screen, bootBanner + 1, (bootInfo->convmem + bootInfo->extmem) / 1024);
								
							// redraw background
							memcpy(gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4);
						}
						
						nextRow = kMenuTopRow;
						showPrompt = true;
						
						if (gDeviceCount)
						{
							showMenu( menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems );
							nextRow += min( gDeviceCount, kMenuMaxItems ) + 3;
						}
						
						// Show the boot prompt.
						showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
						showBootPrompt( nextRow, showPrompt );
						
						//this is used to avoid resetting the incorrect mode while quiting the boot menu
						map->hasSwitched = true;
					}
				}
				clearBootArgs();
				key = 0;
			}
			break;

		case kF5Key:
			// New behavior:
			// Clear gBootVolume to restart the loop
			// if the user enabled rescanning the optical drive.
			// Otherwise boot the default boot volume.
			if (gEnableCDROMRescan) {
				gBootVolume = NULL;
				clearBootArgs();
			}
			break;

		case kF10Key:
			gScanSingleDrive = false;
			scanDisks(gBIOSDev, &bvCount);
			gBootVolume = NULL;
			clearBootArgs();
			break;

		case kTabKey:
			// New behavior:
			// Switch between text & graphic interfaces
			// Only Permitted if started in graphics interface
			if (useGUI)
			{
				setVideoMode(VGA_TEXT_MODE, 0);

				setCursorPosition(0, 0, 0);
				clearScreenRows(0, kScreenLastRow);

				// Display banner and show hardware info.
				printf(bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024);
				printf(getVBEInfoString());

				clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
				changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);

				nextRow = kMenuTopRow;
				showPrompt = true;

				if (gDeviceCount)
				{
					printf("Use \30\31 keys to select the startup volume.");
					showMenu(menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems);
					nextRow += min(gDeviceCount, kMenuMaxItems) + 3;
				}

				showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);
				showBootPrompt(nextRow, showPrompt);
				//changeCursor( 0, kMenuTopRow, kCursorTypeUnderline, 0 );
				
				/*
				 * AutoResolution - make sure all values are set
				 */
				
				bootArgs->Video.v_display = VGA_TEXT_MODE;
				useGUI = false;
			}
			else
			{
				gui.redraw = true;
				setVideoMode(GRAPHICS_MODE, 0);
				
				/*
				 * AutoResolution - make sure all values are set
				 */
				bootArgs->Video.v_display = GRAPHICS_MODE;
				useGUI = true;
				
				updateVRAM();
			}
			key = 0;
			break;

		default:
			key = 0;
			break;
		}
	} while (0 == key);

done:
	if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
		clearScreenRows(kMenuTopRow, kScreenLastRow);
		changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
	}
	shouldboot = false;
	gui.menu.draw = false;
	if (menuItems) {
		free(menuItems);
		menuItems = NULL;
	}
	return 0;
}
Exemple #24
0
void setup_pci_devs(pci_dt_t *pci_dt)
{
	char *devicepath;

	bool do_gfx_devprop = false;
	bool do_skip_n_devprop = false;
	bool do_skip_a_devprop = false;
	bool do_skip_i_devprop = false;

	bool do_enable_hpet = false;
	bool do_hda_devprop = false;

	pci_dt_t *current = pci_dt;

	// GraphicsEnabler
	getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->chameleonConfig);

	// Skip keys
	getBoolForKey(kSkipNvidiaGfx, &do_skip_n_devprop, &bootInfo->chameleonConfig);
	getBoolForKey(kSkipAtiGfx, &do_skip_a_devprop, &bootInfo->chameleonConfig);
	getBoolForKey(kSkipIntelGfx, &do_skip_i_devprop, &bootInfo->chameleonConfig);

	// HDAEnable
	getBoolForKey(kHDAEnabler, &do_hda_devprop, &bootInfo->chameleonConfig);

	// ForceHPET
	getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->chameleonConfig);

	while (current)
	{
		devicepath = get_pci_dev_path(current);

		switch (current->class_id)
		{
			case PCI_CLASS_BRIDGE_HOST:
				DBG("Setup BRIDGE_HOST \n");
				if (current->dev.addr == PCIADDR(0, 0, 0))
				{
					dram_controller_dev = current;
				}
				break; // PCI_CLASS_BRIDGE_HOST

			case PCI_CLASS_NETWORK_ETHERNET:
				DBG("Setup ETHERNET %s enabled\n", do_eth_devprop? "is":"is not");
				verbose("[ ETHERNET DEVICE INFO ]\n");
				setup_eth_devdrop(current);
				verbose("\n");
				break; // PCI_CLASS_NETWORK_ETHERNET

			case PCI_CLASS_NETWORK_OTHER:
				DBG("Setup WIRELESS %s enabled\n", do_wifi_devprop? "is":"is not");
				verbose("[ WIRELESS DEVICE INFO ]\n");
				setup_wifi_devdrop(current);
				verbose("\n");
				break; // PCI_CLASS_NETWORK_OTHER

			case PCI_CLASS_DISPLAY_VGA:
				DBG("GraphicsEnabler %s enabled\n", do_gfx_devprop? "is":"is not");
				if (do_gfx_devprop)
				{
					switch (current->vendor_id)
					{
						case PCI_VENDOR_ID_ATI:
							if ( do_skip_a_devprop )
							{
								verbose("Skip ATi/AMD gfx device!\n");
							}
							else
							{
								verbose("[ ATi GFX DEVICE INFO ]\n");
								setup_ati_devprop(current);
								verbose("\n");
							}
							break; // PCI_VENDOR_ID_ATI

						case PCI_VENDOR_ID_INTEL:
							if ( do_skip_i_devprop )
							{
								verbose("Skip Intel gfx device!\n");
							}
							else
							{
								verbose("[ INTEL GMA DEVICE INFO ]\n");
								setup_gma_devprop(current);
								verbose("\n");
							}
							break; // PCI_VENDOR_ID_INTEL

						case PCI_VENDOR_ID_NVIDIA:
							if ( do_skip_n_devprop )
							{
								verbose("Skip Nvidia gfx device!\n");
							}
							else
							{
								verbose("[ NVIDIA GFX DEVICE INFO ]\n");
								setup_nvidia_devprop(current);
								verbose("\n");
							}
							break; // PCI_VENDOR_ID_NVIDIA

						default:
							break;
					}
				}
				break; // PCI_CLASS_DISPLAY_VGA

			case PCI_CLASS_MULTIMEDIA_AUDIO_DEV:
				DBG("Setup HDEF %s enabled\n", do_hda_devprop ? "is":"is not");
				if (do_hda_devprop)
				{
					verbose("[ AUDIO DEVICE INFO ]\n");
					setup_hda_devprop(current);
					verbose("\n");
				}
				break; // PCI_CLASS_MULTIMEDIA_AUDIO_DEV

			case PCI_CLASS_SERIAL_USB:
				DBG("USB\n");
				notify_usb_dev(current);
				break; // PCI_CLASS_SERIAL_USB

			case PCI_CLASS_SERIAL_FIREWIRE:
				DBG("FireWire\n");
				verbose("[ FIREWIRE DEVICE INFO ]\n");
				verbose("\tClass code: [%04X]\n\tFireWire device [%04x:%04x]-[%04x:%04x]\n\t%s\n",
					current->class_id,current->vendor_id, current->device_id,
					current->subsys_id.subsys.vendor_id,
					current->subsys_id.subsys.device_id, devicepath);
//				set_fwr_devdrop(current);
				verbose("\n");
				break; // PCI_CLASS_SERIAL_FIREWIRE

			case PCI_CLASS_BRIDGE_ISA:
				DBG("Force HPET %s enabled\n", do_enable_hpet ? "is":"is not");
				if (do_enable_hpet)
				{
					verbose("[ HPET ]\n");
					force_enable_hpet(current);
					verbose("\n");
				}
				break; // PCI_CLASS_BRIDGE_ISA

			}

		execute_hook("PCIDevice", current, NULL, NULL, NULL);
		DBG("setup_pci_devs current device ID = [%04x:%04x]\n", current->vendor_id, current->device_id);
		setup_pci_devs(current->children);
		current = current->next;
	}
}
Exemple #25
0
static int ExecKernel(void *binary)
{
    entry_t                   kernelEntry;
    int                       ret;
	
    bootArgs->kaddr = bootArgs->ksize = 0;

    ret = DecodeKernel(binary,
                       &kernelEntry,
                       (char **) &bootArgs->kaddr,
                       (int *)&bootArgs->ksize );

    if ( ret != 0 )
        return ret;

    // Reserve space for boot args
    reserveKernBootStruct();

    // Load boot drivers from the specifed root path.

    if (!gHaveKernelCache) {
          LoadDrivers("/");
    }

    clearActivityIndicator();

    if (gErrors) {
        printf("Errors encountered while starting up the computer.\n");
        printf("Pausing %d seconds...\n", kBootErrorTimeout);
        sleep(kBootErrorTimeout);
    }		
	
	
    setupFakeEfi();
	
	verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64");

    // Cleanup the PXE base code.

    if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit ) {
		if ( (ret = nbpUnloadBaseCode()) != nbpStatusSuccess )
        {
        	printf("nbpUnloadBaseCode error %d\n", (int) ret);
            sleep(2);
        }
    }

    bool dummyVal;
    if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->bootConfig) && dummyVal) {
	printf("Press any key to continue...");
	getc();
    }

    // If we were in text mode, switch to graphics mode.
    // This will draw the boot graphics unless we are in
    // verbose mode.

    if(gVerboseMode)
      setVideoMode( GRAPHICS_MODE, 0 );
    else
      drawBootGraphics();
	
    finalizeBootStruct();
    
    // Jump to kernel's entry point. There's no going back now.

    startprog( kernelEntry, bootArgs );

    // Not reached

    return 0;
}
Exemple #26
0
void HPersistence::LoadGameData(){
    
    G::g_maxPower = getIntForKey("game_max_power", INIT_POWER);
    G::G_setCoin(getIntForKey("game_coin", INIT_COIN));
   // G::g_mPower = getIntForKey("game_power", 7+45);
    if (G::g_mPower  > G::g_maxPower) {
        G::g_last_power_recovery_time = G::G_getCurrentTime();
    }
    G::G_setPower(getIntForKey("game_power", INIT_POWER));
    G::G_setBook(getIntForKey("game_book", INIT_BOOK ));
    G::g_mIsBackgroundMusicOn = getBoolForKey("m_bgm", true);
    G::g_mIsEffectVolumeOn = getBoolForKey("m_soundEffect", true);
    G::g_stageInfos->removeAllObjects();
    for(int i=0;i<MAX_STAGE;i++){
        StageInfo* info;
        char key_IsOpen[30];
        sprintf(key_IsOpen,"stage_%d_isopen",i);
        char key_IsPlay[30];
        sprintf(key_IsPlay,"stage_%d_isplay",i);
        char key_Stars[30];
        sprintf(key_Stars,"stage_%d_stars",i);
        bool isopen ;
        
        if(i==0){
            isopen = getBoolForKey(key_IsOpen,true);
        }else{
            isopen = getBoolForKey(key_IsOpen,false);
        }
        
        char key_IsShowed[30];
        sprintf(key_IsShowed, "stage_%d_isShowed",i);
        bool isShowed = getBoolForKey(key_IsShowed,false);
        
        bool isplay = getBoolForKey(key_IsPlay,false);
        int stars = getIntForKey(key_Stars,0);
        
//        isopen = true;
//        stars = 3;

//        if (i<11) {
//            isopen = true;
//            stars = 3;
//        }
        
        info = new StageInfo(isopen,isplay,stars,isShowed);
        G::g_stageInfos->addObject(info);
    }
    
    G::g_toolinfos->removeAllObjects();
    for (int i =0;i<MAX_TOOL_COUNT;i++) {
        ToolInfo* info = new ToolInfo();
        IntToStringFormat(hold_key, "tool_hold_%d",i);
        info->setHoldCount(getIntForKey(hold_key, 1));
        IntToStringFormat(show_key, "tool_new_showed_%d",i);
        info->new_showed = getBoolForKey(show_key, false);
        info->price = tool_prices[i];
        G::g_toolinfos->addObject(info);
    }
    
    for(unsigned int i=0;i<G::g_achieve_infos->count();i++){
        ACHIEVE_INFO* info = (ACHIEVE_INFO*)G::g_achieve_infos->objectAtIndex(i);
        char a_c_key[30];
        sprintf(a_c_key, "achieve_c_%d",i);
        char a_s_key[30];
        sprintf(a_s_key, "achieve_s_%d",i);
        info->complete = getIntForKey(a_c_key, 0);
        info->achieve_completed_showed = getBoolForKey(a_s_key, false);
        char show_key[30];
        sprintf(show_key, "achieve_new_showed_%d",i);
        info->new_showed = getBoolForKey(show_key, false);
        IntToStringFormat(_time_key, "achieve_complete_time_%d", i)
        info->complete_time = getIntForKey(_time_key,0);
        IntToStringFormat(_complete_key, "achieve_is_complete_%d", i)
        info->is_complete = getBoolForKey(_complete_key, false);
        IntToStringFormat(_new_key, "achieve_isNew_%d", i)
        info->isNew = getBoolForKey(_new_key, true);
    }
    
    for(unsigned int i=0;i<G::g_help_infos.size();i++){
        for (unsigned int j=0; j<G::g_help_infos[i].size(); j++) {
            char h_key[30];
            sprintf(h_key,"help_info_%d_%d",i,j);
            G::g_help_infos[i][j]->isShowed = getBoolForKey(h_key,false);
        }
//        HELP_INFO* help_info = (HELP_INFO*)G::g_help_infos->objectAtIndex(i);
//        char h_key[30];
//        sprintf(h_key,"help_info_%d",i);
//        help_info->isShowed = getBoolForKey(h_key,false);
    }
    
    G::g_hole_max_score = getIntForKey("unlimit_top_score", 0);
    G::g_hole_total_depth = getIntForKey("unlimit_total_dist", 0);
    
    G::tree_scroll_has_showed = getBoolForKey("tree_scroll_showed", false);
 
    G::g_last_power_recovery_time = getIntForKey("last_power_recovery_time",G::G_getCurrentTime());
    
    for (int i=0; i<MAX_SHARE; i++) {
        char got_key[30];
        sprintf(got_key, "share_reward_got_%d",i);
        G::g_share_reward_got[i]= getBoolForKey(got_key, false);
    }
    
    G::g_hole_isOpened = getBoolForKey("hole_opened",false);
   //G::g_hole_isOpened = true;
    G::g_hole_isNewShowed = getBoolForKey("hole_showed", false);
    
    G::g_sea_isOpened = getBoolForKey("sea_opened",false);
   // G::g_sea_isOpened = true;
    G::g_sea_isNewShowed = getBoolForKey("sea_showed", false);
    
    for (int i=0; i<MAX_BAO; i++) {
        BAO_INFO* info = new BAO_INFO();
        info->id = i;
        IntToStringFormat(_getKey, "bao_isget_%d", i);
        IntToStringFormat(_showKey, "bao_show_%d", i);
        IntToStringFormat(_newKey, "bao_new_%d", i);
        info->isGot = getBoolForKey(_getKey, false);
        info->isShowed = getBoolForKey(_showKey, false);
        info->isNew = getBoolForKey(_newKey, true);
        G::g_bao_infos->addObject(info);
    }
    
    for (int i=0; i<MAX_CLOUD; i++) {
        IntToStringFormat(_cloudOpenKey, "cloud_open_%d", i);
        G::g_cloud_isOpened[i] = getBoolForKey(_cloudOpenKey, false);
    }
    G::g_has_first_saved = getBoolForKey("has_first_saved", false);
    
    long currentTime = G::G_getCurrentTime();
    struct tm *ptm = localtime((time_t*)& currentTime);
    G::turntable_time = getIntForKey("turntable_time",ptm->tm_mday);
    G::turntable_count = getIntForKey("turntable_count", 1);
    if (ptm->tm_mday!=G::turntable_time) {
        G::turntable_count = 1;
    }
    
    G::turntable_time = ptm->tm_mday;
    
    CCLOG("turntable_time %ld",G::turntable_time);
    
//    if (G::turntable_count==0) {
//        long currentTime = G::G_getCurrentTime();
//        struct tm *ptm1 = localtime((time_t*)& G::turntable_time);
//        struct tm *ptm2 = localtime((time_t*)& currentTime);
//        if (ptm1->tm_mday!=ptm2->tm_mday) {
//            G::turntable_count = 1;
//        }
////        if (G::G_getCurrentTime()>G::turntable_time) {
////            struct tm *ptm1 = localtime((time_t*)& G::turntable_time);
////            struct tm *ptm2 = localtime((time_t*)& currentTime);
////            if (ptm1->tm_mday!=ptm2->tm_mday) {
////                G::turntable_count = 1;
////            }
////        }
//    }
//    
//    long currentTime = G::G_getCurrentTime();
//    CCLOG("currentTime %ld",currentTime);
//
//    
//    struct tm *ptm1 = localtime((time_t*)& G::turntable_time);
//    struct tm *ptm2 = localtime((time_t*)& currentTime);
//    CCLOG("tm_day1 %d  tmp_day2 %d",ptm1->tm_mday,ptm2->tm_mday);
//    if (ptm1->tm_mday!=ptm2->tm_mday) {
//        G::turntable_count = 1;
//    }
//    G::turntable_time = G::G_getCurrentTime();
    
    G::shop_th_has_buyed = getBoolForKey("shop_th_has_buyed", false);
    G::shop_ts_has_buyed = getBoolForKey("shop_ts_has_buyed", false);
    //G::turntable_count = 99;
}
bool UserDefaultManager::getisFirstTime(){
    return getBoolForKey(kFirstTime);
}
Exemple #28
0
static int ExecKernel(void *binary)
{
	int			ret;
	entry_t		kernelEntry;

	bootArgs->kaddr = bootArgs->ksize = 0;
	execute_hook("ExecKernel", (void*)binary, NULL, NULL, NULL);

	ret = DecodeKernel(binary,
					   &kernelEntry,
					   (char **) &bootArgs->kaddr,
					   (int *)&bootArgs->ksize );

	if ( ret != 0 )
		return ret;

	// Reserve space for boot args
	reserveKernBootStruct();

	// Notify modules that the kernel has been decoded
	execute_hook("DecodedKernel", (void*)binary, (void*)bootArgs->kaddr, (void*)bootArgs->ksize, NULL);

	setupFakeEfi();

	// Load boot drivers from the specifed root path.
	//if (!gHaveKernelCache)
	LoadDrivers("/");

	execute_hook("DriversLoaded", (void*)binary, NULL, NULL, NULL);

	clearActivityIndicator();

	if (gErrors) {
		printf("Errors encountered while starting up the computer.\n");
		printf("Pausing %d seconds...\n", kBootErrorTimeout);
		sleep(kBootErrorTimeout);
	}

	md0Ramdisk();

	// Cleanup the PXE base code.

	if ( (gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit ) {
		if ( (ret = nbpUnloadBaseCode()) != nbpStatusSuccess ) {
			printf("nbpUnloadBaseCode error %d\n", (int) ret);
			sleep(2);
		}
	}

	bool dummyVal;
	if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->chameleonConfig) && dummyVal) {
		showTextBuffer(msgbuf, strlen(msgbuf));
	}

	usb_loop();

	// If we were in text mode, switch to graphics mode.
	// This will draw the boot graphics unless we are in
	// verbose mode.
	if (gVerboseMode) {
		setVideoMode( GRAPHICS_MODE, 0 );
	} else {
		drawBootGraphics();
	}

	DBG("Starting Darwin/%s [%s]\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64", gDarwinBuildVerStr);
	DBG("Boot Args: %s\n", bootArgs->CommandLine);

	setupBooterLog();

	finalizeBootStruct();

	// Jump to kernel's entry point. There's no going back now.
	if ((checkOSVersion("10.7")) || (checkOSVersion("10.8")) || (checkOSVersion("10.9")))
	{

		// Notify modules that the kernel is about to be started
		execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgs, NULL, NULL);

		// Masking out so that Lion doesn't doublefault
		outb(0x21, 0xff);	/* Maskout all interrupts Pic1 */
		outb(0xa1, 0xff);	/* Maskout all interrupts Pic2 */

		startprog( kernelEntry, bootArgs );
	} else {
		// Notify modules that the kernel is about to be started
		execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgsPreLion, NULL, NULL);

		startprog( kernelEntry, bootArgsPreLion );
	}

	// Not reached
	return 0;
}
bool UserDefaultManager::getIsRemoved()
{
    return getBoolForKey(kIsRemoveAds);
}
//==========================================================================
// The 'main' function for the booter. Called by boot0 when booting
// from a block device, or by the network booter.
//
// arguments:
//	 biosdev - Value passed from boot1/NBP to specify the device
//			   that the booter was loaded from.
//
// If biosdev is kBIOSDevNetwork, then this function will return if
// booting was unsuccessful. This allows the PXE firmware to try the
// next boot device on its list.
void common_boot(int biosdev)
{
	bool	 		quiet;
	bool	 		firstRun = true;
	bool	 		instantMenu;
	bool	 		rescanPrompt;
	char	 		*bootFile;
	int				status;
	unsigned int	allowBVFlags = kBVFlagSystemVolume | kBVFlagForeignBoot;
	unsigned int	denyBVFlags = kBVFlagEFISystem;
	unsigned long	adler32;
	
	// Set reminder to unload the PXE base code. Neglect to unload
	// the base code will result in a hang or kernel panic.
	gUnloadPXEOnExit = true;
	
	// Record the device that the booter was loaded from.
	gBIOSDev = biosdev & kBIOSDevMask;
	
	// Initialize boot info structure.
	initKernBootStruct();
	
	initBooterLog();
	
	// Setup VGA text mode.
	// Not sure if it is safe to call setVideoMode() before the
	// config table has been loaded. Call video_mode() instead.
#if DEBUG
	printf("before video_mode\n");
#endif
	video_mode( 2 );  // 80x25 mono text mode.
#if DEBUG
	printf("after video_mode\n");
#endif
	
	// Scan and record the system's hardware information.
	scan_platform();
	
	// First get info for boot volume.
	scanBootVolumes(gBIOSDev, 0);
	bvChain = getBVChainForBIOSDev(gBIOSDev);
	setBootGlobals(bvChain);
	
	// Load boot.plist config file
	status = loadChameleonConfig(&bootInfo->chameleonConfig);
	
	if (getBoolForKey(kQuietBootKey, &quiet, &bootInfo->chameleonConfig) && quiet) {
		gBootMode |= kBootModeQuiet;
	}
	
	// Override firstRun to get to the boot menu instantly by setting "Instant Menu"=y in system config
	if (getBoolForKey(kInstantMenuKey, &instantMenu, &bootInfo->chameleonConfig) && instantMenu) {
		firstRun = false;
	}
	
	// Loading preboot ramdisk if exists.
	loadPrebootRAMDisk();
	
	// Disable rescan option by default
	gEnableCDROMRescan = false;
	
	// Enable it with Rescan=y in system config
	if (getBoolForKey(kRescanKey, &gEnableCDROMRescan, &bootInfo->chameleonConfig)
		&& gEnableCDROMRescan) {
		gEnableCDROMRescan = true;
	}
	
	// Ask the user for Rescan option by setting "Rescan Prompt"=y in system config.
	rescanPrompt = false;
	if (getBoolForKey(kRescanPromptKey, &rescanPrompt , &bootInfo->chameleonConfig)
		&& rescanPrompt && biosDevIsCDROM(gBIOSDev))
	{
		gEnableCDROMRescan = promptForRescanOption();
	}
	
	// Enable touching a single BIOS device only if "Scan Single Drive"=y is set in system config.
	if (getBoolForKey(kScanSingleDriveKey, &gScanSingleDrive, &bootInfo->chameleonConfig)
		&& gScanSingleDrive) {
		gScanSingleDrive = true;
	}
	
	// Create a list of partitions on device(s).
	if (gScanSingleDrive) {
		scanBootVolumes(gBIOSDev, &bvCount);
	} else {
		scanDisks(gBIOSDev, &bvCount);
	}
	
	// Create a separated bvr chain using the specified filters.
	bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
	
	gBootVolume = selectBootVolume(bvChain);
	
	// Intialize module system 
	init_module_system();
		
#if DEBUG
	printf(" Default: %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n",
			 gBootVolume, gBootVolume->biosdev, gBootVolume->part_no, gBootVolume->flags);
	printf(" bt(0,0): %d, ->biosdev: %d, ->part_no: %d ->flags: %d\n",
			 gBIOSBootVolume, gBIOSBootVolume->biosdev, gBIOSBootVolume->part_no, gBIOSBootVolume->flags);
	getchar();
#endif
	
	useGUI = true;
	// Override useGUI default
	getBoolForKey(kGUIKey, &useGUI, &bootInfo->chameleonConfig);
	if (useGUI && initGUI())
	{
		// initGUI() returned with an error, disabling GUI.
		useGUI = false;
	}
	
	setBootGlobals(bvChain);
	
	// Parse args, load and start kernel.
	while (1)
	{
		bool		tryresume, tryresumedefault, forceresume;
		bool		usecache = false;//true;
		const char	*val;
		int			len, trycache, ret = -1;
		long		flags, cachetime, kerneltime, exttime, sleeptime, time;
		void		*binary = (void *)kLoadAddr;
		
		// additional variable for testing alternate kernel image locations on boot helper partitions.
		char		bootFileSpec[512];
		
		// Initialize globals.
		sysConfigValid = false;
		gErrors		   = false;
		
		status = getBootOptions(firstRun);
		firstRun = false;
		if (status == -1) continue;
		 
		status = processBootOptions();
		// Status == 1 means to chainboot
		if ( status ==	1 ) break;
		// Status == -1 means that the config file couldn't be loaded or that gBootVolume is NULL
		if ( status == -1 )
		{
			// gBootVolume == NULL usually means the user hit escape.
			if (gBootVolume == NULL)
			{
				freeFilteredBVChain(bvChain);
				
				if (gEnableCDROMRescan)
					rescanBIOSDevice(gBIOSDev);
				
				bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
				setBootGlobals(bvChain);
				setupDeviceList(&bootInfo->themeConfig);
			}
			continue;
		}
		
		// Other status (e.g. 0) means that we should proceed with boot.
		
		// Turn off any GUI elements
		if ( bootArgs->Video.v_display == GRAPHICS_MODE )
		{
			gui.devicelist.draw = false;
			gui.bootprompt.draw = false;
			gui.menu.draw = false;
			gui.infobox.draw = false;
			gui.logo.draw = false;
			drawBackground();
			updateVRAM();
		}
		
		// Find out which version mac os we're booting.
		getOSVersion();
		
		if (platformCPUFeature(CPU_FEATURE_EM64T)) {
			archCpuType = CPU_TYPE_X86_64;
		} else {
			archCpuType = CPU_TYPE_I386;
		}
		
		if (getValueForKey(karch, &val, &len, &bootInfo->chameleonConfig)) {
			if (strncmp(val, "i386", 4) == 0) {
				archCpuType = CPU_TYPE_I386;
			}
		}
		
		if (getValueForKey(kKernelArchKey, &val, &len, &bootInfo->chameleonConfig)) {
			if (strncmp(val, "i386", 4) == 0) {
				archCpuType = CPU_TYPE_I386;
			}
		}
		
		// Notify modules that we are attempting to boot
		execute_hook("PreBoot", NULL, NULL, NULL, NULL);
		
		if (!getBoolForKey (kWake, &tryresume, &bootInfo->chameleonConfig)) {
			tryresume = true;
			tryresumedefault = true;
		} else {
			tryresumedefault = false;
		}
		
		if (!getBoolForKey (kForceWake, &forceresume, &bootInfo->chameleonConfig)) {
			forceresume = false;
		}
		
		if (forceresume) {
			tryresume = true;
			tryresumedefault = false;
		}
		
		while (tryresume) {
			const char *tmp;
			BVRef bvr;
			if (!getValueForKey(kWakeImage, &val, &len, &bootInfo->chameleonConfig))
				val = "/private/var/vm/sleepimage";
			
			// Do this first to be sure that root volume is mounted
			ret = GetFileInfo(0, val, &flags, &sleeptime);
			
			if ((bvr = getBootVolumeRef(val, &tmp)) == NULL)
				break;
			
			// Can't check if it was hibernation Wake=y is required
			if (bvr->modTime == 0 && tryresumedefault)
				break;
			
			if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeFlat))
				break;
			
			if (!forceresume && ((sleeptime+3)<bvr->modTime)) {
#if DEBUG	
				printf ("Hibernate image is too old by %d seconds. Use ForceWake=y to override\n",
						bvr->modTime-sleeptime);
#endif				  
				break;
			}
			
			HibernateBoot((char *)val);
			break;
		}
		
		getBoolForKey(kUseKernelCache, &usecache, &bootInfo->chameleonConfig);
		if (usecache) {
			if( getValueForKey(kKernelCacheKey, &val, &len, &bootInfo->chameleonConfig) || getValueForKey(kKernelCacheKey, &val, &len, &bootInfo->bootConfig) ) {
				if (val[0] == '\\')
				{
					len--;
					val++;
				}
				strlcpy(gBootKernelCacheFile, val, len + 1);
                verbose("Using kernel cache: \"%s\" \n", gBootKernelCacheFile);
                //sleep(5);
			}
			else {
				// Lion and Mountain Lion prelink kernel cache file␊
				if ((checkOSVersion("10.7")) || (checkOSVersion("10.8"))) {
					sprintf(gBootKernelCacheFile, "%skernelcache", kDefaultCachePathSnow);
				}
				// Snow Leopard
				else if (checkOSVersion("10.6")) {
					sprintf(gBootKernelCacheFile, "kernelcache_%s", (archCpuType == CPU_TYPE_I386)
							? "i386" : "x86_64");
					int lnam = sizeof(gBootKernelCacheFile) + 9; //with adler32
					
					char* name;
					long prev_time = 0;
					
					struct dirstuff* cacheDir = opendir(kDefaultCachePathSnow);
					
					while(readdir(cacheDir, (const char**)&name, &flags, &time) >= 0)
					{
						if (((flags & kFileTypeMask) != kFileTypeDirectory) && time > prev_time
							&& strstr(name, gBootKernelCacheFile) && (name[lnam] != '.'))
						{
							sprintf(gBootKernelCacheFile, "%s%s", kDefaultCachePathSnow, name);
							prev_time = time;
						}
					}
				}
				else {
					// Reset cache name.
					bzero(gCacheNameAdler + 64, sizeof(gCacheNameAdler) - 64);
					
					sprintf(gCacheNameAdler + 64, "%s,%s", gRootDevice, bootInfo->bootFile);
					
					adler32 = Adler32((unsigned char *)gCacheNameAdler, sizeof(gCacheNameAdler));
					
					sprintf(gBootKernelCacheFile, "%s.%08lX", kDefaultCachePathLeo, adler32);
				}
			}
		}
		
		// Check for cache file.
		trycache = (usecache && 
					((gBootMode & kBootModeSafe) == 0) &&
					!gOverrideKernel &&
					(gBootFileType == kBlockDeviceType) &&
					(gMKextName[0] == '\0') &&
					(gBootKernelCacheFile[0] != '\0'));
        
        verbose("trycache: %d\n", trycache);
		
		verbose("Loading Darwin %s\n", gMacOSVersion);
		
		if (trycache) do {
            verbose("bootInfo->bootFile: \"%s\" \n", bootInfo->bootFile);
			ret = GetFileInfo(NULL, bootInfo->bootFile, &flags, &kerneltime);
			if (ret != 0) kerneltime = 0;
			else if ((flags & kFileTypeMask) != kFileTypeFlat) {
				trycache = 0;
                verbose("trycache0 : 1\n");
				break;
			}
			
			ret = GetFileInfo(NULL, gBootKernelCacheFile, &flags, &cachetime);
			if ((ret != 0)) {
				trycache = 0;
                verbose("trycache0 : 2.1 \"%s\" \n", gBootKernelCacheFile);
				break;
			}
			else if ( ((flags & kFileTypeMask) != kFileTypeFlat) ) {
				trycache = 0;
                verbose("trycache0 : 2.2\n");
				break;
			}
			else if ( (cachetime < kerneltime) ) {
				trycache = 0;
                verbose("trycache0 : 2.3\n");
				break;
			}
			
			ret = GetFileInfo("/System/Library/", "Extensions", &flags, &exttime);
			if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeDirectory)
				&& (cachetime < exttime)) {
				trycache = 0;
                verbose("trycache0 : 3\n");
				break;
			}
			
			if (ret == 0 && kerneltime > exttime) {
				exttime = kerneltime;
			}
			
			if (ret == 0 && cachetime < (exttime + 1)) {
				trycache = 0;
                verbose("trycache0 : 4\n");
				break;
			}
		} while (0);

        // sleep(5);

		do {
			if (trycache) {
				bootFile = gBootKernelCacheFile;
				
				verbose("Loading kernel cache %s\n", bootFile);
				
				if ((checkOSVersion("10.7")) || (checkOSVersion("10.8"))) {
					ret = LoadThinFatFile(bootFile, &binary);
				}
				else {
					ret = LoadFile(bootFile);
					binary = (void *)kLoadAddr;
				}
				
				if (ret >= 0)
					break;
				
				verbose("Kernel cache did not load %s\n ", bootFile);
			}
			
			if ((checkOSVersion("10.7")) || (checkOSVersion("10.8"))) {
				bootFile = gBootKernelCacheFile;
			}
			else {
				sprintf(bootFile, "\%s", bootInfo->bootFile);
			}
			
			// Try to load kernel image from alternate locations on boot helper partitions.
			sprintf(bootFileSpec, "com.apple.boot.P%s", bootFile);
			ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); 
			if (ret == -1)
			{
				sprintf(bootFileSpec, "com.apple.boot.R%s", bootFile);
				ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); 
				if (ret == -1)
				{
					sprintf(bootFileSpec, "com.apple.boot.S%s", bootFile);
					ret = GetFileInfo(NULL, bootFileSpec, &flags, &time); 
					if (ret == -1)
					{
						// No alternate location found, using the original kernel image path.
						strcpy(bootFileSpec, bootInfo->bootFile);
					}
				}
			}
			
			if ((checkOSVersion("10.7")) || (checkOSVersion("10.8")))
			{
				//Lion, dont load kernel if haz cache
				if (!trycache) 
				{
					verbose("Loading kernel %s\n", bootFileSpec);
					ret = LoadThinFatFile(bootFileSpec, &binary);
					if (ret <= 0 && archCpuType == CPU_TYPE_X86_64) 
					{
						archCpuType = CPU_TYPE_I386;
						ret = LoadThinFatFile(bootFileSpec, &binary);				
					}
				} 
				else ret = 1;
			} 
			else 
			{
				//Snow Leopard or older
				verbose("Loading kernel %s\n", bootFileSpec);
				ret = LoadThinFatFile(bootFileSpec, &binary);
				if (ret <= 0 && archCpuType == CPU_TYPE_X86_64) 
				{
					archCpuType = CPU_TYPE_I386;
					ret = LoadThinFatFile(bootFileSpec, &binary);				
				}
			}
		} while (0);
		
		clearActivityIndicator();
		
#if DEBUG
		printf("Pausing...");
		sleep(8);
#endif
		
		if (ret <= 0) {
			printf("Can't find %s\n", bootFile);
			
			sleep(1);
			
			if (gBootFileType == kNetworkDeviceType) {
				// Return control back to PXE. Don't unload PXE base code.
				gUnloadPXEOnExit = false;
				break;
			}
		} else {
			/* Won't return if successful. */
			ret = ExecKernel(binary);
		}
	}
	
	// chainboot
	if (status == 1) {
		// if we are already in graphics-mode,
		if (getVideoMode() == GRAPHICS_MODE) {
			setVideoMode(VGA_TEXT_MODE, 0); // switch back to text mode.
		}
	}
	
	if ((gBootFileType == kNetworkDeviceType) && gUnloadPXEOnExit) {
		nbpUnloadBaseCode();
	}
}