Index: boot_mode.cc |
diff --git a/boot_mode.cc b/boot_mode.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..368bb9cc05bcf8e5491aa06f8db216d72c5562e8 |
--- /dev/null |
+++ b/boot_mode.cc |
@@ -0,0 +1,110 @@ |
+// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+// |
+// Relies on underlying platform classes to determine the system state. |
+// In particular, this class orders the current active firmware, |
+// developer mode switch value, and the bootloader kernel commandline |
+// boot parameter to determine the "boot mode". |
+ |
+#include <sys/types.h> |
+ |
+#include "active_main_firmware.h" |
+#include "bootloader_type.h" |
+#include "developer_switch.h" |
+ |
+#include "boot_mode.h" |
+ |
+namespace cros_boot_mode { |
+ |
+const char *BootMode::kBootModeText[] = { |
+ "normal", |
+ "developer", |
+ "normal recovery", |
+ "developer recovery", |
+}; |
+const size_t BootMode::kBootModeCount = |
+ sizeof(kBootModeText) / sizeof(*kBootModeText); |
+ |
+BootMode::BootMode() : |
+ mode_(kUnsupported), |
+ developer_switch_(&default_developer_switch_), |
+ active_main_firmware_(&default_active_main_firmware_), |
+ bootloader_type_(&default_bootloader_type_) { } |
+BootMode::~BootMode() { } |
+ |
+void BootMode::Initialize(bool unsupported_is_developer, bool use_bootloader) { |
+ if (use_bootloader) { |
+ // For now, we treat the bootloader mode as priority over the |
+ // firmware-supplied values. This allows for the kernel commandline to |
+ // allow testing different behaviors changing only the kernel and not |
+ // the switch positions or system image. |
+ bootloader_type_->Initialize(); |
+ // TODO(wad) potentially create a standalone debug mode. TBD. |
+ if (bootloader_type_->value() == BootloaderType::kDebug) { |
+ mode_ = kDeveloper; |
+ return; |
+ } |
+ if (bootloader_type_->value() != BootloaderType::kChromeOS) { |
+ if (unsupported_is_developer) |
+ mode_ = kDeveloper; |
+ return; |
+ } |
+ } |
+ |
+ // After the bootloader, the developer switch position guides the primary |
+ // decision around current mode. |
+ developer_switch_->Initialize(); |
+ switch (developer_switch_->value()) { |
+ case PlatformSwitch::kEnabled: |
+ mode_ = kDeveloper; |
+ break; |
+ case PlatformSwitch::kDisabled: |
+ mode_ = kNormal; |
+ break; |
+ default: |
+ // If we're using the bootloader, rely on it if there's no dev switch. |
+ if (use_bootloader) |
+ return; |
+ // Otherwise, a missing dev switch can be mapped to developer. |
+ if (unsupported_is_developer) |
+ mode_ = kDeveloper; |
+ return; |
+ } |
+ |
+ // The sub-mode of "recovery" can be determined by checking if the firmware |
+ // booted via the recovery firmware. |
+ active_main_firmware_->Initialize(); |
+ if (active_main_firmware_->value() == ActiveMainFirmware::kRecovery) { |
+ if (mode_ == kNormal) { |
+ mode_ = kNormalRecovery; |
+ } else if (mode_ == kDeveloper) { |
+ mode_ = kDeveloperRecovery; |
+ } |
+ } |
+ return; |
+} |
+ |
+ |
+void BootMode::set_developer_switch(DeveloperSwitch *ds) { |
+ if (ds) |
+ developer_switch_ = ds; |
+ else |
+ developer_switch_ = &default_developer_switch_; |
+} |
+ |
+void BootMode::set_active_main_firmware(ActiveMainFirmware *amf) { |
+ if (amf) |
+ active_main_firmware_ = amf; |
+ else |
+ active_main_firmware_ = &default_active_main_firmware_; |
+} |
+ |
+void BootMode::set_bootloader_type(BootloaderType *bt) { |
+ if (bt) |
+ bootloader_type_ = bt; |
+ else |
+ bootloader_type_ = &default_bootloader_type_; |
+} |
+ |
+} // namespace cros_boot_mode |