fix bootctrl hal
authorJan Altensen <info@stricted.net>
Fri, 24 Apr 2020 16:44:59 +0000 (18:44 +0200)
committerJan Altensen <info@stricted.net>
Fri, 24 Apr 2020 19:27:00 +0000 (21:27 +0200)
Change-Id: I41ab2c439a9c38de2b159ac94f52968022e5d05a

bootctrl/Android.mk [new file with mode: 0644]
bootctrl/bctl_metadata.h
bootctrl/boot_control.cpp [new file with mode: 0644]
device.mk
recovery/root/sbin/android.hardware.boot@1.0-impl.exynos.so [deleted file]
recovery/root/sbin/android.hardware.boot@1.0-service [deleted file]
recovery/root/sbin/android.hardware.boot@1.0.so [deleted file]
recovery/root/vendor/lib64/hw/bootctrl.exynos9610.so [new file with mode: 0644]

diff --git a/bootctrl/Android.mk b/bootctrl/Android.mk
new file mode 100644 (file)
index 0000000..16cc47c
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# Copyright (C) 2020 The LineageOS 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_SHARED_LIBRARIES += liblog libcutils
+LOCAL_HEADER_LIBRARIES := libhardware_headers libsystem_headers
+LOCAL_SRC_FILES := boot_control.cpp
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := bootctrl.exynos9610
+LOCAL_PROPRIETARY_MODULE := true
+include $(BUILD_SHARED_LIBRARY)
+
+# Static library for the target. Used by update_engine_sideload from recovery.
+include $(CLEAR_VARS)
+LOCAL_CFLAGS += -Wall -Werror
+LOCAL_SHARED_LIBRARIES += liblog libcutils
+LOCAL_HEADER_LIBRARIES := libhardware_headers libsystem_headers
+LOCAL_SRC_FILES := boot_control.cpp
+LOCAL_MODULE := bootctrl.exynos9610
+include $(BUILD_STATIC_LIBRARY)
index 8145edce96644b42f0828452c6c8abfb62b1af46..9eec5f3baf4d94dcc0a31e34754220b4fe08acff 100644 (file)
@@ -17,8 +17,6 @@
 #ifndef SAMSUNG_BCTL_METADATA_H\r
 #define SAMSUNG_BCTL_METADATA_H\r
 \r
-#include <iostream>\r
-\r
 #define BCTL_METADATA_PARTITION "/dev/block/bootdevice/by-name/slotinfo"\r
 #define BCTL_METADATA_OFFSET 0x800\r
 #define BCTL_METADATA_MAGIC 0x43425845\r
diff --git a/bootctrl/boot_control.cpp b/bootctrl/boot_control.cpp
new file mode 100644 (file)
index 0000000..29449ed
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2020 The LineageOS 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.
+ */
+#include <map>
+#include <list>
+#include <string>
+#include <vector>
+#include <fstream>
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <errno.h>
+#define LOG_TAG "bootcontrolhal"
+#include <log/log.h>
+#include <hardware/boot_control.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <cutils/properties.h>
+
+#include "bctl_metadata.h"
+
+using namespace std;
+
+static bool validateMetadata(bctl_metadata_t& data) {
+    if (data.slot_info[0].magic != BCTL_METADATA_MAGIC || data.slot_info[1].magic != BCTL_METADATA_MAGIC) {
+        return false;
+    }
+    
+    return true;
+}
+
+static bool readMetadata(bctl_metadata_t& data) {
+    std::fstream in(BCTL_METADATA_PARTITION, std::ios::binary | std::ios::in);
+
+    if (in.fail()) {
+        return false;
+    }
+
+    in.seekg(BCTL_METADATA_OFFSET);
+
+    if (in.fail()) {
+        return false;
+    }
+
+    in.read(reinterpret_cast<char*>(&data), sizeof(bctl_metadata_t));
+
+    if (!validateMetadata(data))
+        return false;
+
+    return !in.eof() && !in.fail();
+}
+
+static bool writeMetadata(bctl_metadata_t& data) {
+    if (!validateMetadata(data))
+        return false;
+
+    // We use std::ios::in | std::ios::out even though we only write so that
+    // we don't truncate or append to the file, but rather overwrite the file
+    // in the exact place that we want to write the struct to.
+    std::fstream out(BCTL_METADATA_PARTITION, std::ios::binary | std::ios::in | std::ios::out);
+
+    if (out.fail()) {
+        return false;
+    }
+
+    out.seekp(BCTL_METADATA_OFFSET);
+
+    if (out.fail()) {
+        return false;
+    }
+
+    out.write(reinterpret_cast<const char*>(&data), sizeof(bctl_metadata_t));
+
+    return !out.eof() && !out.fail();
+}
+
+void boot_control_init(struct boot_control_module *)
+{
+}
+
+
+unsigned get_number_slots(struct boot_control_module *)
+{
+       return 2;
+}
+
+unsigned get_current_slot(struct boot_control_module *)
+{
+    bctl_metadata_t data;
+
+    if (readMetadata(data)) {
+        // This is a clever hack because if slot b is active,
+        // is_active will be 0 and if slot a is active, is_active
+        // will be 1. In other words, the "not" value of slot A's
+        // is_active var lines up to the current active slot index.
+        return !data.slot_info[0].is_active;
+    }
+
+    return 0;
+}
+
+
+int mark_boot_successful(struct boot_control_module *)
+{
+    bctl_metadata_t data;
+    bool success = false;
+    int active_slot;
+
+    if (readMetadata(data)) {
+        active_slot = !data.slot_info[0].is_active;
+        
+        data.slot_info[active_slot].boot_successful = 1;
+        data.slot_info[active_slot].tries_remaining = 0;
+
+        if (success)
+            if (writeMetadata(data)) {
+                return 0;
+            } else {
+                ALOGE("%s: Failed to write metadata", __func__);
+            }
+        else {
+            ALOGE("%s: No active slot", __func__);
+        }
+    } else {
+        ALOGE("%s: Failed to read metadata", __func__);
+    }
+
+    return -1;
+}
+
+const char *get_suffix(struct boot_control_module *, unsigned slot)
+{
+    if (slot < 2) {
+        if (slot == 0) {
+            return SLOT_SUFFIX_A;
+        } else {
+            return SLOT_SUFFIX_B;
+        }
+    }
+    // default to slot A
+    return SLOT_SUFFIX_A;
+
+}
+
+int set_active_boot_slot(struct boot_control_module *, unsigned slot)
+{
+    bctl_metadata_t data;
+    int slot2 = (slot == 0) ? 1 : 0;
+
+    if (slot < 2) {
+        if (readMetadata(data)) {
+            data.slot_info[slot].bootable = 1;
+            data.slot_info[slot].is_active = 1;
+            data.slot_info[slot].boot_successful = 0;
+            data.slot_info[slot].tries_remaining = 7;
+            
+            data.slot_info[slot2].bootable = 1;
+            data.slot_info[slot2].is_active = 0;
+            data.slot_info[slot2].boot_successful = 0;
+            data.slot_info[slot2].tries_remaining = 7;
+
+            if (writeMetadata(data)) {
+                return 0;
+            } else {
+                ALOGE("%s: Failed to write metadata", __func__);
+            }
+        } else {
+            ALOGE("%s: Failed to read metadata", __func__);
+        }
+    } else {
+        ALOGE("%s: Invalid slot", __func__);
+    }
+
+    return -1;
+}
+
+int set_slot_as_unbootable(struct boot_control_module *, unsigned slot)
+{
+    bctl_metadata_t data;
+
+    if (slot < 2) {
+        if (readMetadata(data)) {
+            data.slot_info[slot].bootable = 0;
+
+            if (writeMetadata(data)) {
+                return 0;
+            } else {
+                ALOGE("%s: Failed to write metadata", __func__);
+            }
+        } else {
+            ALOGE("%s: Failed to read metadata", __func__);
+        }
+    } else {
+        ALOGE("%s: Invalid slot", __func__);
+    }
+
+    return -1;
+}
+
+int is_slot_bootable(struct boot_control_module *, unsigned slot)
+{
+    bctl_metadata_t data;
+    int ret = -1;
+
+    if (slot < 2) {
+        if (readMetadata(data)) {
+            ret = static_cast<int>(data.slot_info[slot].bootable);
+        } else {
+            ret = 0;
+        }
+    }
+
+    return ret;
+}
+
+int is_slot_marked_successful(struct boot_control_module *, unsigned slot)
+{
+    bctl_metadata_t data;
+    int ret = -1;
+
+    if (slot < 2) {
+        if (readMetadata(data)) {
+            ret = static_cast<int>(data.slot_info[slot].boot_successful);
+        } else {
+            ret = 0;
+        }
+    } else {
+        ret = -1;
+    }
+
+    return ret;
+}
+
+static hw_module_methods_t boot_control_module_methods = {
+       .open = NULL,
+};
+
+boot_control_module_t HAL_MODULE_INFO_SYM = {
+       .common = {
+               .tag = HARDWARE_MODULE_TAG,
+               .module_api_version = 1,
+               .hal_api_version = 0,
+               .id = BOOT_CONTROL_HARDWARE_MODULE_ID,
+               .name = "Boot control HAL",
+               .author = "Code Aurora Forum",
+               .methods = &boot_control_module_methods,
+       },
+       .init = boot_control_init,
+       .getNumberSlots = get_number_slots,
+       .getCurrentSlot = get_current_slot,
+       .markBootSuccessful = mark_boot_successful,
+       .setActiveBootSlot = set_active_boot_slot,
+       .setSlotAsUnbootable = set_slot_as_unbootable,
+       .isSlotBootable = is_slot_bootable,
+       .getSuffix = get_suffix,
+       .isSlotMarkedSuccessful = is_slot_marked_successful,
+};
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
index 6ba103b98e23c47f9306462e91244630d48869ff..0eded0277dd01e185ceac966b77014e3bfc4658e 100644 (file)
--- a/device.mk
+++ b/device.mk
@@ -21,14 +21,13 @@ AB_OTA_POSTINSTALL_CONFIG += \
 # Enable update engine sideloading by including the static version of the
 # boot_control HAL and its dependencies.
 PRODUCT_STATIC_BOOT_CONTROL_HAL := \
-    libgptutils \
+    bootctrl.exynos9610 \
     libz \
     libcutils
 
 # Boot control HAL
 PRODUCT_PACKAGES += \
-    android.hardware.boot@1.0-impl.exynos \
-    android.hardware.boot@1.0-service \
+    bootctrl.exynos9610
 
 
 
diff --git a/recovery/root/sbin/android.hardware.boot@1.0-impl.exynos.so b/recovery/root/sbin/android.hardware.boot@1.0-impl.exynos.so
deleted file mode 100644 (file)
index de6c4fe..0000000
Binary files a/recovery/root/sbin/android.hardware.boot@1.0-impl.exynos.so and /dev/null differ
diff --git a/recovery/root/sbin/android.hardware.boot@1.0-service b/recovery/root/sbin/android.hardware.boot@1.0-service
deleted file mode 100644 (file)
index f2bba84..0000000
Binary files a/recovery/root/sbin/android.hardware.boot@1.0-service and /dev/null differ
diff --git a/recovery/root/sbin/android.hardware.boot@1.0.so b/recovery/root/sbin/android.hardware.boot@1.0.so
deleted file mode 100644 (file)
index c7c5dde..0000000
Binary files a/recovery/root/sbin/android.hardware.boot@1.0.so and /dev/null differ
diff --git a/recovery/root/vendor/lib64/hw/bootctrl.exynos9610.so b/recovery/root/vendor/lib64/hw/bootctrl.exynos9610.so
new file mode 100644 (file)
index 0000000..003f2e5
Binary files /dev/null and b/recovery/root/vendor/lib64/hw/bootctrl.exynos9610.so differ