diff --git a/src/kernel/boot/loader/load_driver_settings.cpp b/src/kernel/boot/loader/load_driver_settings.cpp index 02e002eacf..12f7f5453d 100644 --- a/src/kernel/boot/loader/load_driver_settings.cpp +++ b/src/kernel/boot/loader/load_driver_settings.cpp @@ -7,6 +7,7 @@ #include "load_driver_settings.h" #include +#include #include #include @@ -82,3 +83,34 @@ load_driver_settings(stage2_args */*args*/, Directory *volume) return B_OK; } + + +status_t +add_safe_mode_settings(char *settings) +{ + if (settings == NULL || settings[0] == '\0') + return B_OK; + + size_t length = strlen(settings); + char *buffer = (char *)kernel_args_malloc(length + 1); + if (buffer == NULL) + return B_NO_MEMORY; + + driver_settings_file *file = (driver_settings_file *)kernel_args_malloc(sizeof(driver_settings_file)); + if (file == NULL) { + kernel_args_free(buffer); + return B_NO_MEMORY; + } + + strlcpy(file->name, B_SAFEMODE_DRIVER_SETTINGS, sizeof(file->name)); + memcpy(buffer, settings, length + 1); + file->buffer = buffer; + file->size = length; + + // add it to the list + file->next = gKernelArgs.driver_settings; + gKernelArgs.driver_settings = file; + + return B_OK; +} + diff --git a/src/kernel/boot/loader/load_driver_settings.h b/src/kernel/boot/loader/load_driver_settings.h index 978ade0868..499d79dc25 100644 --- a/src/kernel/boot/loader/load_driver_settings.h +++ b/src/kernel/boot/loader/load_driver_settings.h @@ -9,6 +9,7 @@ #include +extern status_t add_safe_mode_settings(char *buffer); extern status_t load_driver_settings(stage2_args *args, Directory *volume); #endif /* LOAD_DRIVER_SETTINGS_H */ diff --git a/src/kernel/boot/loader/menu.cpp b/src/kernel/boot/loader/menu.cpp index 7a30297c49..6be14e3227 100644 --- a/src/kernel/boot/loader/menu.cpp +++ b/src/kernel/boot/loader/menu.cpp @@ -7,6 +7,7 @@ #include "menu.h" #include "loader.h" #include "RootFileSystem.h" +#include "load_driver_settings.h" #include @@ -407,9 +408,15 @@ add_safe_mode_menu() safeMenu->AddItem(item = new MenuItem("Safe mode")); item->SetData(B_SAFEMODE_SAFE_MODE); item->SetType(MENU_ITEM_MARKABLE); + item->SetHelpText("Puts the system into safe mode. This can be enabled independently " + "from the other options."); + safeMenu->AddItem(item = new MenuItem("Disable user add-ons")); item->SetData(B_SAFEMODE_DISABLE_USER_ADD_ONS); item->SetType(MENU_ITEM_MARKABLE); + item->SetHelpText("Prevent all user installed add-ons to be loaded. Only the add-ons " + "in the system directory will be used."); + safeMenu->AddItem(item = new MenuItem("Disable IDE DMA")); item->SetData(B_SAFEMODE_DISABLE_IDE_DMA); item->SetType(MENU_ITEM_MARKABLE); @@ -423,6 +430,27 @@ add_safe_mode_menu() } +static void +apply_safe_mode_options(Menu *menu) +{ + MenuItemIterator iterator = menu->ItemIterator(); + MenuItem *item; + char buffer[2048]; + int32 pos = 0; + + buffer[0] = '\0'; + + while ((item = iterator.Next()) != NULL) { + if (item->Type() == MENU_ITEM_SEPARATOR || !item->IsMarked() || (uint32)pos > sizeof(buffer)) + continue; + + pos += snprintf(buffer + pos, sizeof(buffer) - pos, "%s true\n", (const char *)item->Data()); + } + + add_safe_mode_settings(buffer); +} + + static bool user_menu_reboot(Menu *menu, MenuItem *item) { @@ -435,13 +463,14 @@ status_t user_menu(Directory **_bootVolume) { Menu *menu = new Menu(MAIN_MENU); + Menu *safeModeMenu; MenuItem *item; // Add boot volume menu->AddItem(item = new MenuItem("Select boot volume", add_boot_volume_menu(*_bootVolume))); // Add safe mode - menu->AddItem(item = new MenuItem("Select safe mode options", add_safe_mode_menu())); + menu->AddItem(item = new MenuItem("Select safe mode options", safeModeMenu = add_safe_mode_menu())); // Add platform dependent menus platform_add_menus(menu); @@ -464,6 +493,9 @@ user_menu(Directory **_bootVolume) if (item->Data() != NULL) *_bootVolume = (Directory *)item->Data(); + apply_safe_mode_options(safeModeMenu); + delete menu; + return B_OK; }