update_engine: New BootControlInterface class.
The new BootControlInterface class is a platform-independent
abstraction to control the bootloader. It provides methods for setting
what partition slots are available for booting and getting the
bootloader status about the available slots.
The Chrome OS specific implementation of the bootloader was moved to
the BootControlChromeOS which now depends on the vboot_host
implementation used in Chrome OS. Follow up CL will implement the
equivalent class for Brillo.
BUG=b:23010637
TEST=unittests; cros flash from the new image and rolled back from it.
Change-Id: I0a03aeeb8c21d8c99e1866b625e6e8c96628215b
diff --git a/boot_control_interface.h b/boot_control_interface.h
new file mode 100644
index 0000000..135d2eb
--- /dev/null
+++ b/boot_control_interface.h
@@ -0,0 +1,85 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_BOOT_CONTROL_INTERFACE_H_
+#define UPDATE_ENGINE_BOOT_CONTROL_INTERFACE_H_
+
+#include <climits>
+#include <string>
+
+#include <base/macros.h>
+
+namespace chromeos_update_engine {
+
+// The abstract boot control interface defines the interaction with the
+// platform's bootloader hiding vendor-specific details from the rest of
+// update_engine. This interface is used for controlling where the device should
+// boot from.
+class BootControlInterface {
+ public:
+ using Slot = unsigned int;
+
+ static const Slot kInvalidSlot = UINT_MAX;
+
+ virtual ~BootControlInterface() = default;
+
+ // Return the number of update slots in the system. A system will normally
+ // have two slots, named "A" and "B" in the documentation, but sometimes
+ // images running from other media can have only one slot, like some USB
+ // image. Systems with only one slot won't be able to update.
+ virtual unsigned int GetNumSlots() const = 0;
+
+ // Return the slot where we are running the system from. On success, the
+ // result is a number between 0 and GetNumSlots() - 1. Otherwise, log an error
+ // and return kInvalidSlot.
+ virtual Slot GetCurrentSlot() const = 0;
+
+ // Determines the block device for the given partition name and slot number.
+ // The |slot| number must be between 0 and GetNumSlots() - 1 and the
+ // |partition_name| is a platform-specific name that identifies a partition on
+ // every slot. On success, returns true and stores the block device in
+ // |device|.
+ virtual bool GetPartitionDevice(const std::string& partition_name,
+ Slot slot,
+ std::string* device) const = 0;
+
+ // Returns whether the passed |slot| is marked as bootable. Returns false if
+ // the slot is invalid.
+ virtual bool IsSlotBootable(Slot slot) const = 0;
+
+ // Mark the specified slot unbootable. No other slot flags are modified.
+ // Returns true on success.
+ virtual bool MarkSlotUnbootable(Slot slot) = 0;
+
+ // Return a human-readable slot name used for logging.
+ static std::string SlotName(Slot slot) {
+ if (slot == kInvalidSlot)
+ return "INVALID";
+ if (slot < 26)
+ return std::string(1, 'A' + slot);
+ return "TOO_BIG";
+ }
+
+ protected:
+ BootControlInterface() = default;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BootControlInterface);
+};
+
+} // namespace chromeos_update_engine
+
+#endif // UPDATE_ENGINE_BOOT_CONTROL_INTERFACE_H_