From 904bc06a623d61d102aa2490c1423e2632c8164e Mon Sep 17 00:00:00 2001 From: merothh Date: Sun, 15 Aug 2021 14:49:48 +0530 Subject: [PATCH] universal9810: Support upgrading firmware - If we are shipping firmware, make sure that we dont flash on any non F (ie. SM-x96xF) model - If the bootloader SW REV. is lower than what is mandated by the build upgrade the firmware. Change-Id: I82066670e45713fae51a07d40972c070e9bd6fb0 --- BoardConfigCommon.mk | 4 ++ board-info.txt | 1 + recovery/Android.bp | 28 +++++++++ recovery/recovery_updater.cpp | 68 ++++++++++++++++++++++ releasetools/releasetools.py | 106 +++++++++++++++++++++++++++++----- 5 files changed, 192 insertions(+), 15 deletions(-) create mode 100644 board-info.txt create mode 100644 recovery/Android.bp create mode 100644 recovery/recovery_updater.cpp diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk index 8cb4aad..7fe351f 100644 --- a/BoardConfigCommon.mk +++ b/BoardConfigCommon.mk @@ -23,6 +23,9 @@ TARGET_SPECIFIC_HEADER_PATH := $(COMMON_PATH)/include TARGET_EXCLUDES_AUDIOFX := true USE_XML_AUDIO_POLICY_CONF := 1 +# Board +TARGET_BOARD_INFO_FILE := $(COMMON_PATH)/board-info.txt + # Bluetooth BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := $(COMMON_PATH)/bluetooth @@ -108,6 +111,7 @@ DEVICE_FRAMEWORK_MANIFEST_FILE := $(COMMON_PATH)/framework_manifest.xml BOARD_PROPERTY_OVERRIDES_SPLIT_ENABLED := true # Releasetools +TARGET_RECOVERY_UPDATER_LIBS := librecovery_updater_universal9810 TARGET_RELEASETOOLS_EXTENSIONS := $(COMMON_PATH)/releasetools # SELinux diff --git a/board-info.txt b/board-info.txt new file mode 100644 index 0000000..1d576dc --- /dev/null +++ b/board-info.txt @@ -0,0 +1 @@ +require version-bootloader-min=F diff --git a/recovery/Android.bp b/recovery/Android.bp new file mode 100644 index 0000000..f6e85d9 --- /dev/null +++ b/recovery/Android.bp @@ -0,0 +1,28 @@ +// +// Copyright (C) 2021 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. +// + +cc_library_static { + name: "librecovery_updater_universal9810", + srcs: [ + "recovery_updater.cpp", + ], + include_dirs: [ + "system/core/base/include", + "bootable/recovery", + "bootable/recovery/edify/include", + "bootable/recovery/otautil/include" + ], +} diff --git a/recovery/recovery_updater.cpp b/recovery/recovery_updater.cpp new file mode 100644 index 0000000..425dfd0 --- /dev/null +++ b/recovery/recovery_updater.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2021, 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 + +#include "edify/expr.h" +#include "otautil/error_code.h" + +Value *VerifyBootloaderMin(const char *name, State *state, + const std::vector> &argv) { + int ret = 0; + std::string bootloader = android::base::GetProperty("ro.boot.bootloader", ""); + if (bootloader.empty()) { + return ErrorAbort(state, kFileGetPropFailure, + "%s() failed to read current bootloader version", name); + } + + std::string min_supported_bootloader_arg; + if (argv.empty() || !Evaluate(state, argv[0], &min_supported_bootloader_arg)) { + return ErrorAbort(state, kArgsParsingFailure, + "%s() error parsing arguments", name); + } + int min_supported_bootloader = int(min_supported_bootloader_arg[0]); + + int version = 0; + if (bootloader.length() >= 5) + version = int(bootloader[bootloader.length() - 5]); + + if (version >= min_supported_bootloader) { + ret = 1; + } + + return StringValue(std::to_string(ret)); +} + +Value *VerifyBootloaderModel(const char *name, State *state, + const std::vector> &argv) { + int ret = 0; + std::string bootloader = android::base::GetProperty("ro.boot.bootloader", ""); + if (bootloader.empty()) { + return ErrorAbort(state, kFileGetPropFailure, + "%s() failed to read current bootloader version", name); + } + + if (bootloader[4] != 'F') { + ret = 1; + } + + return StringValue(std::to_string(ret)); +} + +void Register_librecovery_updater_universal9810() { + RegisterFunction("universal9810.verify_bootloader_min", VerifyBootloaderMin); + RegisterFunction("universal9810.verify_bootloader_model", VerifyBootloaderModel); +} diff --git a/releasetools/releasetools.py b/releasetools/releasetools.py index 25a16b1..b5cb39a 100644 --- a/releasetools/releasetools.py +++ b/releasetools/releasetools.py @@ -1,16 +1,92 @@ +import common +import re + def FullOTA_Assertions(info): - info.script.AppendExtra('ifelse(is_mounted("/vendor"), unmount("/vendor"));'); - info.script.AppendExtra('mount("ext4", "EMMC", "/dev/block/platform/11120000.ufs/by-name/VENDOR", "/vendor");'); - info.script.AppendExtra('ifelse(file_getprop("/vendor/build.prop","ro.vendor.build.version.sdk") != "29",'); - info.script.AppendExtra('unmount("/vendor");'); - info.script.AppendExtra('ui_print(" ");'); - info.script.AppendExtra('ui_print("=============================================");'); - info.script.AppendExtra('ui_print("=============================================");'); - info.script.AppendExtra('ui_print(" ERROR: ");'); - info.script.AppendExtra('ui_print(" Vendor image on the device ");'); - info.script.AppendExtra('ui_print(" is NOT compatible ");'); - info.script.AppendExtra('ui_print(" Expected Android 10 vendor ");'); - info.script.AppendExtra('ui_print("=============================================");'); - info.script.AppendExtra('ui_print("============NO CHANGE HAS BEEN MADE==========");'); - info.script.AppendExtra('abort(" "););'); - info.script.AppendExtra('unmount("/vendor");'); + if "IMAGES/vendor.img" not in info.input_zip.namelist(): + AddVendorAssertion(info) + + # If we are shipping firmware or prebuilt vendor, make sure that we only flash on F variant + if "RADIO/filemap" in info.input_zip.namelist() or "IMAGES/vendor.img" in info.input_zip.namelist(): + AddBlModelAssertion(info) + +def FullOTA_InstallEnd(info): + skip_firmware = False + + # Skip Firmware if filemap or any of the images are not present + if "RADIO/filemap" not in info.input_zip.namelist(): + skip_firmware = True + else: + filemap = info.input_zip.read("RADIO/filemap").decode('utf-8').splitlines() + for file in filemap: + filename = file.split(" ")[0] + if "RADIO/{}".format(filename) not in info.input_zip.namelist(): + skip_firmware = True + break + + if "IMAGES/vendor.img" in info.input_zip.namelist(): + common.ZipWriteStr(info.output_zip, "firmware-update/vendor.img", info.input_zip.read("IMAGES/vendor.img")) + info.script.AppendExtra('ui_print("Patching vendor image unconditionally...");') + info.script.AppendExtra('package_extract_file("firmware-update/vendor.img", "/dev/block/platform/11120000.ufs/by-name/VENDOR");') + + if not skip_firmware: + CopyFirmware(info.input_zip, info.output_zip) + AddFirmwareUpdate(info, filemap) + +def CopyFirmware(input_zip, output_zip): + for info in input_zip.infolist(): + f = info.filename + # Copy files in 'RADIO' to output zip 'firmware-update' + if f.startswith("RADIO/") and (f.__len__() > len("RADIO/")): + fn = f[6:] + common.ZipWriteStr(output_zip, "firmware-update/" + fn, input_zip.read(f)) + +def AddBlModelAssertion(info): + info.script.AppendExtra('ifelse(universal9810.verify_bootloader_model() == "1",') + info.script.AppendExtra('ui_print("=============================================");'); + info.script.AppendExtra('ui_print("=============================================");'); + info.script.AppendExtra('ui_print(" ERROR: ");'); + info.script.AppendExtra('ui_print(" Package contains firmware! ");'); + info.script.AppendExtra('ui_print(" Only F Model is supported! ");'); + info.script.AppendExtra('ui_print(" Cross flashing will brick! ");'); + info.script.AppendExtra('ui_print("=============================================");'); + info.script.AppendExtra('ui_print("============NO CHANGE HAS BEEN MADE==========");'); + info.script.AppendExtra('abort(" ");') + info.script.AppendExtra(');') + +def AddVendorAssertion(info): + info.script.AppendExtra('ifelse(is_mounted("/vendor"), unmount("/vendor"));'); + info.script.AppendExtra('mount("ext4", "EMMC", "/dev/block/platform/11120000.ufs/by-name/VENDOR", "/vendor");'); + info.script.AppendExtra('ifelse(file_getprop("/vendor/build.prop","ro.vendor.build.version.sdk") != "29",'); + info.script.AppendExtra('unmount("/vendor");'); + info.script.AppendExtra('ui_print(" ");'); + info.script.AppendExtra('ui_print("=============================================");'); + info.script.AppendExtra('ui_print("=============================================");'); + info.script.AppendExtra('ui_print(" ERROR: ");'); + info.script.AppendExtra('ui_print(" Vendor image on the device ");'); + info.script.AppendExtra('ui_print(" is NOT compatible ");'); + info.script.AppendExtra('ui_print(" Expected Android 10 vendor ");'); + info.script.AppendExtra('ui_print("=============================================");'); + info.script.AppendExtra('ui_print("============NO CHANGE HAS BEEN MADE==========");'); + info.script.AppendExtra('abort(" ");'); + info.script.AppendExtra(');'); + info.script.AppendExtra('unmount("/vendor");'); + +def AddFirmwareUpdate(info, filemap): + android_info = info.input_zip.read("OTA/android-info.txt").decode('utf-8') + b = re.search(r'require\s+version-bootloader-min\s*=\s*(\S+)', android_info) + if b: + version_bootloader = b.group(1).rstrip() + if ((len(version_bootloader) and '*' not in version_bootloader)): + info.script.AppendExtra('ifelse(universal9810.verify_bootloader_min("' + version_bootloader + '") != "1",') + info.script.AppendExtra('(') + info.script.AppendExtra('ui_print("Upgrading firmware to SW REV. ' + version_bootloader + '");') + for file in filemap: + filename = file.split(" ")[0] + filepath = file.split(" ")[-1] + info.script.AppendExtra('package_extract_file("firmware-update/' + filename + '", "' + filepath + '");') + info.script.AppendExtra('run_program("/sbin/reboot","fota_bl");') + info.script.AppendExtra('),') + info.script.AppendExtra('(') + info.script.AppendExtra('ui_print("Firmware is up-to-date");') + info.script.AppendExtra(')') + info.script.AppendExtra(');') -- GitLab