diff --git a/include/dts-environment.sh b/include/dts-environment.sh index efd653c..1ed632d 100644 --- a/include/dts-environment.sh +++ b/include/dts-environment.sh @@ -122,6 +122,16 @@ declare EC_LINK_COMM declare EC_HASH_LINK_COMM declare EC_SIGN_LINK_COMM declare HEADS_LINK_DPP +# Links to capsules: +declare BIOS_LINK_COMM_CAP +declare BIOS_HASH_LINK_COMM_CAP +declare BIOS_SIGN_LINK_COMM_CAP +declare BIOS_LINK_DPP_CAP +declare BIOS_HASH_LINK_DPP_CAP +declare BIOS_SIGN_LINK_DPP_CAP +declare EC_LINK_COMM_CAP +declare EC_HASH_LINK_COMM_CAP +declare EC_SIGN_LINK_COMM_CAP # Configs, are used in dasharo-deploy script: CAN_INSTALL_BIOS="false" HAVE_HEADS_FW="false" diff --git a/include/dts-functions.sh b/include/dts-functions.sh index 4052870..16aba3c 100644 --- a/include/dts-functions.sh +++ b/include/dts-functions.sh @@ -626,6 +626,7 @@ board_config() { DASHARO_REL_VER="q35/v0.2.0" # TODO: wait till the binaries will be uploaded to the server. BIOS_LINK_COMM="${FW_STORE_URL}/${DASHARO_REL_NAME}/${DASHARO_REL_VER}/" + BIOS_LINK_COMM_CAP="${FW_STORE_URL}/${DASHARO_REL_NAME}/${DASHARO_REL_VER}/" ;; *) print_error "Board model $BOARD_MODEL is currently not supported" @@ -654,6 +655,14 @@ board_config() { [ -z "$BIOS_SIGN_LINK_DPP_SEABIOS" ] && BIOS_SIGN_LINK_DPP_SEABIOS="${BIOS_HASH_LINK_DPP_SEABIOS}.sig" [ -z "$EC_HASH_LINK_COMM" ] && EC_HASH_LINK_COMM="${EC_LINK_COMM}.sha256" [ -z "$EC_SIGN_LINK_COMM" ] && EC_SIGN_LINK_COMM="${EC_HASH_LINK_COMM}.sig" + + # And for capsules as well: + [ -z "$BIOS_HASH_LINK_COMM_CAP" ] && BIOS_HASH_LINK_COMM_CAP="${BIOS_LINK_COMM_CAP}.sha256" + [ -z "$BIOS_SIGN_LINK_COMM_CAP" ] && BIOS_SIGN_LINK_COMM_CAP="${BIOS_SIGN_LINK_COMM_CAP}.sig" + [ -z "$BIOS_HASH_LINK_DPP_CAP" ] && BIOS_HASH_LINK_DPP_CAP="${BIOS_LINK_DPP_CAP}.sha256" + [ -z "$BIOS_SIGN_LINK_DPP_CAP" ] && BIOS_SIGN_LINK_DPP_CAP="${BIOS_HASH_LINK_DPP_CAP}.sig" + [ -z "$EC_HASH_LINK_COMM_CAP" ] && EC_HASH_LINK_COMM_CAP="${EC_LINK_COMM_CAP}.sha256" + [ -z "$EC_SIGN_LINK_COMM_CAP" ] && EC_SIGN_LINK_COMM_CAP="${EC_HASH_LINK_COMM_CAP}.sig" } check_flash_lock() { @@ -812,6 +821,13 @@ get_signing_keys() { } verify_artifacts() { +# This function checks downloaded files, the files that are being downloaded +# should have hashes provided on the server too. The hashes will ben downloaded +# and the binaries will be verified upon them. +# +# In case of .rom files it will be enough but capsules have additional +# protection layer built in, the binaries they provide will be verified by +# drivers, so no need to implement it here. local _type="$1" local _update_file="" local _hash_file="" @@ -819,33 +835,41 @@ verify_artifacts() { local _name="" local _sig_result="" - case ${_type} in - ec) - _update_file=$EC_UPDATE_FILE - _hash_file=$EC_HASH_FILE - _sign_file=$EC_SIGN_FILE - _name="Dasharo EC" - ;; - bios) - _update_file=$BIOS_UPDATE_FILE - _hash_file=$BIOS_HASH_FILE - _sign_file=$BIOS_SIGN_FILE - _name="Dasharo" - ;; - *) - ;; - esac - echo -n "Checking $_name firmware checksum... " - sha256sum --check <(echo "$(cat $_hash_file | cut -d ' ' -f 1)" $_update_file) >> $ERR_LOG_FILE 2>&1 - error_check "Failed to verify $_name firmware checksum" - print_ok "Verified." - if [ -n "$PLATFORM_SIGN_KEY" ]; then - echo -n "Checking $_name firmware signature... " - _sig_result="$(cat $_hash_file | gpg --verify $_sign_file - >> $ERR_LOG_FILE 2>&1)" - error_check "Failed to verify $_name firmware signature.$'\n'$_sig_result" + while [[ $# -gt 0 ]]; do + case ${_type} in + ec) + _update_file=$EC_UPDATE_FILE + _hash_file=$EC_HASH_FILE + _sign_file=$EC_SIGN_FILE + _name="Dasharo EC" + shift + ;; + bios) + _update_file=$BIOS_UPDATE_FILE + _hash_file=$BIOS_HASH_FILE + _sign_file=$BIOS_SIGN_FILE + _name="Dasharo" + shift + ;; + *) + ;; + esac + + echo -n "Checking $_name firmware checksum... " + sha256sum --check <(echo "$(cat $_hash_file | cut -d ' ' -f 1)" $_update_file) >> $ERR_LOG_FILE 2>&1 + error_check "Failed to verify $_name firmware checksum" print_ok "Verified." - fi - echo "$_sig_result" + + if [ -n "$PLATFORM_SIGN_KEY" ]; then + echo -n "Checking $_name firmware signature... " + _sig_result="$(cat $_hash_file | gpg --verify $_sign_file - >> $ERR_LOG_FILE 2>&1)" + error_check "Failed to verify $_name firmware signature.$'\n'$_sig_result" + print_ok "Verified." + fi + echo "$_sig_result" + done + + return 0 } check_intel_regions() { diff --git a/scripts/dasharo-deploy b/scripts/dasharo-deploy index eb4daa7..fd25667 100755 --- a/scripts/dasharo-deploy +++ b/scripts/dasharo-deploy @@ -12,82 +12,165 @@ source $DTS_FUNCS [ -z "$SYSTEM_VENDOR" ] && error_exit "SYSTEM_VENDOR not given" [ -z "$SYSTEM_MODEL" ] && error_exit "SYSTEM_MODEL not given" +# Variables used in this script: +declare UPDATE_TYPE +# Currently following firmware versions are available: community, community_cap, +# dpp, dpp_cap, seabios, and heads: +declare FIRMWARE_VERSION +declare CREDS_VALID CMD="$1" FUM="$2" +check_for_firmware_access() { +# DPP credentials are being provided outside of this script, this script only +# has to check whether the credentials give access to appropriate firmware. The +# appropriate firmware are defined by FIRMWARE_VERSION variable. + + local _firm_ver_to_check + _firm_ver_to_check=$1 + + case ${_firm_ver_to_check} in + community) + # Always available. + ;; + community_cap) + # Always available. + ;; + dpp) + # This firmware type require user to provide creds: + [ "$DPP_IS_LOGGED" == "true" ] || return 1 + + curl -sfI -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$BIOS_LINK_DPP" -o /dev/null + + [ $? -ne 0 ] && return 1 + ;; + dpp_cap) + # This firmware type require user to provide creds: + [ "$DPP_IS_LOGGED" == "true" ] || return 1 + + curl -sfI -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$BIOS_LINK_DPP_CAP" -o /dev/null + + [ $? -ne 0 ] && return 1 + ;; + seabios) + # This firmware type require user to provide creds: + [ "$DPP_IS_LOGGED" == "true" ] || return 1 + + curl -sfI -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$BIOS_LINK_DPP_SEABIOS" -o /dev/null + + [ $? -ne 0 ] && return 1 + ;; + heads) + # This firmware type require user to provide creds: + [ "$DPP_IS_LOGGED" == "true" ] || return 1 + + curl -sfI -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$HEADS_LINK_DPP" -o /dev/null + + [ $? -ne 0 ] && return 1 + ;; + esac + + return 0 +} + ask_for_version() { +# Available firmware versions are defined by FIRMWARE_VERSION variable. + local _option + local _might_be_comm + local _might_be_comm_cap + local _might_be_dpp + local _might_be_dpp_cap + local _might_be_seabios + local _might_be_heads + while : ; do echo - echo "Please, select Dasharo firmware version to install" + echo "Please, select Dasharo firmware version to install:" - # -v: True if the shell variable varname is set (has been assigned a value). if [ -n "$BIOS_LINK_COMM" ]; then - echo " c) Community version" + if check_for_firmware_access community; then + echo " c) Community version" + _might_be_comm="true" + fi fi + + if [ -n "$BIOS_LINK_COMM_CAP" ]; then + if check_for_firmware_access community_cap; then + echo " v) Community version using UEFI Capsule Update" + _might_be_comm_cap="true" + fi + fi + if [ -n "$BIOS_LINK_DPP" ]; then - if [ -n "$DPP_IS_LOGGED" ]; then + if check_for_firmware_access dpp; then echo " d) DPP version (coreboot + UEFI)" + _might_be_dpp="true" else echo " DPP version (coreboot + UEFI) available, if you are interested, please visit https://shop.3mdeb.com/product-category/dasharo-entry-subscription/" fi fi + + if [ -n "$BIOS_LINK_DPP_CAP" ]; then + if check_for_firmware_access dpp; then + echo " f) DPP version (coreboot + UEFI) using UEFI Capsule Update" + _might_be_dpp="true" + else + echo " DPP version (coreboot + UEFI) using UEFI Capsule Update available, if you" + echo " are interested, please visit https://shop.3mdeb.com/product-category/dasharo-entry-subscription/" + fi + fi + if [ -n "$BIOS_LINK_DPP_SEABIOS" ]; then - if [ -n "$DPP_IS_LOGGED" ]; then + if check_for_firmware_access seabios; then echo " s) DPP version (coreboot + SeaBIOS)" + _might_be_seabios="true" else echo " DPP version (coreboot + SeaBIOS) available, if you are interested, please visit https://shop.3mdeb.com/product-category/dasharo-entry-subscription/" fi fi + echo " b) Back to main menu" echo - read -r -p "Enter an option: " OPTION + read -r -p "Enter an option: " _option echo - case ${OPTION} in + case ${_option} in c|C|comm|community|COMMUNITY|COMM|Community) - if [ -n "$BIOS_LINK_COMM" ]; then - BIOS_LINK=$BIOS_LINK_COMM - BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM - BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM - if [ -n "$EC_LINK_COMM" ]; then - EC_LINK=$EC_LINK_COMM - EC_HASH_LINK=$EC_HASH_LINK_COMM - EC_SIGN_LINK=$EC_SIGN_LINK_COMM - fi - echo "Community version selected" - break - else - error_exit "Bad option or resignation. Returning to main menu..." - fi - ;; + if [ -n "$_might_be_comm" ]; then + FIRMWARE_VERSION="community" + break + fi + ;; + v|V) + if [ -n "$_might_be_comm_cap" ]; then + FIRMWARE_VERSION="community_cap" + break + fi + ;; d|D|dpp|DPP|Dpp) - if [ -n "$BIOS_LINK_DPP" ]; then - BIOS_LINK=$BIOS_LINK_DPP - BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP - BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP - if [ -n "$EC_LINK_DPP" ]; then - EC_LINK=$EC_LINK_DPP - EC_HASH_LINK=$EC_HASH_LINK_DPP - # shellcheck disable=SC2034 - EC_SIGN_LINK=$EC_SIGN_LINK_DPP - fi - echo "Dasharo Entry Subscription (coreboot + edk2) version selected" - break - else - error_exit "Bad option. Returning to main menu..." - fi - ;; + if [ -n "$_might_be_dpp" ]; then + FIRMWARE_VERSION="dpp" + break + fi + ;; + f|F) + if [ -n "$_might_be_dpp_cap" ]; then + FIRMWARE_VERSION="dpp_cap" + break + fi + ;; s|S|sea|seabios|SeaBIOS) - if [ -n "$BIOS_LINK_DPP_SEABIOS" ]; then - BIOS_LINK=$BIOS_LINK_DPP_SEABIOS - BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP_SEABIOS - BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP_SEABIOS - echo "Dasharo Entry Subscription (coreboot + SeaBIOS) version selected" - break - else - error_exit "Bad option. Returning to main menu..." - fi - ;; + if [ -n "$_might_be_seabios" ]; then + FIRMWARE_VERSION="seabios" + break + fi + ;; + h|H|heads|Heads|HEADS) + if [ -n "$_might_be_heads" ]; then + FIRMWARE_VERSION="heads" + break + fi + ;; b|B) echo "Returning to main menu..." exit 0 @@ -96,6 +179,245 @@ ask_for_version() { ;; esac done + + return 0 +} + +ask_for_upd_type(){ +# Available update types: +# * from binary using flashrom; +# * from UEFI capsule. + local _option + local _might_be_flashrom + local _might_be_capsule + + while : ; do + if [ -n "$BIOS_LINK_COMM" ] || [ -n "$BIOS_LINK_DPP" ] || [ -n "$BIOS_LINK_DPP_SEABIOS" ] || [ -n "$EC_LINK_COMM" ] || [ -n "$HEADS_LINK_DPP" ]; then + echo -e "f) Update using binary and flashrom" + _might_be_flashrom="true" + fi + + if [ -n "$BIOS_LINK_COMM_CAP" ] || [ -n "$BIOS_LINK_DPP_CAP" ] || [ -n "$BIOS_LINK_DPP_SEABIOS_CAP" ] || [ -n "$EC_LINK_COMM_CAP" ] || [ -n "$HEADS_LINK_DPP_CAP" ]; then + echo -e "u) Update using UEFI capsules" + _might_be_capsule="true" + fi + + echo + read -r -p "Enter an option: " OPTION + echo + + case ${_option} in + f|F) + if [ -n "$_might_be_flashrom" ]; then + UPDATE_TYPE="capsule" + break + fi + ;; + u|U) + if [ -n "$_might_be_capsule" ]; then + UPDATE_TYPE="flashrom" + break + fi + ;; + *) + ;; + esac + done + + return 0 +} + +prepare_env() { +# This function sets all needed variables after user have answered all needed +# questions and before script does any work. This includes: + + # These are key variables for this function: + if [ -z "$FIRMWARE_VERSION" ]; then + return 1 + elif [ "$_prepare_for" == "update" ] && [ -z "$UPDATE_TYPE" ]; then #TODO: + return 1 + fi + + # When board_config returns, we have a set of *_LINK_* variables holding links + # to artifacts for our board. Now we need to deside which links to use (some + # platforms may support several firmware types): + if [ "$FIRMWARE_VERSION" == "community" ]; then + print_ok "Community version selected" + + # If UPDATE_TYPE is not set - we are installing firmware, so use flashrom + # mode because capsules are only for updates. But it is also possible to use + # flashrom mode for updates: + if [ -z "$UPDATE_TYPE" ] || [ "$UPDATE_TYPE" == "flashrom" ]; then + BIOS_LINK=$BIOS_LINK_COMM + BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -v EC_LINK_COMM ]; then + EC_LINK=$EC_LINK_COMM + EC_HASH_LINK=$EC_HASH_LINK_COMM + EC_SIGN_LINK=$EC_SIGN_LINK_COMM + fi + elif [ "$UPDATE_TYPE" == "capsule" ]; then + BIOS_LINK=$BIOS_LINK_COMM_CAP + BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM_CAP + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM_CAP + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -v EC_LINK_COMM ]; then + EC_LINK=$EC_LINK_COMM_CAP + EC_HASH_LINK=$EC_HASH_LINK_COMM_CAP + EC_SIGN_LINK=$EC_SIGN_LINK_COMM_CAP + fi + fi + elif [ "$FIRMWARE_VERSION" == "dpp" ] + print_ok "Subscription version (cooreboot + EDK2) selected" + + # If UPDATE_TYPE is not set - we are installing firmware, so use flashrom + # mode because capsules are only for updates. But it is also possible to use + # flashrom mode for updates: + if [ -z "$UPDATE_TYPE" ] || [ "$UPDATE_TYPE" == "flashrom" ]; then + BIOS_LINK=$BIOS_LINK_DPP + BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -v EC_LINK_DPP ]; then + EC_LINK=$EC_LINK_DPP + EC_HASH_LINK=$EC_HASH_LINK_DPP + EC_SIGN_LINK=$EC_SIGN_LINK_DPP + fi + elif [ "$UPDATE_TYPE" == "capsule" ]; then + BIOS_LINK=$BIOS_LINK_DPP_CAP + BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP_CAP + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP_CAP + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -v EC_LINK_DPP ]; then + EC_LINK=$EC_LINK_DPP_CAP + EC_HASH_LINK=$EC_HASH_LINK_DPP_CAP + EC_SIGN_LINK=$EC_SIGN_LINK_DPP_CAP + fi + fi + elif [ "$FIRMWARE_VERSION" == "seabios" ]; then + print_ok "Subscription version (coreboot + SeaBIOS) selected" + + # If UPDATE_TYPE is not set - we are installing firmware, so use flashrom + # mode because capsules are only for updates. But it is also possible to use + # flashrom mode for updates: + if [ -z "$UPDATE_TYPE" ] || [ "$UPDATE_TYPE" == "flashrom" ]; then + BIOS_LINK=$BIOS_LINK_DPP_SEABIOS + BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP_SEABIOS + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP_SEABIOS + fi + fi + + if [ -v DPP_IS_LOGGED ]; then + if [ -v DASHARO_REL_VER_DPP ]; then + if [ "$DASHARO_FLAVOR" != "Dasharo (coreboot+heads)" ]; then + echo "Latest available Dasharo version: $DASHARO_REL_VER_DPP" + fi + + + + if [ $? -ne 0 ]; then + echo "Current DPP credentials do not match the current platform/firmware flavor." + echo "Latest possible and available update is $DASHARO_REL_VER" + BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM + BIOS_LINK=$BIOS_LINK_COMM + + if [ "$HAVE_EC" == "true" ]; then + EC_HASH_LINK=$EC_HASH_LINK_COMM + EC_SIGN_LINK=$EC_SIGN_LINK_COMM + EC_LINK=$EC_LINK_COMM + fi + + UPDATE_VERSION=$DASHARO_REL_VER + else + BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP + BIOS_LINK=$BIOS_LINK_DPP + + if [ "$HAVE_EC" == "true" ]; then + EC_HASH_LINK=$EC_HASH_LINK_DPP + EC_SIGN_LINK=$EC_SIGN_LINK_DPP + EC_LINK=$EC_LINK_DPP + fi + + UPDATE_VERSION=$DASHARO_REL_VER_DPP + fi + else + if [ "$DASHARO_FLAVOR" != "Dasharo (coreboot+heads)" ]; then + echo "Latest available Dasharo version: $DASHARO_REL_VER" + fi + + BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM + BIOS_LINK=$BIOS_LINK_COMM + + if [ "$HAVE_EC" == "true" ]; then + EC_HASH_LINK=$EC_HASH_LINK_COMM + EC_SIGN_LINK=$EC_SIGN_LINK_COMM + EC_LINK=$EC_LINK_COMM + fi + + UPDATE_VERSION=$DASHARO_REL_VER + fi + + if [ -v HAVE_HEADS_FW ] && [ "$DASHARO_FLAVOR" != "Dasharo (coreboot+heads)" ]; then + # Check if given DPP credentials give access to heads, if not, + # then it means DPP is for regular releases + + + if [ $? -ne 0 ]; then + print_warning "Dasharo Heads firmware version is available, but your" + print_warning "subscription does not give you the access to this firmware." + print_warning "If you are interested, please visit https://shop.3mdeb.com/product-category/dasharo-entry-subscription/" + else + # Access to the heads FW is possible, allow to switch to heads + _can_switch_to_heads="true" + print_ok "Dasharo Heads firmware version is available and your subscription" + print_ok "gives you access to this firmware." + fi + elif [ -v HAVE_HEADS_FW ] && [ "$DASHARO_FLAVOR" == "Dasharo (coreboot+heads)" ]; then + # Set the switch flag to offer switch back + echo "Latest available Dasharo version: $HEADS_REL_VER_DPP" + _can_switch_to_heads="true" + fi + else + if [ -v DASHARO_REL_VER_DPP ]; then + print_green "DPP version (coreboot + UEFI) available, if you are interested" + print_ok "please visit https://shop.3mdeb.com/product-category/dasharo-entry-subscription/" + fi + + if [ "$DASHARO_FLAVOR" != "Dasharo (coreboot+heads)" ]; then + echo "Latest available Dasharo version: $DASHARO_REL_VER" + fi + + BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM + BIOS_LINK=$BIOS_LINK_COMM + + if [ "$HAVE_EC" == "true" ]; then + EC_HASH_LINK=$EC_HASH_LINK_COMM + EC_SIGN_LINK=$EC_SIGN_LINK_COMM + EC_LINK=$EC_LINK_COMM + fi + + UPDATE_VERSION=$DASHARO_REL_VER + + if [ -v HAVE_HEADS_FW ] && [ "$DASHARO_FLAVOR" != "Dasharo (coreboot+heads)" ]; then + print_ok "Dasharo heads firmware version is available. If you are interested," + print_ok "please provide your subscription credentials in the main DTS menu" + print_ok "and select 'Update Dasharo firmware' again to check if you are eligible." + elif [ -v HAVE_HEADS_FW ] && [ "$DASHARO_FLAVOR" == "Dasharo (coreboot+heads)" ]; then + # Set the switch flag to offer switch back + _can_switch_to_heads="true" + fi + fi + + return 0 } display_flashing_warning() { @@ -386,47 +708,51 @@ blob_transmission() { fi } -install_ec() { - verify_artifacts ec - echo "Installing EC..." - $FLASHROM -p "$PROGRAMMER_EC" ${FLASH_CHIP_SELECT} -w "$EC_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE - error_check "Failed to install Dasharo EC firmware" - echo "Successfully installed Dasharo EC firmware" -} +deploy_ec_firmware() { +# This function deploys (installs or updates) downloaded EC firmware either UEFI +# capsules (updates only) and binaries. Parameters: update, install. + local _mode + _mode="$1" -install() { - ask_for_version - if [ "$CAN_INSTALL_BIOS" == "false" ]; then - download_ec - unset BIOS_HASH_LINK - display_flashing_warning - else - download_artifacts - display_flashing_warning - check_flash_lock - verify_artifacts bios - - check_intel_regions - check_blobs_in_binary $BIOS_UPDATE_FILE - check_if_me_disabled - set_intel_regions_update_params "-N --ifd -i bios" - fi - - if [ "$HAVE_EC" == "true" ]; then + if [ "$_mode" == "update" ]; then + if [ "$UPDATE_TYPE" == "capsule" ]; then + echo "Updating EC..." + cat "$EC_UPDATE_FILE" > "$CAP_UPD_DEVICE" + else + # Following command will reset device, so the function will not quit: + $DASHARO_ECTOOL flash "$EC_UPDATE_FILE" &>> $ERR_LOG_FILE + fi + error_check "Failed to update EC firmware" + elif [ "$_mode" == "install" ]; then echo "Checking for Open Source Embedded Controller firmware" $DASHARO_ECTOOL info >> $ERR_LOG_FILE 2>&1 + if [ $? -eq 0 ]; then echo "Device has already Open Source Embedded Controller firmware, do not flash EC..." else _ec_fw_version=$($FLASHROM -p "$PROGRAMMER_EC" ${FLASH_CHIP_SELECT} | grep "Mainboard EC Version" | tr -d ' ' | cut -d ':' -f 2) + if [ "$_ec_fw_version" != "$COMPATIBLE_EC_FW_VERSION" ]; then - print_warning "EC version: $_ec_fw_version is not supported, update required" - install_ec + echo "Installing EC..." + $FLASHROM -p "$PROGRAMMER_EC" ${FLASH_CHIP_SELECT} -w "$EC_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + error_check "Failed to install Dasharo EC firmware" + print_ok "Successfully installed Dasharo EC firmware" fi fi fi - if [ "$CAN_INSTALL_BIOS" == "true" ]; then + return 0 +} + +deploy_firmware(){ +# This function deploys (installs or updates) downloaded firmware either UEFI +# capsules (updates only) and binaries. Parameters: update, install. + local _mode + _mode="$1" + + if [ "$_mode" == "update" ]; then + # Updating... + elif [ "$_mode" == "install" ]; then cbfstool "$BIOS_UPDATE_FILE" extract -r COREBOOT -n config -f "$BIOS_UPDATE_CONFIG_FILE" grep "CONFIG_VBOOT=y" "$BIOS_UPDATE_CONFIG_FILE" HAVE_VBOOT="$?" @@ -457,14 +783,54 @@ install() { fi $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_REGIONS} -w "$BIOS_UPDATE_FILE" ${_flashrom_extra_args} >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE error_check "Failed to install Dasharo firmware" - print_ok "Successfully installed Dasharo firmware" fi + return 0 +} + +install_workflow() { +# Installation workflow. The installation of firmware is possible only via +# flashrom, capsules cannot do the installation because they need initial +# supportinside firmware. + + # Subscription or community versions are available: + ask_for_version + prepare_env + + # Download, verify and do some checks: + if [ "$CAN_INSTALL_BIOS" == "false" && "$HAVE_EC" == "true" ]; then + unset BIOS_HASH_LINK + + download_ec + verify_artifacts ec + display_flashing_warning + else + download_artifacts + verify_artifacts ec bios + display_flashing_warning + check_flash_lock + check_intel_regions + check_blobs_in_binary $BIOS_UPDATE_FILE + check_if_me_disabled + set_intel_regions_update_params "-N --ifd -i bios" + fi + + # Deploy EC firmware + if [ "$HAVE_EC" == "true" ]; then + deploy_ec_firmware install + fi + + # Deploy BIOS firmware + if [ "$CAN_INSTALL_BIOS" == "true" ]; then + deploy_firmware install + fi + + # Post installation routine: echo -n "Syncing disks... " sync echo "Done." - if [ "$NEED_EC_RESET" = "true" ]; then + if [ "$NEED_EC_RESET" == "true" ]; then echo "The computer will shut down automatically in 5 seconds" else echo "The computer will reboot automatically in 5 seconds" @@ -483,28 +849,25 @@ install() { sleep 0.5 echo "Rebooting" sleep 1 - if [ "$NEED_EC_RESET" = "true" ]; then + if [ "$NEED_EC_RESET" == "true" ]; then it5570_shutdown else ${CMD_REBOOT} fi } -update_ec() { - verify_artifacts ec - echo "Updating EC..." - $DASHARO_ECTOOL flash "$EC_UPDATE_FILE" &>> $ERR_LOG_FILE - error_check "Failed to update EC firmware" -} - -update() { +update_workflow() { local _can_switch_to_heads="false" sync_clocks + + # Verify the the device is not using battery as a power source: check_if_ac error_check "Firmware update process interrupted on user request." - echo "Checking for the latest Dasharo update available..." + ask_for_upd_type + prepare_env + echo "Current Dasharo version: $DASHARO_VERSION" if [ -n "$DPP_IS_LOGGED" ]; then if [ -n "$DASHARO_REL_VER_DPP" ]; then @@ -612,7 +975,6 @@ update() { echo "That version does not support gen 13 and above CPU. Therefore we cannot continue with flashing." error_exit "Aborting update process..." fi - fi while : ; do @@ -733,9 +1095,10 @@ update() { print_ok "Successfully updated Dasharo firmware." fi + # Post update routine: if [ "$HAVE_EC" == "true" ]; then echo "Updating Embedded Controller firmware. Your computer will power off automatically when done." - update_ec # Ends in a reset, does not exit + deploy_ec_firmware update # Ends in a reset, does not exit. else echo -n "Syncing disks... " sync @@ -900,7 +1263,7 @@ case "$CMD" in initial deployment of Dasharo Firmware. Aborting..." fi backup - install + install_workflow ;; update) if [ "$FUM" == "fum" ]; then