int processBootOptions() { const char * cp = gBootArgs; const char * val = 0; const char * kernel; int cnt; int userCnt; int cntRemaining; char * argP; char uuidStr[64]; bool uuidSet = false; char * configKernelFlags; char * valueBuffer; valueBuffer = malloc(VALUE_SIZE); skipblanks( &cp ); // Update the unit and partition number. if ( gBootVolume ) { if (!( gBootVolume->flags & kBVFlagNativeBoot )) { readBootSector( gBootVolume->biosdev, gBootVolume->part_boff, (void *) 0x7c00 ); // // Setup edx, and signal intention to chain load the // foreign booter. // chainbootdev = gBootVolume->biosdev; chainbootflag = 1; return 1; } setRootVolume(gBootVolume); } // If no boot volume fail immediately because we're just going to fail // trying to load the config file anyway. else return -1; // Load config table specified by the user, or use the default. if (!getValueForBootKey(cp, "config", &val, &cnt)) { val = 0; cnt = 0; } // Load com.apple.Boot.plist from the selected volume // and use its contents to override default bootConfig. // This is not a mandatory operation anymore. loadOverrideConfig(&bootInfo->overrideConfig); // Use the kernel name specified by the user, or fetch the name // in the config table, or use the default if not specified. // Specifying a kernel name on the command line, or specifying // a non-default kernel name in the config file counts as // overriding the kernel, which causes the kernelcache not // to be used. gOverrideKernel = false; if (( kernel = extractKernelName((char **)&cp) )) { strcpy( bootInfo->bootFile, kernel ); gOverrideKernel = true; } else { if ( getValueForKey( kKernelNameKey, &val, &cnt, &bootInfo->bootConfig ) ) { strlcpy( bootInfo->bootFile, val, cnt+1 ); if (strcmp( bootInfo->bootFile, kDefaultKernel ) != 0) { gOverrideKernel = true; } } else { strcpy( bootInfo->bootFile, kDefaultKernel ); } } cntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space argP = bootArgs->CommandLine; // Get config table kernel flags, if not ignored. if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) || !getValueForKey( kKernelFlagsKey, &val, &cnt, &bootInfo->bootConfig )) { val = ""; cnt = 0; } configKernelFlags = malloc(cnt + 1); strlcpy(configKernelFlags, val, cnt + 1); if (processBootArgument(kBootUUIDKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, 0)) { // boot-uuid was set either on the command-line // or in the config file. uuidSet = true; } else { // // Try an alternate method for getting the root UUID on boot helper partitions. // if (gBootVolume->flags & kBVFlagBooter) { if((loadHelperConfig(&bootInfo->helperConfig) == 0) && getValueForKey(kHelperRootUUIDKey, &val, &cnt, &bootInfo->helperConfig) ) { getValueForKey(kHelperRootUUIDKey, &val, &cnt, &bootInfo->helperConfig); copyArgument(kBootUUIDKey, val, cnt, &argP, &cntRemaining); uuidSet = true; } } if (!uuidSet && gBootVolume->fs_getuuid && gBootVolume->fs_getuuid (gBootVolume, uuidStr) == 0) { verbose("Setting boot-uuid to: %s\n", uuidStr); copyArgument(kBootUUIDKey, uuidStr, strlen(uuidStr), &argP, &cntRemaining); uuidSet = true; } } if (!processBootArgument(kRootDeviceKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gRootDevice)) { cnt = 0; if ( getValueForKey( kBootDeviceKey, &val, &cnt, &bootInfo->bootConfig)) { valueBuffer[0] = '*'; cnt++; strlcpy(valueBuffer + 1, val, cnt); val = valueBuffer; } else { if (uuidSet) { val = "*uuid"; cnt = 5; } else { // Don't set "rd=.." if there is no boot device key // and no UUID. val = ""; cnt = 0; } } if (cnt > 0) { copyArgument( kRootDeviceKey, val, cnt, &argP, &cntRemaining); } strlcpy( gRootDevice, val, (cnt + 1)); } /* * Removed. We don't need this anymore. * if (!processBootArgument(kPlatformKey, cp, configKernelFlags, bootInfo->config, &argP, &cntRemaining, gPlatformName)) { getPlatformName(gPlatformName); copyArgument(kPlatformKey, gPlatformName, strlen(gPlatformName), &argP, &cntRemaining); } */ if (!getValueForBootKey(cp, kSafeModeFlag, &val, &cnt) && !getValueForBootKey(configKernelFlags, kSafeModeFlag, &val, &cnt)) { if (gBootMode & kBootModeSafe) { copyArgument(0, kSafeModeFlag, strlen(kSafeModeFlag), &argP, &cntRemaining); } } // Store the merged kernel flags and boot args. cnt = strlen(configKernelFlags); if (cnt) { if (cnt > cntRemaining) { error("Warning: boot arguments too long, truncating\n"); cnt = cntRemaining; } strncpy(argP, configKernelFlags, cnt); argP[cnt++] = ' '; cntRemaining -= cnt; } userCnt = strlen(cp); if (userCnt > cntRemaining) { error("Warning: boot arguments too long, truncating\n"); userCnt = cntRemaining; } strncpy(&argP[cnt], cp, userCnt); argP[cnt+userCnt] = '\0'; if(!shouldboot) { gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, &bootInfo->bootConfig ) || getValueForKey( kSingleUserModeFlag, &val, &cnt, &bootInfo->bootConfig ); gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, &bootInfo->bootConfig ) ) ? kBootModeSafe : kBootModeNormal; if ( getValueForKey( kIgnoreCachesFlag, &val, &cnt, &bootInfo->bootConfig ) ) { gBootMode = kBootModeSafe; } } if ( getValueForKey( kMKextCacheKey, &val, &cnt, &bootInfo->bootConfig ) ) { strlcpy(gMKextName, val, cnt + 1); } free(configKernelFlags); free(valueBuffer); return 0; }
int processBootOptions(void) { char *cp_cache = (char*)(uint32_t)get_env(envgBootArgs); if (cp_cache) { bzero(gBootArgs,sizeof(gBootArgs)); strlcpy(gBootArgs, cp_cache,sizeof(gBootArgs)); } const char * cp = gBootArgs; const char * val = 0; const char * kernel; int cnt; int userCnt; char * argP; char * configKernelFlags; int ArgCntRemaining; skipblanks( &cp ); // Update the unit and partition number. if ( ((BVRef)(uint32_t)get_env(envgBootVolume)) ) { #ifndef NO_MULTIBOOT_SUPPORT if (!( ((BVRef)(uint32_t)get_env(envgBootVolume))->flags & kBVFlagNativeBoot )) { readBootSector( ((BVRef)(uint32_t)get_env(envgBootVolume))->biosdev, ((BVRef)(uint32_t)get_env(envgBootVolume))->part_boff, (void *) 0x7c00 ); // // Setup edx, and signal intention to chain load the // foreign booter. // extern unsigned char chainbootdev; extern unsigned char chainbootflag; chainbootdev = ((BVRef)(uint32_t)get_env(envgBootVolume))->biosdev; chainbootflag = 1; return 1; } #endif setRootVolume(((BVRef)(uint32_t)get_env(envgBootVolume))); } // If no boot volume fail immediately because we're just going to fail // trying to load the config file anyway. else return -1; // Load config table specified by the user, or use the default. if (!getValueForBootKey(cp, "config", &val, &cnt)) { val = 0; cnt = 0; } // Load com.apple.Boot.plist from the selected volume // and use its contents to override default bootConfig. // This is not a mandatory opeartion anymore. loadOverrideConfig(); // Load System com.apple.boot.plist config file loadSystemConfig(); #if virtualM || PCI_FIX // we can simply make an option for this fix addBootArg("npci=0x2000"); #endif #if verbose addBootArg("-v"); #endif // Use the kernel name specified by the user, or fetch the name // in the config table, or use the default if not specified. // Specifying a kernel name on the command line, or specifying // a non-default kernel name in the config file counts as // overriding the kernel, which causes the kernelcache not // to be used. safe_set_env(envgOverrideKernel,false); if (( kernel = extractKernelName((char **)&cp) )) { strlcpy( bootInfo->bootFile, kernel, sizeof(bootInfo->bootFile) ); safe_set_env(envgOverrideKernel,true); } else { if ( getValueForKey( kKernelNameKey, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) { strlcpy( bootInfo->bootFile, val, sizeof(bootInfo->bootFile) ); if (strncmp( bootInfo->bootFile, kDefaultKernel, sizeof(kDefaultKernel) ) != 0) { safe_set_env(envgOverrideKernel,true); } } else if (((BVRef)(uint32_t)get_env(envgBootVolume))->kernelfound == true) { strlcpy( bootInfo->bootFile, kDefaultKernel, sizeof(bootInfo->bootFile) ); } else { printf("No kernel found on this volume : hd(%d,%d)\n", BIOS_DEV_UNIT(((BVRef)(uint32_t)get_env(envgBootVolume))), ((BVRef)(uint32_t)get_env(envgBootVolume))->part_no); sleep(1); return -1; } } ArgCntRemaining = BOOT_STRING_LEN - 2; // save 1 for NULL, 1 for space argP = bootArgs->CommandLine; // Get config table kernel flags, if not ignored. if (getValueForBootKey(cp, kIgnoreBootFileFlag, &val, &cnt) || !getValueForKey( kKernelFlagsKey, &val, &cnt, DEFAULT_BOOT_CONFIG )) { val = ""; cnt = 0; } configKernelFlags = newString(val); { bool isSafeMode = false; if (configKernelFlags) { isSafeMode = getValueForBootKey(configKernelFlags, kSafeModeFlag, &val, &cnt); } if (!getValueForBootKey(cp, kSafeModeFlag, &val, &cnt) && (isSafeMode == false)) { if (get_env(envgBootMode) & kBootModeSafe) { copyArgument(0, kSafeModeFlag, strlen(kSafeModeFlag), &argP, &ArgCntRemaining); } } } if (configKernelFlags) { // Store the merged kernel flags and boot args. cnt = strlen(configKernelFlags); if (cnt) { if (cnt > ArgCntRemaining) { printf("Warning: boot arguments too long, truncating\n"); cnt = ArgCntRemaining; } strncpy(argP, configKernelFlags, cnt); argP[cnt++] = ' '; ArgCntRemaining -= cnt; } } userCnt = strlen(cp); if (userCnt > ArgCntRemaining) { printf("Warning: boot arguments too long, truncating\n"); userCnt = ArgCntRemaining; } strncpy(&argP[cnt], cp, userCnt); argP[cnt+userCnt] = '\0'; if(!get_env(envShouldboot)) { bool gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, DEFAULT_BOOT_CONFIG ) || getValueForKey( kSingleUserModeFlag, &val, &cnt, DEFAULT_BOOT_CONFIG ); safe_set_env(envgVerboseMode, gVerboseMode); long gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) ? kBootModeSafe : kBootModeNormal; safe_set_env(envgBootMode,gBootMode); if ( getValueForKey( kIgnoreCachesFlag, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) { gBootMode = kBootModeSafe; safe_set_env(envgBootMode,gBootMode); } } if ( getValueForKey( kMKextCacheKey, &val, &cnt, DEFAULT_BOOT_CONFIG ) ) { char * MKextName = (char*)(uint32_t)get_env(envMKextName); strlcpy(MKextName,val,Cache_len_name); } if (configKernelFlags) { free(configKernelFlags); } safe_set_env(envArgCntRemaining,ArgCntRemaining); return 0; }