コード例 #1
0
/*
 * Initialize the module system by loading the Symbols.dylib module.
 * Once loaded, locate the _lookup_symbol function so that internal
 * symbols can be resolved.
 */
int init_module_system()
{
    // Start any modules that were compiled in first.
    start_built_in_modules();
    
    
	int retVal = 0;
	void (*module_start)(void) = NULL;
	char* module_data = symbols_module_start + BOOT2_ADDR;
    
	// Intialize module system
	if(symbols_module_start != (void*)0xFFFFFFFF)
	{
		// Module system  was compiled in (Symbols.dylib addr known)
		module_start = parse_mach(module_data, &load_module, &add_symbol, NULL);
		
		if(module_start && module_start != (void*)0xFFFFFFFF)
		{
			// Notify the system that it was laoded
			module_loaded(SYMBOLS_MODULE, SYMBOLS_AUTHOR, SYMBOLS_DESCRIPTION, SYMBOLS_VERSION, SYMBOLS_COMPAT);
			
			(*module_start)();	// Start the module. This will point to load_all_modules due to the way the dylib was constructed.
			execute_hook("ModulesLoaded", NULL, NULL, NULL, NULL);
			DBG("Module %s Loaded.\n", SYMBOLS_MODULE);
			retVal = 1;

		}
		else
		{
            module_data -= 0x10;    // XCODE 4 HACK
            module_start = parse_mach(module_data, &load_module, &add_symbol, NULL);
            
            if(module_start && module_start != (void*)0xFFFFFFFF)
            {
                // Notify the system that it was laoded
                module_loaded(SYMBOLS_MODULE, SYMBOLS_AUTHOR, SYMBOLS_DESCRIPTION, SYMBOLS_VERSION, SYMBOLS_COMPAT);
                
                (*module_start)();	// Start the module. This will point to load_all_modules due to the way the dylib was constructed.
                execute_hook("ModulesLoaded", NULL, NULL, NULL, NULL);
                DBG("Module %s Loaded.\n", SYMBOLS_MODULE);
                retVal = 1;
                
            }
            else
            {
                // The module does not have a valid start function
                printf("Unable to start %s\n", SYMBOLS_MODULE); getchar();
            }		
		}		
	}
	return retVal;
}
コード例 #2
0
/** scan mem for memory autodection purpose */
void scan_mem() {
    static bool done = false;
    if (done) return;

	execute_hook("ScanMemory", NULL, NULL, NULL, NULL);
    done = true;
}
コード例 #3
0
ファイル: options.c プロジェクト: svn2github/chameleon
static void clearBootArgs(void)
{
	gBootArgsPtr = gBootArgs;
	memset(gBootArgs, '\0', BOOT_STRING_LEN);

	if (bootArgs->Video.v_display != VGA_TEXT_MODE)
	{
		clearGraphicBootPrompt();
	}
	execute_hook("ClearArgs", NULL, NULL, NULL, NULL);
}
コード例 #4
0
long
LoadDriverMKext( char * fileSpec )
{
	unsigned long    driversAddr, driversLength;
	long             length;
	char             segName[32];
	DriversPackage * package;

#define GetPackageElement(e)     OSSwapBigToHostInt32(package->e)

	// Load the MKext.
	length = LoadThinFatFile(fileSpec, (void **)&package);
	if (length < sizeof (DriversPackage)) {
		return -1;
	}

	// call hook to notify modules that the mkext has been loaded
	execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) &length, NULL);

	
	// Verify the MKext.
	if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
		( GetPackageElement(signature2) != kDriverPackageSignature2) ||
		( GetPackageElement(length)      > kLoadSize )               ||
		( GetPackageElement(adler32)    !=
		Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
	{
		return -1;
	}

	// Make space for the MKext.
	driversLength = GetPackageElement(length);
	driversAddr   = AllocateKernelMemory(driversLength);

	// Copy the MKext.
	memcpy((void *)driversAddr, (void *)package, driversLength);

	// Add the MKext to the memory map.
	snprintf(segName, sizeof(segName), "DriversPackage-%lx", driversAddr);
	AllocateMemoryRange(segName, driversAddr, driversLength, kBootDriverTypeMKEXT);

	return 0;
}
コード例 #5
0
ファイル: pci_setup.c プロジェクト: JayMonkey/chameleon
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;
	}
}
コード例 #6
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();
	}
}
コード例 #7
0
long NBI_LoadDrivers( char * dirSpec )
{
	
    char dirSpecExtra[1024];
	
    if ( InitDriverSupport() != 0 )
        return 0;
	
	int step = 0;
	execute_hook("ramDiskLoadDrivers", &step, NULL, NULL, NULL, NULL, NULL);
#ifdef NBP_SUPPORT	
    if ( get_env(envgBootFileType) == kNetworkDeviceType )
    {
        if (NetLoadDrivers(dirSpec) != 0)
		{
            error("Could not load drivers from the network\n");
            return -1;
        }
    }
    else
#endif
		if ( get_env(envgBootFileType) == kBlockDeviceType )
		{
			verbose("Loading Recovery Extensions\n");
			strlcpy(dirSpecExtra, "/Extra/RecoveryExtensions/", sizeof(dirSpecExtra));
			FileLoadDrivers(dirSpecExtra, sizeof(dirSpecExtra), 0);
			
#ifdef BOOT_HELPER_SUPPORT			
			// TODO: fix this, the order does matter, and it's not correct now.
			// Also try to load Extensions from boot helper partitions.
			if (((BVRef)(uint32_t)get_env(envgBootVolume))->flags & kBVFlagBooter)
			{
				strlcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/", sizeof(dirSpecExtra));
				if (FileLoadDrivers(dirSpecExtra, sizeof(dirSpecExtra), 0) != 0)
				{
					strlcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/", sizeof(dirSpecExtra));
					if (FileLoadDrivers(dirSpecExtra, sizeof(dirSpecExtra), 0) != 0)
					{
						strlcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/", sizeof(dirSpecExtra));
						FileLoadDrivers(dirSpecExtra, sizeof(dirSpecExtra), 0);
					}
				}
			}
#endif
            char * MKextName = (char*)(uint32_t)get_env(envMKextName);
			
			if (MKextName[0] != '\0')
			{
				verbose("LoadDrivers: Loading from [%s]\n", MKextName);
				if ( LoadDriverMKext(MKextName) != 0 )
				{
					error("Could not load %s\n", MKextName);
					return -1;
				}
			}
			else
			{
				char * ExtensionsSpec = (char*)(uint32_t)get_env(envDriverExtSpec);
				
				strlcpy(ExtensionsSpec, dirSpec, DEFAULT_DRIVER_SPEC_SIZE);
				strlcat(ExtensionsSpec, "System/Library/", DEFAULT_DRIVER_SPEC_SIZE);
				FileLoadDrivers(ExtensionsSpec,DEFAULT_DRIVER_SPEC_SIZE, 0);
			}
		}
		else
		{
			return 0;
		}
#if UNUSED
    MatchPersonalities();
#endif
    MatchLibraries();
	
    LoadMatchedModules();
	
    return 0;
}
コード例 #8
0
ファイル: pci_setup.c プロジェクト: Klozz/ChameleonFRK
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;
	}
}
コード例 #9
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;
}
コード例 #10
0
ファイル: commit2.cpp プロジェクト: beamerblvd/vyatta-cfg
int
main(int argc, char** argv)
{
  int ch;
  boolean priority_mode = TRUE;
  boolean test_mode = FALSE;
  boolean disable_partial_commit = FALSE;
  boolean full_commit_check = FALSE;
  boolean break_priority = FALSE;
  int     break_priority_node = -1;
  boolean disable_hook = FALSE;
  char   *commit_comment  = NULL;  

  /* this is needed before calling certain glib functions */
  g_type_init();

  //grab inputs
  while ((ch = getopt(argc, argv, "xdpthsecoafb:rlC:")) != -1) {
    switch (ch) {
    case 'x':
      g_old_print_output = TRUE;
      break;
    case 'd':
      g_debug = TRUE;
      break;
    case 'h':
      usage();
      exit(0);
      break;
    case 'p':
      priority_mode = FALSE;
      break;
    case 't':
      test_mode = TRUE;
      break;
    case 's':
      g_dump_trans = TRUE;
      break;
    case 'e':
      g_display_error_node = TRUE;
      break;
    case 'c':
      g_coverage = TRUE;
      break;
    case 'o':
      disable_partial_commit = TRUE;
      break;
    case 'a':
      g_dump_actions = TRUE;
      break;
    case 'f':
      full_commit_check = TRUE;
      break;
    case 'b':
      break_priority_node = strtoul(optarg,NULL,10);
      break_priority = TRUE;
      break;
    case 'r':
      disable_hook = TRUE;
      break;
    case 'C':
      commit_comment = strdup(optarg);
      break;
    case 'l':
      release_config_lock();
      break;
    default:
      usage();
      exit(0);
    }
  }

  //can also be set via environment variable
  if (getenv("VYATTA_OUTPUT_ERROR_LOCATION") != NULL) {
    g_print_error_location_all = TRUE;
  }

  if (disable_hook == FALSE) {
    execute_hook(PRE_COMMIT_HOOK_DIR,commit_comment);
  } 

  initialize_output("Commit");
  init_paths(TRUE);
  d_dplog("commit2: starting up");

  if (get_config_lock() != 0) {
    fprintf(out_stream, "Configuration system temporarily locked "
                        "due to another commit in progress\n");
    exit(1);
  }

  //get local session data plus configuration data
  GNode *config_data = common_get_local_session_data();
  if (g_node_n_children(config_data) == 0) {
    common_commit_clean_temp_config(NULL, test_mode);
    fprintf(out_stream, "No configuration changes to commit\n");
    return 0;
  }

  GNode *orig_node_tree = g_node_copy(config_data);

  // Get collection of transactions, i.e. trans nodes that have been activated. 
  GNode *trans_coll = get_transactions(config_data, priority_mode);
  if (trans_coll == NULL) {
    printf("commit2: transactions collection is empty, exiting\n");
    exit(0);
  }

  if (g_debug == TRUE || g_dump_trans == TRUE) {
    if (g_dump_trans == TRUE) {
      fprintf(out_stream,"Dumping transactions\n");
      syslog(LOG_DEBUG,"Dumping transactions");
    }
    //iterate over config_data and dump...
    g_node_traverse(trans_coll,
                    G_PRE_ORDER,
                    G_TRAVERSE_ALL,
                    -1,
                    (GNodeTraverseFunc)dump_func,
                    (gpointer)NULL);
    if (g_dump_trans == TRUE) {
      exit(0);
    }
  }

  set_in_commit(TRUE);

  GNode *trans_child_node = (GNode*)g_node_first_child(trans_coll);
  if (trans_child_node == NULL) {
    printf("commit2: No child nodes to process, exiting\n");
    exit(0);
  }

  //open the changes file and clear
  FILE *fp_changes = fopen(COMMIT_CHANGES_FILE,"w");
  if (fp_changes == NULL) {
    cond_plog(true, LOG_ERR, "commit2: Cannot access changes file, exiting");
    exit(0);
  }

  GSList *completed_root_node_coll = NULL;
  GSList *nodes_visited_coll = NULL;
  int errors = 0;
  int i = 0;
  do {
    boolean success = FALSE;
    d_dplog("commit2: Starting new transaction processing pass on root: [%s]",
            ((trans_child_node && trans_child_node->data
              && ((struct VyattaNode*)(trans_child_node->data))->_data._name)
             ? ((struct VyattaNode*)(trans_child_node->data))->_data._name
               : ""));

    if (break_priority) {
      gpointer gp = ((GNode*)trans_child_node)->data;
      long p = (long) ((struct VyattaNode*)gp)->_config._priority;
      if (p >= break_priority_node) {
        g_dump_trans = TRUE;
        g_node_traverse(trans_child_node,
                        G_PRE_ORDER,
                        G_TRAVERSE_ALL,
                        -1,
                        (GNodeTraverseFunc)dump_func,
                        (gpointer)NULL);
        g_dump_trans = FALSE;
        fprintf(out_stream,"Press any key to commit...\n");
        
        // Wait for single character 
        char input = getchar(); 
        input = input; //to fix stupid compilier warning
      }
    }

    //complete() now requires a undisturbed copy of the trans_child_node tree
    GNode *comp_cp_node = g_node_copy(trans_child_node);

    if (g_dump_actions == TRUE) {
      fprintf(out_stream,"\n"); //add an extra line here
    }

    //on each priority node now execute actions

    nodes_visited_coll = NULL;
    if (validate_configuration(trans_child_node, full_commit_check,
                               &nodes_visited_coll) == TRUE
        && (success = process_priority_node(trans_child_node)) == TRUE) {
      //this below copies the node directory from the local to active location
      //if this is true root skip
      if (trans_child_node != NULL && trans_child_node->data != NULL
          && strcmp(((struct VyattaNode*)(trans_child_node->data))
                    ->_data._path, "/") == 0) {
        //no op, need better way to define true root
      }
      else {
        if (disable_partial_commit == FALSE && g_dump_actions == FALSE) {
          completed_root_node_coll
            = g_slist_append(completed_root_node_coll, comp_cp_node);
        }
      }
    }

    if (g_dump_actions == TRUE) {
      success = TRUE; //FORCE SUCCESS ON DISPLAY MODE OF ACTIONS
    }

    if (success == FALSE) {
      errors |= 1;
      d_dplog("commit2: Failed in processing node");
    }
    else {
      errors |= 2;
    }

    //now update the changes file
    update_change_file(fp_changes,nodes_visited_coll);
    fflush(fp_changes);

    ++i;
  } while ((trans_child_node
              = (GNode*) g_node_nth_child((GNode*) trans_coll,
                                          (guint) i)) != NULL);

  if (errors == 2) {
    /*
     * Need to add to the following func below to clean up dangling .wh. files
     */
    if (g_dump_actions == FALSE) {
      common_commit_copy_to_live_config(orig_node_tree, TRUE, test_mode);
      common_commit_clean_temp_config(orig_node_tree, test_mode);
    }
    d_dplog("commit2: successful commit, now cleaning up temp directories");
  }
  else {
    fprintf(out_stream,"Commit failed\n");
    complete(completed_root_node_coll, test_mode);
  }

  set_in_commit(FALSE);
  d_dplog("DONE");
  
  if (fp_changes != NULL) {
    fclose(fp_changes);
  }
 
  restore_output();
  if (disable_hook == FALSE) {
    if (errors == 2) {
      setenv(ENV_COMMIT_STATUS,"SUCCESS",1);
    }
    else if (errors == 3) {
      setenv(ENV_COMMIT_STATUS,"PARTIAL",1);
    }
    else {
      setenv(ENV_COMMIT_STATUS,"FAILURE",1);
    }
    execute_hook(POST_COMMIT_HOOK_DIR,commit_comment);
    unsetenv(ENV_COMMIT_STATUS);
  } 

  //remove tmp changes file as all the work is now done
  unlink(COMMIT_CHANGES_FILE);

  exit (errors == 2 ? 0 : 1);
}
コード例 #11
0
long DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
{
	long ret = 0;
	compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary;
	u_int32_t uncompressed_size = 0, size = 0, adler32 = 0;
	void *buffer = NULL;
	unsigned long len = 0;
	
/*#if 0
	printf("kernel header:\n");
	printf("signature: 0x%x\n", kernel_header->signature);
	printf("compress_type: 0x%x\n", kernel_header->compress_type);
	printf("adler32: 0x%x\n", kernel_header->adler32);
	printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
	printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
	getchar();
#endif*/

	if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
	{
		DBG("Decompressing Kernel: ");

		if ((kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) &&
			(kernel_header->compress_type != OSSwapBigToHostConstInt32('lzvn')))
		{
			error("ERROR: kernel compression is bad!\n");
			return -1;
		}
#if NOTDEF
		if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
		{
			return -1;
		}

		if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
		{
			return -1;
		}
#endif
		uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
		binary = buffer = malloc(uncompressed_size);

		// MinusZwei
		size = 0;
		switch (kernel_header->compress_type)
		{
			case OSSwapBigToHostConstInt32('lzvn'):
				size = decompress_lzvn( binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
				break;

			case OSSwapBigToHostConstInt32('lzss'):
				size = decompress_lzss( (u_int8_t *)binary, uncompressed_size, &kernel_header->data[0], OSSwapBigToHostInt32(kernel_header->compressed_size));
				break;

			default:
				break;
		}
		// MinusZwei

		if (uncompressed_size != size)
		{
			if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzvn'))
			{
				error("ERROR: size mismatch from lzvn (found: %x, expected: %x).\n", size, uncompressed_size);
			}

			if ( kernel_header->compress_type == OSSwapBigToHostConstInt32('lzss'))
			{
				error("ERROR: size mismatch from lzss (found: %x, expected: %x).\n", size, uncompressed_size);
			}

			return -1;
		}

		adler32 = Adler32(binary, uncompressed_size);
		if (OSSwapBigToHostInt32(kernel_header->adler32) != adler32)
		{
			error("ERROR: adler mismatch (found: %x, expected: %x).\n", adler32, OSSwapBigToHostInt32(kernel_header->adler32));
			return -1;
		}

		DBG("OK.\n");
	}
	
	ret = ThinFatFile(&binary, &len);
	if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
	{
		archCpuType=CPU_TYPE_I386;
		ret = ThinFatFile(&binary, &len);
	}

	// Bungo: no range checking, sorry
	size = 0;
	while (memcmp((uint8_t *)binary + size, (uint8_t *)gDarwinBuildVerStr, 21)) {
		size++;
	}
	gDarwinBuildVerStr = (char *)binary + size;

	// Notify modules that the kernel has been decompressed, thinned and is about to be decoded
	execute_hook("DecodeKernel", (void*)binary, NULL, NULL, NULL);

	ret = DecodeMachO(binary, rentry, raddr, rsize);
	if (ret < 0 && archCpuType == CPU_TYPE_X86_64)
	{
		archCpuType = CPU_TYPE_I386;
		ret = DecodeMachO(binary, rentry, raddr, rsize);
	}

	return ret;
}
コード例 #12
0
ファイル: drivers.c プロジェクト: JayMonkey/chameleon
long 
DecodeKernel(void *binary, entry_t *rentry, char **raddr, int *rsize)
{
	long ret;
	compressed_kernel_header * kernel_header = (compressed_kernel_header *) binary;
	u_int32_t uncompressed_size, size;
	void *buffer;
	unsigned long len;
	
#if 0
	printf("kernel header:\n");
	printf("signature: 0x%x\n", kernel_header->signature);
	printf("compress_type: 0x%x\n", kernel_header->compress_type);
	printf("adler32: 0x%x\n", kernel_header->adler32);
	printf("uncompressed_size: 0x%x\n", kernel_header->uncompressed_size);
	printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
	getchar();
#endif
	
	if (kernel_header->signature == OSSwapBigToHostConstInt32('comp'))
	{
		if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss'))
		{
			error("kernel compression is bad\n");
			return -1;
		}
#if NOTDEF
		if (kernel_header->platform_name[0] && strcmp(gPlatformName, kernel_header->platform_name))
			return -1;
		if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
			return -1;
#endif
		uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
		binary = buffer = malloc(uncompressed_size);
		
		size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0],
							   OSSwapBigToHostInt32(kernel_header->compressed_size));
		if (uncompressed_size != size) {
			error("size mismatch from lzss: %x\n", size);
			return -1;
		}
		
		if (OSSwapBigToHostInt32(kernel_header->adler32) !=
			Adler32(binary, uncompressed_size))
		{
			printf("adler mismatch\n");
			return -1;
		}
	}
	
	ret = ThinFatFile(&binary, &len);
    if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
    {
        archCpuType=CPU_TYPE_I386;
        ret = ThinFatFile(&binary, &len);
    }
    
    // Notify modules that the kernel has been decompressed, thinned and is about to be decoded
	execute_hook("DecodeKernel", (void*)binary, NULL, NULL, NULL);
    
    
    ret = DecodeMachO(binary, rentry, raddr, rsize);
    if (ret<0 && archCpuType==CPU_TYPE_X86_64)
    {
        archCpuType=CPU_TYPE_I386;
        ret = DecodeMachO(binary, rentry, raddr, rsize);
    }
    
    return ret;
}
コード例 #13
0
ファイル: options.c プロジェクト: svn2github/chameleon
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;
}
コード例 #14
0
ファイル: modules.c プロジェクト: Klozz/ChameleonFRK
/*
 * Initialize the module system by loading the Symbols.dylib module.
 * Once loaded, locate the _lookup_symbol function so that internal
 * symbols can be resolved.
 */
int init_module_system()
{
	// Start any modules that were compiled in first.
	start_built_in_modules();


	int retVal = 0;
	void (*module_start)(void) = NULL;

	extern char  symbols_start  __asm("section$start$__DATA$__Symbols");
	char* module_data = &symbols_start;

	// Intialize module system
	if(module_data)
	{
		// Module system  was compiled in (Symbols.dylib addr known)
		module_start = parse_mach(module_data, &load_module, &add_symbol, NULL);

		if(module_start && (module_start != (void*)0xFFFFFFFF))
		{
			// Notify the system that it was laoded
			module_loaded(SYMBOLS_MODULE, module_start, SYMBOLS_AUTHOR, SYMBOLS_DESCRIPTION, SYMBOLS_VERSION, SYMBOLS_COMPAT);
			(*module_start)();	// Start the module. This will point to load_all_modules due to the way the dylib was constructed.
			DBG("Module %s Loaded.\n", SYMBOLS_MODULE);
			retVal = 1;

		}
		else
		{
			// The module does not have a valid start function
			printf("Unable to start %s at 0x%x\n", SYMBOLS_MODULE, module_data);
			pause();
		}
	}

	// Look for modules located in the multiboot header.
	if(gMI && (gMI->mi_flags & MULTIBOOT_INFO_HAS_MODS))
	{
		if(gMI->mi_mods_count)
		{
			struct multiboot_module* mod = (struct multiboot_module*)gMI->mi_mods_addr;
			while(gMI->mi_mods_count--)
			{
				if(mod->mm_string)
				{
					// Convert string to module name, check for dylib.
					if(strcmp(&mod->mm_string[strlen(mod->mm_string) - sizeof("dylib")], ".dylib") == 0)
					{
						module_data = (char*)mod->mm_mod_start;

						char* last = strrchr(mod->mm_string, '/');
						if(last)
						{
							last++;
						}
						else
						{
							last = mod->mm_string;
						}

						char *name = strdup(last);
						name[strlen(last) - sizeof("dylib")] = 0;
						DBG("Loading multiboot module %s\n", name);

						module_start = parse_mach(module_data, &load_module, &add_symbol, NULL);

						if(module_start && (module_start != (void*)0xFFFFFFFF))
						{
							// Notify the system that it was laoded
							module_loaded(name, module_start, NULL, NULL, 0, 0 /*moduleName, NULL, moduleVersion, moduleCompat*/);
							(*module_start)();	// Start the module
							DBG("Module %s Loaded.\n", name); DBGPAUSE();
						}
					}
				}
			}
		}
	}

	if(retVal) execute_hook("ModulesLoaded", NULL, NULL, NULL, NULL);

	return retVal;
}
コード例 #15
0
ファイル: pci_setup.c プロジェクト: svn2github/chameleon
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;
    }
}
コード例 #16
0
int getBootOptions(bool firstRun)
{
	int     i;
	int     key;
	int     nextRow;
	int     timeout;
#if UNUSED
	int     bvCount;
#endif
	BVRef   bvr;
	BVRef   menuBVR;
	bool    showPrompt, newShowPrompt, isCDROM;
    int     optionKey;
	
	// Initialize default menu selection entry.
	menuBVR = selectBootVolume(getBvChain());
	safe_set_env(envgBootVolume, (uint32_t)menuBVR);
	
	if (biosDevIsCDROM((int)get_env(envgBIOSDev))) {
		isCDROM = true;
	} else {
		isCDROM = false;
	}
	
	// Clear command line boot arguments
	clearBootArgs();
	
	// Allow user to override default timeout.
#if UNUSED
	if (multiboot_timeout_set) {
		timeout = multiboot_timeout;
	} else 
#endif
		if (!getIntForKey(kTimeoutKey, &timeout, DEFAULT_BOOT_CONFIG)) {
			/*  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 = get_env(envSysConfigValid) ? kBootTimeout : 0;
			}
		}
	
    long gBootMode = (long)get_env(envgBootMode);
    
	if (timeout < 0) {
		gBootMode |= kBootModeQuiet;
        safe_set_env(envgBootMode,gBootMode);
		
	}
	
	// If the user is holding down a modifier key, enter safe mode.
	if ((readKeyboardShiftFlags() & 0x0F) != 0) {
		
		gBootMode |= kBootModeSafe;
        safe_set_env(envgBootMode,gBootMode);
		
	}
	
	// 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;
        safe_set_env(envgBootMode,gBootMode);
		
		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);
	}
	
	setCursorPosition(0, 0, 0);
	clearScreenRows(0, kScreenLastRow);
	if (!(gBootMode & kBootModeQuiet)) {
		// Display banner and show hardware info.
        char * bootBanner = (char*)(uint32_t)get_env(envBootBanner);
        
		printf(bootBanner, (int)(get_env(envConvMem) + get_env(envExtMem)) / 1024);       
	}
	changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
	msglog("Scanning device %x...", (uint32_t)get_env(envgBIOSDev));
	
	// 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;
		
		if (getValueForKey(kCDROMPromptKey, &val, &cnt, DEFAULT_BOOT_CONFIG)) {
			prompt = calloc(cnt + 1, sizeof(char));
            if (!prompt) {
                stop("Couldn't allocate memory for the prompt\n"); //TODO: Find a better stategie
                return -1;
            }
			strncat(prompt, val, cnt);
		} else {			
            prompt = calloc(256, sizeof(char));
            if (!prompt) {
                stop("Couldn't allocate memory for the prompt\n"); //TODO: Find a better stategie
                return -1;
            }
            BVRef bvr;
            if (( bvr = ((BVRef)(uint32_t)get_env(envgBootVolume)))) {
                name = calloc(80, sizeof(char));
                if (!name) {
                    stop("Couldn't allocate memory for the device name\n"); //TODO: Find a better stategie
                    return -1;
                }
                getBootVolumeDescription(bvr, name, 79, false);
                
                snprintf(prompt, 256,"Press ENTER to start up from %s, or press any key to enter startup options.", name);
                free(name);
            } else snprintf(prompt, 256,"Press ENTER to start up, or press any key to enter startup options.");
			
		}
		
		if (getIntForKey( kCDROMOptionKey, &optionKey, DEFAULT_BOOT_CONFIG )) {
			// 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, &optionKey);
		} else {
			key = optionKey;
		}
		
		if (prompt != NULL) {
			free(prompt);
		}
		
		clearScreenRows( kMenuTopRow, kMenuTopRow + 2 );
		
        do {
            // Hit the option key ?
            if (key == optionKey) {
				
                if (key != 0x1C0D) {
                    gBootMode &= ~kBootModeQuiet;
                    safe_set_env(envgBootMode,gBootMode);
                    timeout = 0;
                    break;
                }
                
            } 
            
            key = key & 0xFF;
            
            // Try booting hard disk if user pressed 'h'
            if (biosDevIsCDROM((int)get_env(envgBIOSDev)) && key == 'h') {
                BVRef bvr;
                
                // Look at partitions hosting OS X other than the CD-ROM
                for (bvr = getBvChain(); bvr; bvr=bvr->next) {
                    if ((bvr->flags & kBVFlagSystemVolume) && bvr->biosdev != (int)get_env(envgBIOSDev)) {
						safe_set_env(envgBootVolume, (uint32_t)bvr);
                    }
                }
            }
            goto done;
            
        } while (0);
		
	}
	
	if (get_env(envgBootMode) & kBootModeQuiet) {
		// No input allowed from user.
		goto done;
	}
	
	if (firstRun && timeout > 0 ) {
        
        key = countdown("Press ENTER to start up, or press any key to enter startup options.", kMenuTopRow, timeout, &optionKey);
        
        if (key == 0x1C0D) {
            goto done;
			
        } 
        else if (key == 0)
        {
            // If the user is holding down a modifier key,
            // enter safe mode.     
            
            if ((readKeyboardShiftFlags() & 0x0F) != 0) {
                gBootMode |= kBootModeSafe;
                safe_set_env(envgBootMode,gBootMode);
            }
            goto done;
        }
	}
	int devcnt = (int)get_env(envgDeviceCount);
    
	if (devcnt) {
		// Allocate memory for an array of menu items.
		menuItems = calloc(devcnt,sizeof(MenuItem));
		if (menuItems == NULL) {
			goto done;
		}
		
		// Associate a menu item for each BVRef.
		for (bvr=getBvChain(), i=devcnt-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--;
			}
		}
	}
	
	// Clear screen and hide the blinking cursor.
	clearScreenRows(kMenuTopRow, kMenuTopRow + 2);
	changeCursor(0, kMenuTopRow, kCursorTypeHidden, 0);
	
	nextRow = kMenuTopRow;
	/*showPrompt = true;*/
	
	if (devcnt) {
		printf("Use \30\31 keys to select the startup volume.");
		showMenu( menuItems, devcnt, selectIndex, kMenuTopRow + 2, kMenuMaxItems );
		nextRow += min( devcnt, kMenuMaxItems ) + 3;
	}
	
	// Show the boot prompt.
	showPrompt = (devcnt == 0) || (menuBVR->flags & kBVFlagNativeBoot);
	showBootPrompt( nextRow, showPrompt );
	
	do {        
        
		key = getc();
		updateMenu( key, (void **) &menuBVR );
		newShowPrompt = (devcnt == 0) || (menuBVR->flags & kBVFlagNativeBoot);
		
		if (newShowPrompt != showPrompt)
		{
			showPrompt = newShowPrompt;
			showBootPrompt( nextRow, showPrompt );
		}
		
		if (showPrompt)
		{            
			updateBootArgs(key);
		}		
        
		switch (key) {
			case kReturnKey:
				if (*gBootArgs == '?') {
					char * argPtr = gBootArgs;
					
					// Skip the leading "?" character.
					argPtr++;
					getNextArg(&argPtr, booterCommand);
					getNextArg(&argPtr, booterParam);
					
					/*
					 * TODO: this needs to be refactored.
					 */
#if UNUSED
					if (strncmp( booterCommand, "video", sizeof("video") ) == 0)
					{
						printVBEModeInfo();
					}
					else
#endif
						if ( strncmp( booterCommand, "memory", sizeof("memory") ) == 0) 
						{
							printMemoryInfo();
						}
						else if (strncmp(booterCommand, "lspci", sizeof( "lspci")) == 0) 
						{
							lspci();
						} 
						else if (strncmp(booterCommand, "more",  sizeof("more")) == 0) 
						{
							showTextFile(booterParam);
						}
						else if (strncmp(booterCommand, "rd", sizeof("rd")) == 0) 
						{
							if (execute_hook("processRAMDiskCommand", (void*)argPtr, &booterParam, NULL, NULL, NULL, NULL) != EFI_SUCCESS)
								showMessage("ramdisk module not found, please install RamdiskLoader.dylib in /Extra/modules/");
						} 
						else if (strncmp(booterCommand, "norescan", sizeof("norescan")) == 0)
						{
							if (get_env(envgEnableCDROMRescan))
							{
                                safe_set_env(envgEnableCDROMRescan,false);
								break;
							}
						}
						else
						{
							showHelp();
						}
					key = 0;
					showBootPrompt(nextRow, showPrompt);
					break;
				}
				safe_set_env(envgBootVolume, (uint32_t)menuBVR);
				setRootVolume(menuBVR);
                safe_set_env(envgBIOSDev,menuBVR->biosdev);
				break;
				
			case kEscapeKey:
				clearBootArgs();
				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 (get_env(envgEnableCDROMRescan)) {
					//gBootVolume = NULL;
					safe_set_env(envgBootVolume, (uint32_t)NULL);
					clearBootArgs();
				}
				break;
				
			case kF10Key:
                safe_set_env(envgScanSingleDrive, false);
                
                scanDisks();
                
				//gBootVolume = NULL;
				safe_set_env(envgBootVolume, (uint32_t)NULL);
				
				clearBootArgs();
				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);
	}
    safe_set_env(envShouldboot, false);
	
	if (menuItems) {
		free(menuItems);
		menuItems = NULL;
	}
	return 0;
}
コード例 #17
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;
	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();
	}
}
コード例 #18
0
void NBI_PreBoot_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)
{	
	
	bool dummyVal = 0;
	config_file_t systemVersion;
	
	char valid = false;
	const char *val;
	int len;
	const char* gPrevMacOSBuildVersion;
	
	
	if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion))
	{
		valid = true;
	}
	else if (!loadConfigFile("System/Library/CoreServices/ServerVersion.plist", &systemVersion))
	{
		valid = true;
	}
	
	if (valid)
	{
		if  (getValueForKey("ProductBuildVersion", &val, &len, &systemVersion))
		{
			
			if (!loadConfigFile("Extra/SystemVersion.LastPatched.plist", &systemVersion))
			{
				if(getValueForKey("ProductBuildVersion", &gPrevMacOSBuildVersion, &len, &systemVersion))
				{
					if(strlen(val) != strlen(gPrevMacOSBuildVersion) ||
					   strcmp(val, gPrevMacOSBuildVersion) != 0
					   )
					{
						runNetbookInstaller = 1;
					}
					else 
					{
						// Only allow restore from hibernation if the system hasn't changed, probably a bad idea though
						//char* val="/private/var/vm/sleepimage";
						
						// Do this first to be sure that root volume is mounted
						//ret = GetFileInfo(0, val, &flags, &sleeptime);
						
						//printf("System version has not changed\n");
						//runNetbookInstaller = 0;
						
					}
					
				}
			}
		}
	}
	
	
	
	
	
	if (!runNetbookInstaller && getBoolForKey("recovery", &dummyVal, DEFAULT_BOOT_CONFIG) && dummyVal)
	{
		if(dummyVal) runNetbookInstaller = 2;
	}
	
	if(runNetbookInstaller)
	{
		
		replace_system_function("_LoadDrivers", &NBI_LoadDrivers);
		
		if(runNetbookInstaller == 1 )
		{
			if (execute_hook("isRamDiskRegistred", NULL, NULL, NULL, NULL, NULL, NULL) == EFI_SUCCESS)
			{
				replace_function_any("_md0Ramdisk", &NBI_md0Ramdisk);
			} 
			else
			{
				register_hook_callback("md0Ramdisk", NBI_md0Ramdisk_hook);
			}
			
		}
		
		// Force arch=i386 + -v
		safe_set_env(envarchCpuType, CPU_TYPE_I386);
		safe_set_env(envgVerboseMode, true);
	}
}
コード例 #19
0
long
LoadMatchedModules( void )
{
	TagPtr		  prop;
	ModulePtr	  module;
	char		  *fileName, segName[32];
	DriverInfoPtr driver;
	long		  length, driverAddr, driverLength;
	void		  *executableAddr = 0;

	module = gModuleHead;

	while (module != 0)
	{
		if (module->willLoad)
		{
			prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);

			if (prop != 0)
			{
				fileName = prop->string;
				snprintf(gFileSpec, 4096, "%s%s", module->executablePath, fileName);
				length = LoadThinFatFile(gFileSpec, &executableAddr);
				if (length == 0)
				{
					length = LoadFile(gFileSpec);
					executableAddr = (void *)kLoadAddr;
				}
//				printf("%s length = %d addr = 0x%x\n", gFileSpec, length, driverModuleAddr); getchar();
			}
			else
				length = 0;

			if (length != -1)
			{
//				driverModuleAddr = (void *)kLoadAddr;
//				if (length != 0)
//				{
//					ThinFatFile(&driverModuleAddr, &length);
//				}

				// Make make in the image area.
                
				execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);

				driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;
				driverAddr = AllocateKernelMemory(driverLength);

				// Set up the DriverInfo.
				driver = (DriverInfoPtr)driverAddr;
				driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
				driver->plistLength = module->plistLength;
				if (length != 0)
				{
					driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +
										 module->plistLength);
					driver->executableLength = length;
				}
				else
				{
					driver->executableAddr	 = 0;
					driver->executableLength = 0;
				}
				driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +
									 module->plistLength + driver->executableLength);
				driver->bundlePathLength = module->bundlePathLength;

				// Save the plist, module and bundle.
				strcpy(driver->plistAddr, module->plistAddr);
				if (length != 0)
				{
					memcpy(driver->executableAddr, executableAddr, length);
				}
				strcpy(driver->bundlePathAddr, module->bundlePath);

				// Add an entry to the memory map.
				snprintf(segName, sizeof(segName), "Driver-%lx", (unsigned long)driver);
				AllocateMemoryRange(segName, driverAddr, driverLength,
									kBootDriverTypeKEXT);
			}
		}
		module = module->nextModule;
	}

	return 0;
}
コード例 #20
0
static int ExecKernel(void *binary)
{
    entry_t                   kernelEntry;
    int                       ret;

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

    //Azi: gHaveKernelCache is set here
    ret = DecodeKernel(binary,
                       &kernelEntry,
                       (char **) &bootArgs->kaddr,
                       (int *)&bootArgs->ksize );

    if ( ret != 0 )
        return ret;

    // Reserve space for boot args
    reserveKernBootStruct();

    //Azi: ...
    // Load boot drivers from the specifed root path,
    // if we don't have a prelinked kernel - check load.c 43 & 264
    if (!gHaveKernelCache) {
          LoadDrivers("/");
    }

    clearActivityIndicator();

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

    setupFakeEfi(); //Azi: check position on Mek (plkernel)

    md0Ramdisk();

    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;

	//Azi: Wait=y is breaking other keys when typed "after them" at boot prompt.
	// Works properly if typed in first place or used on Boot.plist.
	if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->bootConfig) && dummyVal) {
		printf("(Wait) "); // Add to trunk?? don't forget that puse uses printf, not verbose!!
		pause();
	}

	usb_loop();

//autoresolution - Check if user disabled AutoResolution at the boot prompt.
	// we can't check the plist here if we have AutoResolution=n there and we anabled it
	// at boot prompt...?????
//	getBoolForKey(kAutoResolutionKey, &gAutoResolution, &bootInfo->bootConfig);
	finishAutoRes();
	
	//Azi: closing Vbios after "if (gVerboseMode)" stuff eliminates the need for setting
	// AutoResolution = true above; but creates another bug when booting in TextMode with -v arg.
	// Simptoms include: staring some seconds at a nicely drawn white screen, after boot prompt.
	// Think i'm just going to end up removing setting gAutoResolution = false
	// on closeVbios().. the more i think, the less sense it makes doing it there!!
//autoresolution - end

	// Notify modules that the kernel is about to be started
	// testing...
	
	if (gMacOSVersion[3] <= '6')
		execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgsPreLion, NULL, NULL);
	else
		execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgs, NULL, NULL);

    // 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();

	setupBooterLog();
	
    finalizeBootStruct();

//Azi: see asm.s LABEL(_disableIRQs)
//	outb(0x21, 0xff);
//	outb(0xa1, 0xff);

    // Jump to kernel's entry point. There's no going back now.
	if (gMacOSVersion[3] <= '6')
		startprog( kernelEntry, bootArgsPreLion );
	else
		startprog( kernelEntry, bootArgs );

    // Not reached
    return 0;
}