diff --git a/data/settings/kernel/drivers/kernel b/data/settings/kernel/drivers/kernel index 21a81bda63..e0a093ca3d 100644 --- a/data/settings/kernel/drivers/kernel +++ b/data/settings/kernel/drivers/kernel @@ -59,3 +59,6 @@ acpi true #acpi_avoid_full_init true # Avoids running _INI and _STA methods and final object initialization, # which may be used to for debugging ACPI issues, false by default + +#4gb_memory_limit true + # Ignores all memory beyond the 4 GB address limit. Default is false. diff --git a/headers/private/system/safemode_defs.h b/headers/private/system/safemode_defs.h index 5fe530ad0a..7bd2435bdd 100644 --- a/headers/private/system/safemode_defs.h +++ b/headers/private/system/safemode_defs.h @@ -15,6 +15,7 @@ #define B_SAFEMODE_DISABLE_SMP "disable_smp" #define B_SAFEMODE_DISABLE_HYPER_THREADING "disable_hyperthreading" #define B_SAFEMODE_FAIL_SAFE_VIDEO_MODE "fail_safe_video_mode" +#define B_SAFEMODE_4_GB_MEMORY_LIMIT "4gb_memory_limit" #if DEBUG_SPINLOCK_LATENCIES # define B_SAFEMODE_DISABLE_LATENCY_CHECK "disable_latency_check" diff --git a/src/system/boot/loader/load_driver_settings.cpp b/src/system/boot/loader/load_driver_settings.cpp index ebb792263d..b38ead2851 100644 --- a/src/system/boot/loader/load_driver_settings.cpp +++ b/src/system/boot/loader/load_driver_settings.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include #include #include @@ -58,6 +60,20 @@ load_driver_settings_file(Directory* directory, const char* name) } +static void +apply_boot_settings(void* kernelSettings, void* safemodeSettings) +{ +#if B_HAIKU_PHYSICAL_BITS > 32 + if (get_driver_boolean_parameter(kernelSettings, "4gb_memory_limit", false, + false) + || get_driver_boolean_parameter(safemodeSettings, + B_SAFEMODE_4_GB_MEMORY_LIMIT, false, false)) { + ignore_physical_memory_ranges_beyond_4gb(); + } +#endif +} + + // #pragma mark - @@ -133,3 +149,18 @@ add_safe_mode_settings(char* settings) return B_OK; } + + +void +apply_boot_settings() +{ + void* kernelSettings = load_driver_settings("kernel"); + void* safemodeSettings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); + + apply_boot_settings(kernelSettings, safemodeSettings); + + if (safemodeSettings != NULL) + unload_driver_settings(safemodeSettings); + if (kernelSettings) + unload_driver_settings(kernelSettings); +} diff --git a/src/system/boot/loader/load_driver_settings.h b/src/system/boot/loader/load_driver_settings.h index 1648ab192f..a5ad2f86a6 100644 --- a/src/system/boot/loader/load_driver_settings.h +++ b/src/system/boot/loader/load_driver_settings.h @@ -13,4 +13,7 @@ extern status_t add_safe_mode_settings(char *buffer); extern status_t add_stage2_driver_settings(stage2_args *args); extern status_t load_driver_settings(stage2_args *args, Directory *volume); +extern void apply_boot_settings(); + + #endif /* LOAD_DRIVER_SETTINGS_H */ diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index db23ea9dd5..bc67e3a9ab 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -113,6 +113,9 @@ main(stage2_args *args) load_modules(args, volume); load_driver_settings(args, volume); + // apply boot settings + apply_boot_settings(); + // set up kernel args version info gKernelArgs.kernel_args_size = sizeof(kernel_args); gKernelArgs.version = CURRENT_KERNEL_ARGS_VERSION; diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index bed9a19473..5c90849002 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -673,6 +673,28 @@ add_safe_mode_menu() item->SetHelpText("Disables IDE DMA, increasing IDE compatibilty " "at the expense of performance."); +#if B_HAIKU_PHYSICAL_BITS > 32 + // check whether we have memory beyond 4 GB + bool hasMemoryBeyond4GB = false; + for (uint32 i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) { + phys_addr_range& range = gKernelArgs.physical_memory_range[i]; + if (range.start >= (phys_addr_t)1 << 32) { + hasMemoryBeyond4GB = true; + break; + } + } + + // ... add the menu, if so + if (hasMemoryBeyond4GB) { + safeMenu->AddItem( + item = new(nothrow) MenuItem("Ignore memory beyond 4 GiB")); + item->SetData(B_SAFEMODE_4_GB_MEMORY_LIMIT); + item->SetType(MENU_ITEM_MARKABLE); + item->SetHelpText("Ignores all memory beyond the 4 GiB address limit, " + "overriding the setting in the kernel settings file."); + } +#endif + platform_add_menus(safeMenu); safeMenu->AddSeparatorItem();