diff --git a/Makefile b/Makefile index d0036d3c..c11148ab 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,8 @@ install: install -m 0755 include/dts-environment.sh $(DESTDIR)$(SBINDIR) install -m 0755 include/dts-functions.sh $(DESTDIR)$(SBINDIR) install -m 0755 include/dts-subscription.sh $(DESTDIR)$(SBINDIR) + install -m 0755 include/hal/dts-hal.sh $(DESTDIR)$(SBINDIR) + install -m 0755 include/hal/common-mock-func.sh $(DESTDIR)$(SBINDIR) install -m 0755 scripts/cloud_list $(DESTDIR)$(SBINDIR) install -m 0755 scripts/dasharo-deploy $(DESTDIR)$(SBINDIR) diff --git a/include/dts-environment.sh b/include/dts-environment.sh index a94c6dfd..01ebf76f 100644 --- a/include/dts-environment.sh +++ b/include/dts-environment.sh @@ -5,6 +5,10 @@ # SPDX-License-Identifier: Apache-2.0 # shellcheck disable=SC2034 +# shellcheck source=../include/hal/dts-hal.sh +source $DTS_HAL +# shellcheck source=../include/dts-functions.sh +source $DTS_FUNCS # Text colors: NORMAL='\033[0m' @@ -13,15 +17,22 @@ YELLOW='\033[0;33m' GREEN='\033[0;32m' BLUE='\033[0;36m' -# DPP options: +# DPP variables: DPP_SERVER_ADDRESS="https://dl.dasharo.com" DPP_SERVER_USER_ALIAS="premium" DPP_PACKAGE_MANAGER_DIR="/var/dasharo-package-manager" DPP_AVAIL_PACKAGES_LIST="$DPP_PACKAGE_MANAGER_DIR/packages-list.json" DPP_PACKAGES_SCRIPTS_PATH="$DPP_PACKAGE_MANAGER_DIR/packages-scripts" DPP_SUBMENU_JSON="$DPP_PACKAGES_SCRIPTS_PATH/submenu.json" +DPP_CREDENTIAL_FILE="/etc/cloud-pass" +FW_STORE_URL="${FW_STORE_URL_DEV:-https://dl.3mdeb.com/open-source-firmware/Dasharo}" +FW_STORE_URL_DPP="https://cloud.3mdeb.com/public.php/webdav" +CLOUD_REQUEST="X-Requested-With: XMLHttpRequest" +BASE_CLOUDSEND_LOGS_URL="39d4biH4SkXD8Zm" +BASE_CLOUDSEND_PASSWORD="1{\[\k6G" +DEPLOY_REPORT="false" -# DTS options: +# DTS menu options: HCL_REPORT_OPT="1" DASHARO_FIRM_OPT="2" REST_FIRM_OPT="3" @@ -42,20 +53,24 @@ SEND_LOGS_OPT_LOW="$(echo $SEND_LOGS_OPT | awk '{print tolower($0)}')" VERBOSE_OPT="V" VERBOSE_OPT_LOW="$(echo $VERBOSE_OPT | awk '{print tolower($0)}')" -SYSTEM_VENDOR="${SYSTEM_VENDOR:-$(dmidecode -s system-manufacturer)}" -SYSTEM_MODEL="${SYSTEM_MODEL:-$(dmidecode -s system-product-name)}" -BOARD_VENDOR="${BOARD_VENDOR:-$(dmidecode -s system-manufacturer)}" -BOARD_MODEL="${BOARD_MODEL:-$(dmidecode -s baseboard-product-name)}" +# Hardware variables: +SYSTEM_VENDOR="$($DMIDECODE dump_var_mock -s system-manufacturer)" +SYSTEM_MODEL="$($DMIDECODE dump_var_mock -s system-product-name)" +BOARD_MODEL="$($DMIDECODE dump_var_mock -s baseboard-product-name)" +CPU_VERSION="$($DMIDECODE dump_var_mock -s processor-version)" -CPU_VERSION="$(dmidecode -s processor-version)" -BIOS_VENDOR="${BIOS_VENDOR:-$(dmidecode -s bios-vendor)}" -BIOS_VERSION="${BIOS_VERSION:-$(dmidecode -s bios-version)}" +# Firmware variables +BIOS_VENDOR="$($DMIDECODE dump_var_mock -s bios-vendor)" +BIOS_VERSION="$($DMIDECODE dump_var_mock -s bios-version)" DASHARO_VERSION="$(echo $BIOS_VERSION | cut -d ' ' -f 3 | tr -d 'v')" DASHARO_FLAVOR="$(echo $BIOS_VERSION | cut -d ' ' -f 1,2)" -# path to temporary files, created while deploying or updating Dasharo firmware -BIOS_UPDATE_FILE="/tmp/biosupdate.rom" -EC_UPDATE_FILE="/tmp/ecupdate.rom" +# Paths to temporary files, created while deploying or updating Dasharo +# firmware, are used globally for both: updating via binaries and via UEFI +# Capsule Update. +BIOS_UPDATE_FILE="/tmp/biosupdate" +BIOS_DUMP_FILE="/tmp/bios.bin" +EC_UPDATE_FILE="/tmp/ecupdate" BIOS_HASH_FILE="/tmp/bioshash.sha256" EC_HASH_FILE="/tmp/echash.sha256" BIOS_SIGN_FILE="/tmp/biossignature.sig" @@ -65,10 +80,6 @@ RESIGNED_BIOS_UPDATE_FILE="/tmp/biosupdate_resigned.rom" SYSTEM_UUID_FILE="/tmp/system_uuid.txt" SERIAL_NUMBER_FILE="/tmp/serial_number.txt" -# default value for flash chip related information -FLASH_CHIP_SELECT="" -FLASH_CHIP_SIZE="" - # dasharo-deploy backup cmd related variables, do we still use and need this as # backup is placed in HCL? ROOT_DIR="/" @@ -77,50 +88,104 @@ FW_BACKUP_DIR="${ROOT_DIR}${FW_BACKUP_NAME}" FW_BACKUP_TAR="${FW_BACKUP_DIR}.tar.gz" FW_BACKUP_TAR="$(echo "$FW_BACKUP_TAR" | sed 's/\ /_/g')" -# path to system files +# Paths to system files ERR_LOG_FILE="/var/local/dts-err.log" FLASHROM_LOG_FILE="/var/local/flashrom.log" FLASH_INFO_FILE="/tmp/flash_info" OS_VERSION_FILE="/etc/os-release" KEYS_DIR="/tmp/devkeys" -# path to system commands -CMD_POWEROFF="/sbin/poweroff" -CMD_REBOOT="/sbin/reboot" -CMD_SHELL="/bin/bash" +# Paths to system commands: +CMD_SHELL="bash" + +# Paths to DTS commands: CMD_DASHARO_HCL_REPORT="/usr/sbin/dasharo-hcl-report" CMD_NCMENU="/usr/sbin/novacustom_menu" CMD_DASHARO_DEPLOY="/usr/sbin/dasharo-deploy" CMD_CLOUD_LIST="/usr/sbin/cloud_list" CMD_EC_TRANSITION="/usr/sbin/ec_transition" -# default values for flashrom programmer -FLASHROM="${FLASHROM:-flashrom}" +# Configuration variables declaration and default values (see dts-functions.sh/ +# board_config function for more inf.): +# Versions and names: +declare DASHARO_REL_NAME +declare DASHARO_REL_VER +declare DASHARO_REL_VER_DPP +declare DASHARO_REL_VER_DPP_CAP +declare HEADS_REL_VER_DPP +declare DASHARO_REL_VER_DPP_SEABIOS +declare COMPATIBLE_EC_FW_VERSION +# and for capsules: +declare DASHARO_REL_VER_CAP +declare DASHARO_REL_VER_DPP_CAP +# To use capsule update a platform should already run a firmware with capsule +# update support. Therefore DTS should check, from which Dasharo firmware +# version capsule update is supported for the platform and compare with the +# version of the currently installed firmware. This variable holds the version +# from which Dasharo firmware supports capsule update for current patform. It is +# set in board_config: +declare DASHARO_SUPPORT_CAP_FROM +# Links to files: +declare BIOS_LINK_COMM +declare BIOS_HASH_LINK_COMM +declare BIOS_SIGN_LINK_COMM +declare BIOS_LINK_DPP +declare BIOS_HASH_LINK_DPP +declare BIOS_SIGN_LINK_DPP +declare BIOS_LINK_DPP_SEABIOS +declare BIOS_HASH_LINK_DPP_SEABIOS +declare BIOS_SIGN_LINK_DPP_SEABIOS +declare EC_LINK_COMM +declare EC_HASH_LINK_COMM +declare EC_SIGN_LINK_COMM +declare EC_LINK_DPP +declare EC_HASH_LINK_DPP +declare EC_SIGN_LINK_DPP +declare HEADS_LINK_DPP +declare HEADS_HASH_LINK_DPP +declare HEADS_SIGN_LINK_DPP +# and for 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" +HAVE_EC="false" +NEED_EC_RESET="false" +NEED_SMBIOS_MIGRATION="false" +NEED_SMMSTORE_MIGRATION="false" +NEED_BOOTSPLASH_MIGRATION="false" +NEED_BLOB_TRANSMISSION="false" +NEED_ROMHOLE_MIGRATION="false" +# Default flashrom parameters, may differ depending on a platform: PROGRAMMER_BIOS="internal" -PROGRAMMER_EC="ite_ec" - -DASHARO_ECTOOL="${DASHARO_ECTOOL:-dasharo_ectool}" - -# variables defining Dasharo specific entries in DMI tables, used to check if -# Dasharo FW is already installed +PROGRAMMER_EC="ite_ec:boardmismatch=force,romsize=128K,autoload=disable" +declare FLASHROM_ADD_OPT_UPDATE_OVERRIDE +declare HEADS_SWITCH_FLASHROM_OPT_OVERRIDE +# Platform-specific: +declare PLATFORM_SIGN_KEY + +# Other variables: +# Default values for flash chip related information: +declare FLASH_CHIP_SELECT +declare FLASH_CHIP_SIZE +# Default UEFI Capsule Update device: +CAP_UPD_DEVICE="/dev/efi_capsule_loader" +# Variables defining Dasharo specific entries in DMI tables, used to check if +# Dasharo FW is already installed: DASHARO_VENDOR="3mdeb" DASHARO_NAME="Dasharo" - -# most the time one flash chipset will be detected, for other cases (like for -# ASUS KGPE-D16) we will test the following list in check_flash_chip function +# Most the time one flash chipset will be detected, for other cases (like for +# ASUS KGPE-D16) we will test the following list in check_flash_chip function: FLASH_CHIP_LIST="W25Q64BV/W25Q64CV/W25Q64FV W25Q64JV-.Q W25Q128.V..M" -# Dasharo Supporters Entrance variables -DPP_credential_file="/etc/cloud-pass" -FW_STORE_URL="${FW_STORE_URL_DEV:-https://dl.3mdeb.com/open-source-firmware/Dasharo}" -FW_STORE_URL_DPP="https://cloud.3mdeb.com/public.php/webdav" -CLOUD_REQUEST="X-Requested-With: XMLHttpRequest" - -## base values -BASE_CLOUDSEND_LOGS_URL="39d4biH4SkXD8Zm" -BASE_CLOUDSEND_PASSWORD="1{\[\k6G" -DEPLOY_REPORT="false" - BASE_DTS_LOGS_URL="xjBCYbzFdyq3WLt" DTS_LOGS_PASSWORD="/w\J&>8 & 0xff)) + $IOTOOLS io_write8 0x2e 0x2e + $IOTOOLS io_write8 0x2f 0x11 + $IOTOOLS io_write8 0x2e 0x2f + $IOTOOLS io_write8 0x2f $(($2>>8 & 0xff)) # Address low byte - iotools io_write8 0x2e 0x2e - iotools io_write8 0x2f 0x10 - iotools io_write8 0x2e 0x2f - iotools io_write8 0x2f $(($2 & 0xff)) + $IOTOOLS io_write8 0x2e 0x2e + $IOTOOLS io_write8 0x2f 0x10 + $IOTOOLS io_write8 0x2e 0x2f + $IOTOOLS io_write8 0x2f $(($2 & 0xff)) # Data - iotools io_write8 0x2e 0x2e - iotools io_write8 0x2f 0x12 - iotools io_write8 0x2e 0x2f + $IOTOOLS io_write8 0x2e 0x2e + $IOTOOLS io_write8 0x2f 0x12 + $IOTOOLS io_write8 0x2e 0x2f case $1 in "r") - iotools io_read8 0x2f + $IOTOOLS io_read8 0x2f ;; "w") - iotools io_write8 0x2f "$3" + $IOTOOLS io_write8 0x2f "$3" ;; esac } @@ -208,39 +205,43 @@ ask_for_model() { done } -## Supported boards configuration - board_config() { +# This functions checks used platform and configure environment in case the +# platform is supported. The supported platforms are sorted by variables +# SYSTEM_VENDOR, SYSTEM_MODEL, and BOARD_MODEL in switch/case statements. +# +# Every platform uses some standard environment configuration variables +# described in dts-environment.sh file, these could be specified for a specific +# board or vendor or shared between some, some platforms may have their own env. +# var. as well. +# +# All the standard variables are explicitly declared in dts-environment.sh +# script and, if appropriate, set to default values. If a platform has its own +# configuration variables - it must declare them here, even if they are not +# set. This is made with a goal to limit global variables declaration to +# dts-environment.sh and board_config function. + # We download firmwares via network. At this point, the network connection # must be up already. wait_for_network_connection - CAN_INSTALL_BIOS="true" - echo "Checking if board is Dasharo compatible." case "$SYSTEM_VENDOR" in "Notebook") + # Common settings for all Notebooks: + CAN_USE_FLASHROM="true" + HAVE_EC="true" + NEED_EC_RESET="true" + PLATFORM_SIGN_KEY="customer-keys/novacustom/novacustom-open-source-firmware-release-1.x-key.asc \ + customer-keys/novacustom/dasharo-release-0.9.x-for-novacustom-signing-key.asc" + NEED_SMMSTORE_MIGRATION="true" + case "$SYSTEM_MODEL" in "NV4XMB,ME,MZ") DASHARO_REL_NAME="novacustom_nv4x_tgl" DASHARO_REL_VER="1.5.2" - BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}.rom" - EC_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_ec_v${DASHARO_REL_VER}.rom" - HAVE_EC="true" - NEED_EC_RESET="true" + CAN_INSTALL_BIOS="true" COMPATIBLE_EC_FW_VERSION="2022-10-07_c662165" - EC_HASH_LINK_COMM="$EC_LINK_COMM.sha256" - BIOS_HASH_LINK_COMM="$BIOS_LINK_COMM.sha256" - EC_SIGN_LINK_COMM="$EC_LINK_COMM.sha256.sig" - BIOS_SIGN_LINK_COMM="$BIOS_LINK_COMM.sha256.sig" - PLATFORM_SIGN_KEY="customer-keys/novacustom/novacustom-open-source-firmware-release-1.x-key.asc \ - customer-keys/novacustom/dasharo-release-0.9.x-for-novacustom-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="false" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="ite_ec:boardmismatch=force,romsize=128K,autoload=disable" if check_if_dasharo; then # if v1.5.1 or older, flash the whole bios region # TODO: Let DTS determine which parameters are suitable. @@ -258,23 +259,8 @@ board_config() { "NS50_70MU") DASHARO_REL_NAME="novacustom_ns5x_tgl" DASHARO_REL_VER="1.5.2" - BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}.rom" - EC_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_ec_v${DASHARO_REL_VER}.rom" - HAVE_EC="true" - NEED_EC_RESET="true" + CAN_INSTALL_BIOS="true" COMPATIBLE_EC_FW_VERSION="2022-08-31_cbff21b" - EC_HASH_LINK_COMM="$EC_LINK_COMM.sha256" - BIOS_HASH_LINK_COMM="$BIOS_LINK_COMM.sha256" - EC_SIGN_LINK_COMM="$EC_LINK_COMM.sha256.sig" - BIOS_SIGN_LINK_COMM="$BIOS_LINK_COMM.sha256.sig" - PLATFORM_SIGN_KEY="customer-keys/novacustom/novacustom-open-source-firmware-release-1.x-key.asc \ - customer-keys/novacustom/dasharo-release-0.9.x-for-novacustom-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="false" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="ite_ec:boardmismatch=force,romsize=128K,autoload=disable" if check_if_dasharo; then # if v1.5.1 or older, flash the whole bios region # TODO: Let DTS determine which parameters are suitable. @@ -292,22 +278,7 @@ board_config() { "NS5x_NS7xPU") DASHARO_REL_NAME="novacustom_ns5x_adl" DASHARO_REL_VER="1.7.2" - BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}.rom" - EC_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_ec_v${DASHARO_REL_VER}.rom" - HAVE_EC="true" - NEED_EC_RESET="true" COMPATIBLE_EC_FW_VERSION="2022-08-31_cbff21b" - EC_HASH_LINK_COMM="$EC_LINK_COMM.sha256" - BIOS_HASH_LINK_COMM="$BIOS_LINK_COMM.sha256" - EC_SIGN_LINK_COMM="$EC_LINK_COMM.sha256.sig" - BIOS_SIGN_LINK_COMM="$BIOS_LINK_COMM.sha256.sig" - PLATFORM_SIGN_KEY="customer-keys/novacustom/novacustom-open-source-firmware-release-1.x-key.asc \ - customer-keys/novacustom/dasharo-release-0.9.x-for-novacustom-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="ite_ec:boardmismatch=force,romsize=128K,autoload=disable" if check_if_dasharo; then # if v1.7.2 or older, flash the whole bios region # TODO: Let DTS determine which parameters are suitable. @@ -328,23 +299,7 @@ board_config() { HEADS_REL_VER_DPP="0.9.1" HEADS_LINK_DPP="${FW_STORE_URL_DPP}/${DASHARO_REL_NAME}/v${HEADS_REL_VER_DPP}/${DASHARO_REL_NAME}_v${HEADS_REL_VER_DPP}_heads.rom" HEADS_SWITCH_FLASHROM_OPT_OVERRIDE="--ifd -i bios" - BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}.rom" - EC_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_ec_v${DASHARO_REL_VER}.rom" - HAVE_EC="true" - NEED_EC_RESET="true" COMPATIBLE_EC_FW_VERSION="2022-08-31_cbff21b" - EC_HASH_LINK_COMM="$EC_LINK_COMM.sha256" - BIOS_HASH_LINK_COMM="$BIOS_LINK_COMM.sha256" - EC_SIGN_LINK_COMM="$EC_LINK_COMM.sha256.sig" - BIOS_SIGN_LINK_COMM="$BIOS_LINK_COMM.sha256.sig" - PLATFORM_SIGN_KEY="customer-keys/novacustom/novacustom-open-source-firmware-release-1.x-key.asc \ - customer-keys/novacustom/dasharo-release-0.9.x-for-novacustom-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="false" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="ite_ec:boardmismatch=force,romsize=128K,autoload=disable" if check_if_dasharo; then # if v1.7.2 or older, flash the whole bios region # TODO: Let DTS determine which parameters are suitable. @@ -367,57 +322,25 @@ board_config() { "V54x_6x_TU") # Dasharo 0.9.0-rc10 and higher have board model in baseboard-version if check_if_dasharo && compare_versions "$DASHARO_VERSION" 0.9.0-rc10; then - BOARD_MODEL="$(dmidecode -s baseboard-version)" - elif ! dasharo_ectool info 2>/dev/null; then + BOARD_MODEL="$($DMIDECODE dump_var_mock -s baseboard-version)" + elif ! $DASHARO_ECTOOL check_for_opensource_firm_mock info 2>/dev/null; then ask_for_model V540TU V560TU else - BOARD_MODEL=$(dasharo_ectool info | grep "board:" | + BOARD_MODEL=$($DASHARO_ECTOOL novacustom_check_sys_model_mock info | grep "board:" | sed -r 's|.*novacustom/(.*)|\1|' | awk '{print toupper($1)}') fi + + # Common configuration for all V54x_6x_TU: + DASHARO_REL_VER="0.9.0" + COMPATIBLE_EC_FW_VERSION="2024-07-17_4ae73b9" + NEED_BOOTSPLASH_MIGRATION="true" + case $BOARD_MODEL in "V540TU") DASHARO_REL_NAME="novacustom_v54x_mtl" - DASHARO_REL_VER="0.9.0" - BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}.rom" - EC_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_ec_v${DASHARO_REL_VER}.rom" - HAVE_EC="true" - NEED_EC_RESET="true" - COMPATIBLE_EC_FW_VERSION="2024-07-17_4ae73b9" - EC_HASH_LINK_COMM="$EC_LINK_COMM.sha256" - BIOS_HASH_LINK_COMM="$BIOS_LINK_COMM.sha256" - EC_SIGN_LINK_COMM="$EC_LINK_COMM.sha256.sig" - BIOS_SIGN_LINK_COMM="$BIOS_LINK_COMM.sha256.sig" - PLATFORM_SIGN_KEY="customer-keys/novacustom/novacustom-open-source-firmware-release-1.x-key.asc \ - customer-keys/novacustom/dasharo-release-0.9.x-for-novacustom-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="true" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="ite_ec:boardmismatch=force,romsize=128K,autoload=disable" - CAN_INSTALL_BIOS="false" ;; "V560TU") DASHARO_REL_NAME="novacustom_v56x_mtl" - DASHARO_REL_VER="0.9.0" - BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}.rom" - EC_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_ec_v${DASHARO_REL_VER}.rom" - HAVE_EC="true" - NEED_EC_RESET="true" - COMPATIBLE_EC_FW_VERSION="2024-07-17_4ae73b9" - EC_HASH_LINK_COMM="$EC_LINK_COMM.sha256" - BIOS_HASH_LINK_COMM="$BIOS_LINK_COMM.sha256" - EC_SIGN_LINK_COMM="$EC_LINK_COMM.sha256.sig" - BIOS_SIGN_LINK_COMM="$BIOS_LINK_COMM.sha256.sig" - PLATFORM_SIGN_KEY="customer-keys/novacustom/novacustom-open-source-firmware-release-1.x-key.asc \ - customer-keys/novacustom/dasharo-release-0.9.x-for-novacustom-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="true" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="ite_ec:boardmismatch=force,romsize=128K,autoload=disable" - CAN_INSTALL_BIOS="false" ;; *) print_error "Board model $BOARD_MODEL is currently not supported" @@ -427,22 +350,12 @@ board_config() { ;; "V5xTNC_TND_TNE") if check_if_dasharo; then - BOARD_MODEL="$(dmidecode -s baseboard-version)" + BOARD_MODEL="$($DMIDECODE dump_var_mock -s baseboard-version)" else ask_for_model V540TNx V560TNx fi - PLATFORM_SIGN_KEY="customer-keys/novacustom/novacustom-open-source-firmware-release-1.x-key.asc \ - customer-keys/novacustom/dasharo-release-0.9.x-for-novacustom-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" NEED_BOOTSPLASH_MIGRATION="true" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="ite_ec:boardmismatch=force,romsize=128K,autoload=disable" - CAN_INSTALL_BIOS="false" - HAVE_EC="true" - NEED_EC_RESET="true" case $BOARD_MODEL in "V540TNx") @@ -460,101 +373,63 @@ board_config() { return 1 ;; esac - - BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}.rom" - EC_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_ec_v${DASHARO_REL_VER}.rom" - BIOS_HASH_LINK_COMM="$BIOS_LINK_COMM.sha256" - BIOS_SIGN_LINK_COMM="$BIOS_LINK_COMM.sha256.sig" - EC_HASH_LINK_COMM="$EC_LINK_COMM.sha256" - EC_SIGN_LINK_COMM="$EC_LINK_COMM.sha256.sig" ;; *) print_error "Board model $SYSTEM_MODEL is currently not supported" return 1 ;; esac + BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}.rom" + EC_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_ec_v${DASHARO_REL_VER}.rom" ;; "Micro-Star International Co., Ltd.") case "$SYSTEM_MODEL" in "MS-7D25") + # Common configuration for all MS-7D25: + DASHARO_REL_NAME="msi_ms7d25" + DASHARO_REL_VER="1.1.1" + DASHARO_REL_VER_DPP="1.1.4" + CAN_INSTALL_BIOS="true" + HAVE_HEADS_FW="true" + HEADS_REL_VER_DPP="0.9.0" + HEADS_SWITCH_FLASHROM_OPT_OVERRIDE="--ifd -i bios" + PLATFORM_SIGN_KEY="dasharo/msi_ms7d25/dasharo-release-1.x-compatible-with-msi-ms-7d25-signing-key.asc \ + dasharo/msi_ms7d25/dasharo-release-0.x-compatible-with-msi-ms-7d25-signing-key.asc" + NEED_SMBIOS_MIGRATION="true" + NEED_SMMSTORE_MIGRATION="true" + NEED_ROMHOLE_MIGRATION="true" + + # Add capsules: + DASHARO_REL_NAME_CAP="$DASHARO_REL_NAME" + DASHARO_REL_VER_DPP_CAP="$DASHARO_REL_VER_DPP" + DASHARO_SUPPORT_CAP_FROM="1.1.4" + + if check_if_dasharo; then + # if v1.1.3 or older, flash the whole bios region + # TODO: Let DTS determine which parameters are suitable. + # FIXME: Can we ever get rid of that? We change so much in each release, + # that we almost always need to flash whole BIOS region + # because of non-backward compatible or breaking changes. + compare_versions $DASHARO_VERSION 1.1.3 + if [ $? -eq 1 ]; then + # For Dasharo version lesser than 1.1.3 + NEED_BOOTSPLASH_MIGRATION="true" + FLASHROM_ADD_OPT_UPDATE_OVERRIDE="--ifd -i bios" + fi + fi + case "$BOARD_MODEL" in "PRO Z690-A WIFI DDR4(MS-7D25)" | "PRO Z690-A DDR4(MS-7D25)") - DASHARO_REL_NAME="msi_ms7d25" - DASHARO_REL_VER="1.1.1" - DASHARO_REL_VER_DPP="1.1.4" BIOS_LINK_COMM="${FW_STORE_URL}/${DASHARO_REL_NAME}/v${DASHARO_REL_VER}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}_ddr4.rom" BIOS_LINK_DPP="${FW_STORE_URL_DPP}/MS-7D25/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}_ddr4.rom" - HAVE_HEADS_FW="true" - HEADS_REL_VER_DPP="0.9.0" + BIOS_LINK_DPP_CAP="${FW_STORE_URL_DPP}/MS-7D25/v${DASHARO_REL_VER_DPP_CAP}/${DASHARO_REL_NAME_CAP}_v${DASHARO_REL_VER_DPP_CAP}_ddr4.cap" HEADS_LINK_DPP="${FW_STORE_URL_DPP}/MS-7D25/v${HEADS_REL_VER_DPP}/${DASHARO_REL_NAME}_v${HEADS_REL_VER_DPP}_ddr4_heads.rom" - HEADS_SWITCH_FLASHROM_OPT_OVERRIDE="--ifd -i bios" - HAVE_EC="false" - NEED_EC_RESET="false" - BIOS_HASH_LINK_COMM="${BIOS_LINK_COMM}.sha256" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - BIOS_SIGN_LINK_COMM="${BIOS_LINK_COMM}.sha256.sig" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" - PLATFORM_SIGN_KEY="dasharo/msi_ms7d25/dasharo-release-1.x-compatible-with-msi-ms-7d25-signing-key.asc \ - dasharo/msi_ms7d25/dasharo-release-0.x-compatible-with-msi-ms-7d25-signing-key.asc" - NEED_SMBIOS_MIGRATION="true" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="false" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="" - NEED_ROMHOLE_MIGRATION="true" - if check_if_dasharo; then - # if v1.1.3 or older, flash the whole bios region - # TODO: Let DTS determine which parameters are suitable. - # FIXME: Can we ever get rid of that? We change so much in each release, - # that we almost always need to flash whole BIOS region - # because of non-backward compatible or breaking changes. - compare_versions $DASHARO_VERSION 1.1.3 - if [ $? -eq 1 ]; then - # For Dasharo version lesser than 1.1.3 - NEED_BOOTSPLASH_MIGRATION="true" - FLASHROM_ADD_OPT_UPDATE_OVERRIDE="--ifd -i bios" - fi - fi ;; "PRO Z690-A WIFI (MS-7D25)" | "PRO Z690-A (MS-7D25)") - DASHARO_REL_NAME="msi_ms7d25" - DASHARO_REL_VER="1.1.1" - DASHARO_REL_VER_DPP="1.1.4" BIOS_LINK_COMM="${FW_STORE_URL}/${DASHARO_REL_NAME}/v${DASHARO_REL_VER}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}_ddr5.rom" BIOS_LINK_DPP="${FW_STORE_URL_DPP}/MS-7D25/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}_ddr5.rom" - HAVE_HEADS_FW="true" - HEADS_REL_VER_DPP="0.9.0" + BIOS_LINK_DPP_CAP="${FW_STORE_URL_DPP}/MS-7D25/v${DASHARO_REL_VER_DPP_CAP}/${DASHARO_REL_NAME_CAP}_v${DASHARO_REL_VER_DPP_CAP}_ddr5.cap" HEADS_LINK_DPP="${FW_STORE_URL_DPP}/MS-7D25/v${HEADS_REL_VER_DPP}/${DASHARO_REL_NAME}_v${HEADS_REL_VER_DPP}_ddr5_heads.rom" - HEADS_SWITCH_FLASHROM_OPT_OVERRIDE="--ifd -i bios" - HAVE_EC="false" - NEED_EC_RESET="false" - BIOS_HASH_LINK_COMM="${BIOS_LINK_COMM}.sha256" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - BIOS_SIGN_LINK_COMM="${BIOS_LINK_COMM}.sha256.sig" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" - PLATFORM_SIGN_KEY="dasharo/msi_ms7d25/dasharo-release-1.x-compatible-with-msi-ms-7d25-signing-key.asc \ - dasharo/msi_ms7d25/dasharo-release-0.x-compatible-with-msi-ms-7d25-signing-key.asc" - NEED_SMBIOS_MIGRATION="true" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="false" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="" - NEED_ROMHOLE_MIGRATION="true" - if check_if_dasharo; then - # if v1.1.3 or older, flash the whole bios region - # TODO: Let DTS determine which parameters are suitable. - # FIXME: Can we ever get rid of that? We change so much in each release, - # that we almost always need to flash whole BIOS region - # because of non-backward compatible or breaking changes. - compare_versions $DASHARO_VERSION 1.1.3 - if [ $? -eq 1 ]; then - # For Dasharo version lesser than 1.1.3 - NEED_BOOTSPLASH_MIGRATION="true" - FLASHROM_ADD_OPT_UPDATE_OVERRIDE="--ifd -i bios" - fi - fi ;; *) print_error "Board model $BOARD_MODEL is currently not supported" @@ -563,82 +438,50 @@ board_config() { esac ;; "MS-7E06") + # Common configuration for all MS-7E06: + DASHARO_REL_NAME="msi_ms7e06" + #DASHARO_REL_VER="" + DASHARO_REL_VER_DPP="0.9.2" + CAN_INSTALL_BIOS="true" + HAVE_HEADS_FW="true" + HEADS_REL_VER_DPP="0.9.0" + HEADS_SWITCH_FLASHROM_OPT_OVERRIDE="--ifd -i bios" + PLATFORM_SIGN_KEY="dasharo/msi_ms7e06/dasharo-release-0.x-compatible-with-msi-ms-7e06-signing-key.asc" + NEED_SMMSTORE_MIGRATION="true" + NEED_ROMHOLE_MIGRATION="true" + + # Add capsules: + DASHARO_REL_NAME_CAP="$DASHARO_REL_NAME" + DASHARO_REL_VER_DPP_CAP="$DASHARO_REL_VER_DPP" + DASHARO_SUPPORT_CAP_FROM="0.9.2" + + if check_if_dasharo; then + # if v0.9.1 or older, flash the whole bios region + # TODO: Let DTS determine which parameters are suitable. + # FIXME: Can we ever get rid of that? We change so much in each release, + # that we almost always need to flash whole BIOS region + # because of non-backward compatible or breaking changes. + compare_versions $DASHARO_VERSION 0.9.1 + if [ $? -eq 1 ]; then + # For Dasharo version lesser than 0.9.1 + NEED_BOOTSPLASH_MIGRATION="true" + FLASHROM_ADD_OPT_UPDATE_OVERRIDE="--ifd -i bios" + fi + fi + case "$BOARD_MODEL" in "PRO Z790-P WIFI DDR4(MS-7E06)" | "PRO Z790-P DDR4(MS-7E06)" | "PRO Z790-P WIFI DDR4 (MS-7E06)" | "PRO Z790-P DDR4 (MS-7E06)") - DASHARO_REL_NAME="msi_ms7e06" - #DASHARO_REL_VER="" - DASHARO_REL_VER_DPP="0.9.2" #BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}_ddr4.rom" BIOS_LINK_DPP="${FW_STORE_URL_DPP}/MS-7E06/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}_ddr4.rom" - HAVE_HEADS_FW="true" - HEADS_REL_VER_DPP="0.9.0" + BIOS_LINK_DPP_CAP="${FW_STORE_URL_DPP}/MS-7E06/v${DASHARO_REL_VER_DPP_CAP}/${DASHARO_REL_NAME_CAP}_v${DASHARO_REL_VER_DPP_CAP}_ddr4.cap" HEADS_LINK_DPP="${FW_STORE_URL_DPP}/MS-7E06/v${HEADS_REL_VER_DPP}/${DASHARO_REL_NAME}_v${HEADS_REL_VER_DPP}_ddr4_heads.rom" - HEADS_SWITCH_FLASHROM_OPT_OVERRIDE="--ifd -i bios" - HAVE_EC="false" - NEED_EC_RESET="false" - #BIOS_HASH_LINK_COMM="${BIOS_LINK_COMM}.sha256" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - #BIOS_SIGN_LINK_COMM="${BIOS_LINK_COMM}.sha256.sig" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" - PLATFORM_SIGN_KEY="dasharo/msi_ms7e06/dasharo-release-0.x-compatible-with-msi-ms-7e06-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="false" - NEED_BLOB_TRANSMISSION="false" PROGRAMMER_BIOS="internal:boardmismatch=force" - PROGRAMMER_EC="" - NEED_ROMHOLE_MIGRATION="true" - if check_if_dasharo; then - # if v0.9.1 or older, flash the whole bios region - # TODO: Let DTS determine which parameters are suitable. - # FIXME: Can we ever get rid of that? We change so much in each release, - # that we almost always need to flash whole BIOS region - # because of non-backward compatible or breaking changes. - compare_versions $DASHARO_VERSION 0.9.1 - if [ $? -eq 1 ]; then - # For Dasharo version lesser than 0.9.1 - NEED_BOOTSPLASH_MIGRATION="true" - FLASHROM_ADD_OPT_UPDATE_OVERRIDE="--ifd -i bios" - fi - fi ;; "PRO Z790-P WIFI (MS-7E06)" | "PRO Z790-P (MS-7E06)") - DASHARO_REL_NAME="msi_ms7e06" - #DASHARO_REL_VER="" - DASHARO_REL_VER_DPP="0.9.2" #BIOS_LINK_COMM="$FW_STORE_URL/$DASHARO_REL_NAME/v$DASHARO_REL_VER/${DASHARO_REL_NAME}_v${DASHARO_REL_VER}_ddr5.rom" BIOS_LINK_DPP="${FW_STORE_URL_DPP}/MS-7E06/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}_ddr5.rom" - HAVE_HEADS_FW="true" - HEADS_REL_VER_DPP="0.9.0" + BIOS_LINK_DPP_CAP="${FW_STORE_URL_DPP}/MS-7E06/v${DASHARO_REL_VER_DPP_CAP}/${DASHARO_REL_NAME_CAP}_v${DASHARO_REL_VER_DPP_CAP}_ddr5.cap" HEADS_LINK_DPP="${FW_STORE_URL_DPP}/MS-7E06/v${HEADS_REL_VER_DPP}/${DASHARO_REL_NAME}_v${HEADS_REL_VER_DPP}_ddr5_heads.rom" - HEADS_SWITCH_FLASHROM_OPT_OVERRIDE="--ifd -i bios" - HAVE_EC="false" - NEED_EC_RESET="false" - #BIOS_HASH_LINK_COMM="${BIOS_LINK_COMM}.sha256" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - #BIOS_SIGN_LINK_COMM="${BIOS_LINK_COMM}.sha256.sig" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" - PLATFORM_SIGN_KEY="dasharo/msi_ms7e06/dasharo-release-0.x-compatible-with-msi-ms-7e06-signing-key.asc" - NEED_SMBIOS_MIGRATION="false" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="false" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" - PROGRAMMER_EC="" - NEED_ROMHOLE_MIGRATION="true" - if check_if_dasharo; then - # if v0.9.1 or older, flash the whole bios region - # TODO: Let DTS determine which parameters are suitable. - # FIXME: Can we ever get rid of that? We change so much in each release, - # that we almost always need to flash whole BIOS region - # because of non-backward compatible or breaking changes. - compare_versions $DASHARO_VERSION 0.9.1 - if [ $? -eq 1 ]; then - # For Dasharo version lesser than 0.9.1 - NEED_BOOTSPLASH_MIGRATION="true" - FLASHROM_ADD_OPT_UPDATE_OVERRIDE="--ifd -i bios" - fi - fi ;; *) print_error "Board model $BOARD_MODEL is currently not supported" @@ -653,22 +496,20 @@ board_config() { esac ;; "Dell Inc.") + # Common configuration for all Dell releases: DASHARO_REL_NAME="dell_optiplex_7010_9010" DASHARO_REL_VER_DPP="0.1.0" BIOS_LINK_DPP="$FW_STORE_URL_DPP/v$DASHARO_REL_VER_DPP/${DASHARO_REL_NAME}_v$DASHARO_REL_VER_DPP.rom" - HAVE_EC="false" - NEED_EC_RESET="false" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" + CAN_INSTALL_BIOS="true" NEED_SMBIOS_MIGRATION="true" NEED_BLOB_TRANSMISSION="true" - PROGRAMMER_BIOS="internal" SINIT_ACM_FILENAME="/tmp/630744_003.zip" SINIT_ACM_URL="https://cdrdv2.intel.com/v1/dl/getContent/630744" SINIT_ACM_HASH="0b412c1832bd504d4b8f5fa01b32449c344fe0019e5e4da6bb5d80d393df5e8b $SINIT_ACM_FILENAME" SINIT_ACM="/tmp/630744_003/SNB_IVB_SINIT_20190708_PW.bin" FLASHROM_ADD_OPT_DEPLOY="--ifd -i bios" FLASHROM_ADD_OPT_UPDATE="--fmap -i RW_SECTION_A" + case "$SYSTEM_MODEL" in "OptiPlex 7010") DBT_BIOS_UPDATE_FILENAME="/tmp/O7010A29.exe" @@ -711,8 +552,7 @@ board_config() { "KGPE-D16") DASHARO_REL_NAME="asus_kgpe-d16" DASHARO_REL_VER="0.4.0" - HAVE_EC="false" - NEED_EC_RESET="false" + CAN_INSTALL_BIOS="true" case "$FLASH_CHIP_SIZE" in "2") BIOS_HASH_LINK_COMM="65e5370e9ea6b8ae7cd6cc878a031a4ff3a8f5d36830ef39656b8e5a6e37e889 $BIOS_UPDATE_FILE" @@ -732,8 +572,6 @@ board_config() { ;; esac NEED_SMBIOS_MIGRATION="true" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" ;; *) print_error "Board model $SYSTEM_MODEL is currently not supported" @@ -742,86 +580,42 @@ board_config() { esac ;; "PC Engines") + # Common configuration for all PC Engines releases: + DASHARO_REL_VER_DPP="0.9.0" + CAN_INSTALL_BIOS="true" + DASHARO_REL_VER_DPP_SEABIOS="24.05.00.01" + PROGRAMMER_BIOS="internal:boardmismatch=force" + NEED_SMMSTORE_MIGRATION="true" + NEED_BOOTSPLASH_MIGRATION="true" FLASH_CHIP_LIST="W25Q64JV-.Q" + shopt -s nocasematch case "$SYSTEM_MODEL" in "APU2") DASHARO_REL_NAME="pcengines_apu2" - DASHARO_REL_VER_DPP="0.9.0" - HAVE_EC="false" - NEED_EC_RESET="false" - BIOS_LINK_DPP="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}.rom" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" - DASHARO_REL_VER_DPP_SEABIOS="24.05.00.01" - BIOS_LINK_DPP_SEABIOS="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP_SEABIOS}/${DASHARO_REL_NAME}_seabios_v${DASHARO_REL_VER_DPP_SEABIOS}.rom" - BIOS_HASH_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256" - BIOS_SIGN_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256.sig" - PROGRAMMER_BIOS="internal:boardmismatch=force" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="true" ;; "APU3") DASHARO_REL_NAME="pcengines_apu3" - DASHARO_REL_VER_DPP="0.9.0" - HAVE_EC="false" - NEED_EC_RESET="false" - BIOS_LINK_DPP="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}.rom" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" - DASHARO_REL_VER_DPP_SEABIOS="24.05.00.01" - BIOS_LINK_DPP_SEABIOS="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP_SEABIOS}/${DASHARO_REL_NAME}_seabios_v${DASHARO_REL_VER_DPP_SEABIOS}.rom" - BIOS_HASH_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256" - BIOS_SIGN_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256.sig" - PROGRAMMER_BIOS="internal:boardmismatch=force" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="true" ;; "APU4") DASHARO_REL_NAME="pcengines_apu4" - DASHARO_REL_VER_DPP="0.9.0" - HAVE_EC="false" - NEED_EC_RESET="false" - BIOS_LINK_DPP="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}.rom" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" - DASHARO_REL_VER_DPP_SEABIOS="24.05.00.01" - BIOS_LINK_DPP_SEABIOS="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP_SEABIOS}/${DASHARO_REL_NAME}_seabios_v${DASHARO_REL_VER_DPP_SEABIOS}.rom" - BIOS_HASH_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256" - BIOS_SIGN_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256.sig" - PROGRAMMER_BIOS="internal:boardmismatch=force" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="true" ;; "APU6") DASHARO_REL_NAME="pcengines_apu6" - DASHARO_REL_VER_DPP="0.9.0" - HAVE_EC="false" - NEED_EC_RESET="false" - BIOS_LINK_DPP="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}.rom" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" - DASHARO_REL_VER_DPP_SEABIOS="24.05.00.01" - BIOS_LINK_DPP_SEABIOS="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP_SEABIOS}/${DASHARO_REL_NAME}_seabios_v${DASHARO_REL_VER_DPP_SEABIOS}.rom" - BIOS_HASH_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256" - BIOS_SIGN_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256.sig" - PROGRAMMER_BIOS="internal:boardmismatch=force" - NEED_SMMSTORE_MIGRATION="true" - NEED_BOOTSPLASH_MIGRATION="true" ;; *) print_error "Board model $SYSTEM_MODEL is currently not supported" return 1 ;; esac + + BIOS_LINK_DPP="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP}/${DASHARO_REL_NAME}_v${DASHARO_REL_VER_DPP}.rom" + BIOS_LINK_DPP_SEABIOS="${FW_STORE_URL_DPP}/pcengines_apu2/v${DASHARO_REL_VER_DPP_SEABIOS}/${DASHARO_REL_NAME}_seabios_v${DASHARO_REL_VER_DPP_SEABIOS}.rom" + shopt -u nocasematch ;; "HARDKERNEL") - HAVE_EC="false" - NEED_EC_RESET="false" NEED_SMBIOS_MIGRATION="true" - NEED_BLOB_TRANSMISSION="false" - PROGRAMMER_BIOS="internal" case "$SYSTEM_MODEL" in "ODROID-H4") @@ -836,18 +630,58 @@ board_config() { esac BIOS_LINK_DPP="$FW_STORE_URL_DPP/$DASHARO_REL_NAME/v$DASHARO_REL_VER_DPP/${DASHARO_REL_NAME}_v$DASHARO_REL_VER_DPP.rom" - BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" - BIOS_SIGN_LINK_DPP="${BIOS_LINK_DPP}.sha256.sig" + ;; + "QEMU"|"Emulation") + case "$SYSTEM_MODEL" in + *Q35*ICH9*|*q35*ich9*) + # Update type: + CAN_INSTALL_BIOS="true" + # Download and versioning variables: + DASHARO_REL_NAME_CAP="qemu_q35" + DASHARO_REL_VER_CAP="0.2.0" + DASHARO_SUPPORT_CAP_FROM="0.2.0" + # TODO: wait till the binaries will be uploaded to the server. + BIOS_LINK_COMM_CAP="${FW_STORE_URL}/${DASHARO_REL_NAME_CAP}/v${DASHARO_REL_VER_CAP}/" + ;; + *) + print_error "Board model $SYSTEM_MODEL is currently not supported" + return 1 + ;; + esac ;; *) print_error "Board vendor: $SYSTEM_VENDOR is currently not supported" return 1 ;; esac + + # Set some default values at the end: + [ -z "$BIOS_HASH_LINK_COMM" ] && BIOS_HASH_LINK_COMM="${BIOS_LINK_COMM}.sha256" + [ -z "$BIOS_SIGN_LINK_COMM" ] && BIOS_SIGN_LINK_COMM="${BIOS_HASH_LINK_COMM}.sig" + [ -z "$BIOS_HASH_LINK_DPP" ] && BIOS_HASH_LINK_DPP="${BIOS_LINK_DPP}.sha256" + [ -z "$BIOS_SIGN_LINK_DPP" ] && BIOS_SIGN_LINK_DPP="${BIOS_HASH_LINK_DPP}.sig" + [ -z "$BIOS_HASH_LINK_DPP_SEABIOS" ] && BIOS_HASH_LINK_DPP_SEABIOS="${BIOS_LINK_DPP_SEABIOS}.sha256" + [ -z "$BIOS_SIGN_LINK_DPP_SEABIOS" ] && BIOS_SIGN_LINK_DPP_SEABIOS="${BIOS_HASH_LINK_DPP_SEABIOS}.sig" + [ -z "$HEADS_HASH_LINK_DPP" ] && HEADS_HASH_LINK_DPP="${HEADS_LINK_DPP}.sha256" + [ -z "$HEADS_SIGN_LINK_DPP" ] && HEADS_SIGN_LINK_DPP="${HEADS_HASH_LINK_DPP}.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" + [ -z "$EC_HASH_LINK_DPP" ] && EC_HASH_LINK_DPP="${EC_LINK_DPP}.sha256" + [ -z "$EC_SIGN_LINK_DPP" ] && EC_SIGN_LINK_DPP="${EC_HASH_LINK_DPP}.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_HASH_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" + [ -z "$EC_HASH_LINK_DPP_CAP" ] && EC_HASH_LINK_DPP_CAP="${EC_LINK_DPP_CAP}.sha256" + [ -z "$EC_SIGN_LINK_DPP_CAP" ] && EC_SIGN_LINK_DPP_CAP="${EC_HASH_LINK_DPP_CAP}.sig" } check_flash_lock() { - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} > /tmp/check_flash_lock 2> /tmp/check_flash_lock.err + $FLASHROM check_flash_lock_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} > /tmp/check_flash_lock 2> /tmp/check_flash_lock.err # Check in flashrom output if lock is enabled grep -q 'PR0: Warning:.* is read-only\|SMM protection is enabled' /tmp/check_flash_lock.err if [ $? -eq 0 ]; then @@ -860,22 +694,22 @@ check_flash_lock() { check_flash_chip() { echo "Gathering flash chip and chipset information..." - $FLASHROM -p "$PROGRAMMER_BIOS" --flash-name >> "$FLASH_INFO_FILE" 2>> "$ERR_LOG_FILE" + $FLASHROM flash_chip_name_mock -p "$PROGRAMMER_BIOS" --flash-name >> "$FLASH_INFO_FILE" 2>> "$ERR_LOG_FILE" if [ $? -eq 0 ]; then echo -n "Flash information: " tail -n1 "$FLASH_INFO_FILE" - FLASH_CHIP_SIZE=$(($($FLASHROM -p "$PROGRAMMER_BIOS" --flash-size 2>> /dev/null | tail -n1) / 1024 / 1024)) + FLASH_CHIP_SIZE=$(($($FLASHROM flash_chip_size_mock -p "$PROGRAMMER_BIOS" --flash-size 2>> /dev/null | tail -n1) / 1024 / 1024)) echo -n "Flash size: " echo ${FLASH_CHIP_SIZE}M else for flash_name in $FLASH_CHIP_LIST do - $FLASHROM -p "$PROGRAMMER_BIOS" -c "$flash_name" --flash-name >> "$FLASH_INFO_FILE" 2>> "$ERR_LOG_FILE" + $FLASHROM flash_chip_name_mock -p "$PROGRAMMER_BIOS" -c "$flash_name" --flash-name >> "$FLASH_INFO_FILE" 2>> "$ERR_LOG_FILE" if [ $? -eq 0 ]; then echo "Chipset found" tail -n1 "$FLASH_INFO_FILE" FLASH_CHIP_SELECT="-c ${flash_name}" - FLASH_CHIP_SIZE=$(($($FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} --flash-size 2>> /dev/null | tail -n1) / 1024 / 1024)) + FLASH_CHIP_SIZE=$(($($FLASHROM flash_chip_size_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} --flash-size 2>> /dev/null | tail -n1) / 1024 / 1024)) echo "Chipset size" echo ${FLASH_CHIP_SIZE}M break @@ -911,7 +745,7 @@ compare_versions() { } download_bios() { - if [ -v BIOS_LINK_COMM ] && [ ${BIOS_LINK} == ${BIOS_LINK_COMM} ]; then + if [ "${BIOS_LINK}" == "${BIOS_LINK_COMM}" ] || [ "${BIOS_LINK}" == "${BIOS_LINK_COMM_CAP}" ]; then curl -s -L -f "$BIOS_LINK" -o $BIOS_UPDATE_FILE error_check "Cannot access $FW_STORE_URL while downloading binary. Please check your internet connection" @@ -936,52 +770,29 @@ download_bios() { } download_ec() { - if [ -v BIOS_LINK_COMM ] && [ ${BIOS_LINK} == ${BIOS_LINK_COMM} ]; then - if [ "$HAVE_EC" == "true" ]; then - curl -s -L -f "$EC_LINK" -o "$EC_UPDATE_FILE" - error_check "Cannot access $FW_STORE_URL while downloading binary. Please + if [ "${BIOS_LINK}" = "${BIOS_LINK_COMM}" ] || [ "${BIOS_LINK}" = "${BIOS_LINK_COMM_CAP}" ]; then + curl -s -L -f "$EC_LINK" -o "$EC_UPDATE_FILE" + error_check "Cannot access $FW_STORE_URL while downloading binary. Please + check your internet connection" + curl -s -L -f "$EC_HASH_LINK" -o $EC_HASH_FILE + error_check "Cannot access $FW_STORE_URL while downloading signature. Please + check your internet connection" + curl -s -L -f "$EC_SIGN_LINK" -o $EC_SIGN_FILE + error_check "Cannot access $FW_STORE_URL while downloading signature. Please + check your internet connection" + else + curl -s -L -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$EC_LINK" -o $EC_UPDATE_FILE + error_check "Cannot access $FW_STORE_URL while downloading binary. Please check your internet connection and credentials" - curl -s -L -f "$EC_HASH_LINK" -o $EC_HASH_FILE - error_check "Cannot access $FW_STORE_URL while downloading signature. Please + curl -s -L -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$EC_HASH_LINK" -o $EC_HASH_FILE + error_check "Cannot access $FW_STORE_URL while downloading signature. Please check your internet connection and credentials" - curl -s -L -f "$EC_SIGN_LINK" -o $EC_SIGN_FILE - error_check "Cannot access $FW_STORE_URL while downloading signature. Please + curl -s -L -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$EC_SIGN_LINK" -o $EC_SIGN_FILE + error_check "Cannot access $FW_STORE_URL while downloading signature. Please check your internet connection and credentials" - fi - else - if [ "$HAVE_EC" == "true" ]; then - if [ -v EC_LINK_COMM ] && [ ${EC_LINK} == ${EC_LINK_COMM} ]; then - curl -s -L -f "$EC_LINK" -o "$EC_UPDATE_FILE" - error_check "Cannot access $FW_STORE_URL while downloading binary. Please - check your internet connection" - curl -s -L -f "$EC_HASH_LINK" -o $EC_HASH_FILE - error_check "Cannot access $FW_STORE_URL while downloading signature. Please - check your internet connection" - curl -s -L -f "$EC_SIGN_LINK" -o $EC_SIGN_FILE - error_check "Cannot access $FW_STORE_URL while downloading signature. Please - check your internet connection" - else - curl -s -L -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$EC_LINK" -o $EC_UPDATE_FILE - error_check "Cannot access $FW_STORE_URL while downloading binary. Please - check your internet connection" - curl -s -L -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$EC_HASH_LINK" -o $EC_HASH_FILE - error_check "Cannot access $FW_STORE_URL while downloading signature. Please - check your internet connection" - curl -s -L -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$EC_SIGN_LINK" -o $EC_SIGN_FILE - error_check "Cannot access $FW_STORE_URL while downloading signature. Please - check your internet connection" - fi - fi fi } -download_artifacts() { - echo -n "Downloading Dasharo firmware..." - download_bios - download_ec - print_ok "Done" -} - download_keys() { mkdir $KEYS_DIR wget -O $KEYS_DIR/recovery_key.vbpubk https://github.com/Dasharo/vboot/raw/dasharo/tests/devkeys/recovery_key.vbpubk >> $ERR_LOG_FILE 2>&1 @@ -1002,45 +813,62 @@ get_signing_keys() { } verify_artifacts() { - local _type="$1" +# 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 _update_file="" local _hash_file="" local _sign_file="" 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 [ -v 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 + local _type="$1" + + 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 + ;; + *) + error_exit "Unknown artifact type: $_type" + ;; + 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() { - FLASH_REGIONS=$($FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} 2>&1) + FLASH_REGIONS=$($FLASHROM check_intel_regions_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} 2>&1) BOARD_HAS_FD_REGION=0 BOARD_FD_REGION_RW=0 BOARD_HAS_ME_REGION=0 @@ -1068,7 +896,7 @@ check_blobs_in_binary() { # If there is no descriptor, there is no ME as well, so skip the check if [ $BOARD_HAS_FD_REGION -ne 0 ]; then - ME_OFFSET=$(ifdtool -d $1 2> /dev/null | grep "Flash Region 2 (Intel ME):" | sed 's/Flash Region 2 (Intel ME)\://' |awk '{print $1;}') + ME_OFFSET=$($IFDTOOL check_blobs_in_binary_mock -d $1 2> /dev/null | grep "Flash Region 2 (Intel ME):" | sed 's/Flash Region 2 (Intel ME)\://' | awk '{print $1;}') # Check for IFD signature at offset 0 (old descriptors) if [ "$(tail -c +0 $1|head -c 4|xxd -ps)" == "5aa5f00f" ]; then BINARY_HAS_FD=1 @@ -1098,11 +926,8 @@ check_if_me_disabled() { return fi - # Check if HECI present - # FIXME: what if HECI is not device 16.0? - if [ -d /sys/class/pci_bus/0000:00/device/0000:00:16.0 ]; then - # Check ME Current Operation Mode at offset 0x40 bits 19:16 - ME_OPMODE="$(setpci -s 00:16.0 42.B 2> /dev/null | cut -c2-)" + if check_if_heci_present; then + ME_OPMODE="$(check_me_op_mode)" if [ $ME_OPMODE == "0" ]; then echo "ME is not disabled" >> $ERR_LOG_FILE return @@ -1137,8 +962,8 @@ check_if_me_disabled() { fi else # If we are running coreboot, check for status in logs - cbmem -1 | grep -q "ME is disabled" && ME_DISABLED=1 && return # HECI (soft) disabled - cbmem -1 | grep -q "ME is HAP disabled" && ME_DISABLED=1 && return # HAP disabled + $CBMEM check_if_me_disabled_mock -1 | grep -q "ME is disabled" && ME_DISABLED=1 && return # HECI (soft) disabled + $CBMEM check_if_me_disabled_mock -1 | grep -q "ME is HAP disabled" && ME_DISABLED=1 && return # HAP disabled # TODO: If proprietary BIOS, then also try to check SMBIOS for ME FWSTS # BTW we could do the same in coreboot, expose FWSTS in SMBIOS before it # gets disabled @@ -1183,10 +1008,10 @@ set_flashrom_update_params() { # We need to read whole binary (or BIOS region), otherwise cbfstool will # return different attributes for CBFS regions echo "Checking flash layout." - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_UPDATE} -r /tmp/bios.bin > /dev/null 2>&1 - if [ $? -eq 0 ] && [ -f "/tmp/bios.bin" ]; then - BOARD_FMAP_LAYOUT=$(cbfstool /tmp/bios.bin layout -w 2> /dev/null) - BINARY_FMAP_LAYOUT=$(cbfstool $1 layout -w 2> /dev/null) + $FLASHROM read_flash_layout_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_UPDATE} -r $BIOS_DUMP_FILE > /dev/null 2>&1 + if [ $? -eq 0 ] && [ -f "$BIOS_DUMP_FILE" ]; then + BOARD_FMAP_LAYOUT=$($CBFSTOOL layout_mock $BIOS_DUMP_FILE layout -w 2> /dev/null) + BINARY_FMAP_LAYOUT=$($CBFSTOOL layout_mock $1 layout -w 2> /dev/null) diff <(echo "$BOARD_FMAP_LAYOUT") <(echo "$BINARY_FMAP_LAYOUT") > /dev/null 2>&1 # If layout is identical, perform standard update using FMAP only if [ $? -eq 0 ]; then @@ -1259,9 +1084,21 @@ handle_fw_switching() { yes|y|Y|Yes|YES) UPDATE_VERSION=$HEADS_REL_VER_DPP FLASHROM_ADD_OPT_UPDATE_OVERRIDE=$HEADS_SWITCH_FLASHROM_OPT_OVERRIDE - BIOS_HASH_LINK="${HEADS_LINK_DPP}.sha256" - BIOS_SIGN_LINK="${HEADS_LINK_DPP}.sha256.sig" - BIOS_LINK=$HEADS_LINK_DPP + BIOS_HASH_LINK="${HEADS_HASH_LINK_DPP}" + BIOS_SIGN_LINK="${HEADS_SIGN_LINK_DPP}" + BIOS_LINK="$HEADS_LINK_DPP" + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -n "$EC_LINK_DPP" ]; then + EC_LINK=$EC_LINK_DPP + EC_HASH_LINK=$EC_HASH_LINK_DPP + EC_SIGN_LINK=$EC_SIGN_LINK_DPP + elif [ -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 + export SWITCHING_TO="heads" echo echo "Switching to Dasharo heads firmware v$UPDATE_VERSION" @@ -1279,7 +1116,7 @@ handle_fw_switching() { ;; esac done - elif [ -v DPP_IS_LOGGED ] && [ -v HEADS_LINK_DPP ]; then + elif [ -n "$DPP_IS_LOGGED" ] && [ -n "$HEADS_LINK_DPP" ]; then local _heads_dpp=1 curl -sfI -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$HEADS_LINK_DPP" -o /dev/null _heads_dpp=$? @@ -1313,9 +1150,21 @@ handle_fw_switching() { fi echo "Will not switch back to regular Dasharo firmware. Proceeding with Dasharo heads firmware update to $UPDATE_VERSION." FLASHROM_ADD_OPT_UPDATE_OVERRIDE="--ifd -i bios" - BIOS_HASH_LINK="${HEADS_LINK_DPP}.sha256" - BIOS_SIGN_LINK="${HEADS_LINK_DPP}.sha256.sig" - BIOS_LINK=$HEADS_LINK_DPP + BIOS_HASH_LINK="${HEADS_HASH_LINK_DPP}" + BIOS_SIGN_LINK="${HEADS_SIGN_LINK_DPP}" + BIOS_LINK="$HEADS_LINK_DPP" + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -n "$EC_LINK_DPP" ]; then + EC_LINK=$EC_LINK_DPP + EC_HASH_LINK=$EC_HASH_LINK_DPP + EC_SIGN_LINK=$EC_SIGN_LINK_DPP + elif [ -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 + break ;; *) @@ -1323,7 +1172,7 @@ handle_fw_switching() { esac done fi - elif [ ! -v DPP_IS_LOGGED ] && [ "$DASHARO_FLAVOR" == "Dasharo (coreboot+heads)" ]; then + elif [ -z "$DPP_IS_LOGGED" ] && [ "$DASHARO_FLAVOR" == "Dasharo (coreboot+heads)" ]; then # Not logged with DPP and we are on heads, offer switch back compare_versions $DASHARO_VERSION $HEADS_REL_VER_DPP if [ $? -eq 1 ]; then @@ -1391,7 +1240,7 @@ You can find more info about HCL in docs.dasharo.com/glossary\r" show_ram_inf() { # Get the data: local data="" - data=$(dmidecode) + data=$($DMIDECODE) # Initialize an empty array to store the extracted values: local -a memory_devices_array @@ -1447,7 +1296,7 @@ show_hardsoft_inf() { echo -e "${BLUE}**${NORMAL} HARDWARE INFORMATION ${NORMAL}" echo -e "${BLUE}*********************************************************${NORMAL}" echo -e "${BLUE}**${YELLOW} System Inf.: ${NORMAL}${SYSTEM_VENDOR} ${SYSTEM_MODEL}" - echo -e "${BLUE}**${YELLOW} Baseboard Inf.: ${NORMAL}${BOARD_VENDOR} ${BOARD_MODEL}" + echo -e "${BLUE}**${YELLOW} Baseboard Inf.: ${NORMAL}${SYSTEM_VENDOR} ${BOARD_MODEL}" echo -e "${BLUE}**${YELLOW} CPU Inf.: ${NORMAL}${CPU_VERSION}" show_ram_inf echo -e "${BLUE}*********************************************************${NORMAL}" @@ -1488,10 +1337,14 @@ show_main_menu() { echo -e "${BLUE}**${YELLOW} ${HCL_REPORT_OPT})${BLUE} Dasharo HCL report${NORMAL}" if check_if_dasharo; then echo -e "${BLUE}**${YELLOW} ${DASHARO_FIRM_OPT})${BLUE} Update Dasharo Firmware${NORMAL}" - else + # flashrom does not support QEMU. TODO: this could be handled in a better way: + elif [ "${SYSTEM_VENDOR}" != "QEMU" ] && [ "${SYSTEM_VENDOR}" != "Emulation" ]; then echo -e "${BLUE}**${YELLOW} ${DASHARO_FIRM_OPT})${BLUE} Install Dasharo Firmware${NORMAL}" fi - echo -e "${BLUE}**${YELLOW} ${REST_FIRM_OPT})${BLUE} Restore firmware from Dasharo HCL report${NORMAL}" + # flashrom does not support QEMU. TODO: this could be handled in a better way: + if [ "${SYSTEM_VENDOR}" != "QEMU" ] && [ "${SYSTEM_VENDOR}" != "Emulation" ]; then + echo -e "${BLUE}**${YELLOW} ${REST_FIRM_OPT})${BLUE} Restore firmware from Dasharo HCL report${NORMAL}" + fi if [ -n "${DPP_IS_LOGGED}" ]; then echo -e "${BLUE}**${YELLOW} ${DPP_KEYS_OPT})${BLUE} Edit your DPP keys${NORMAL}" else @@ -1531,12 +1384,16 @@ main_menu_options(){ export DEPLOY_REPORT="false" ${CMD_DASHARO_HCL_REPORT} fi - read -p "Press any key to continue." + read -p "Press enter to continue." return 0 ;; "${DASHARO_FIRM_OPT}") if ! check_if_dasharo; then + # flashrom does not support QEMU, but installation depends on flashrom. + # TODO: this could be handled in a better way: + [ "${SYSTEM_VENDOR}" = "QEMU" ] || [ "${SYSTEM_VENDOR}" = "Emulation" ] && return 0 + if wait_for_network_connection; then echo "Preparing ..." if [ -z "${LOGS_SENT}" ]; then @@ -1555,6 +1412,7 @@ main_menu_options(){ ${CMD_DASHARO_DEPLOY} install fi else + # TODO: This should be placed in dasharo-deploy: # For NovaCustom TGL laptops with Dasharo version lower than 1.3.0, # we shall run the ec_transition script instead. See: # https://docs.dasharo.com/variants/novacustom_nv4x_tgl/releases/#v130-2022-10-18 @@ -1581,15 +1439,19 @@ main_menu_options(){ # Use regular update process for everything else ${CMD_DASHARO_DEPLOY} update fi - read -p "Press any key to continue." + read -p "Press enter to continue." return 0 ;; "${REST_FIRM_OPT}") + # flashrom does not support QEMU, but restore depends on flashrom. + # TODO: this could be handled in a better way: + [ "${SYSTEM_VENDOR}" = "QEMU" ] || [ "${SYSTEM_VENDOR}" = "Emulation" ] && return 0 + if check_if_dasharo; then ${CMD_DASHARO_DEPLOY} restore fi - read -p "Press any key to continue." + read -p "Press enter to continue." return 0 ;; @@ -1602,20 +1464,27 @@ main_menu_options(){ # Try to log in using available DPP credentials, start loop over if login # was not successful: - login_to_dpp_server || return 0 + login_to_dpp_server + if [ $? -ne 0 ]; then + print_warning "Your credentials do not have access to DPP packages. If you bought one, check the" + print_warning "credentials you have used, and contact support. If you did not buy any DPP" + print_warning "packages - feel free to continue." + read -p "Press enter to continue" + return 0 + fi # Check if there is some packages available to install, start loop over if # no packages is available: check_avail_dpp_packages || return 0 # Download and install available packages, start loop over if there is - # no packages tto install: + # no packages to install: install_all_dpp_packages || return 0 # Parse installed packages for premium submenus: parse_for_premium_submenu - read -p "Press any key to continue." + read -p "Press enter to continue." return 0 ;; "${DPP_SUBMENU_OPT}") @@ -1639,9 +1508,9 @@ show_footer(){ echo -ne "${RED}${SSH_OPT_UP}${NORMAL} to launch SSH server ${NORMAL}" fi if [ "${SEND_LOGS_ACTIVE}" == "true" ]; then - echo -ne "${RED}${SEND_LOGS_OPT}${NORMAL} to disable sending DTS logs ${NORMAL}" + echo -e "${RED}${SEND_LOGS_OPT}${NORMAL} to disable sending DTS logs ${NORMAL}" else - echo -ne "${RED}${SEND_LOGS_OPT}${NORMAL} to enable sending DTS logs ${NORMAL}" + echo -e "${RED}${SEND_LOGS_OPT}${NORMAL} to enable sending DTS logs ${NORMAL}" fi if [ "${VERBOSE_ACTIVE}" == "true" ]; then echo -ne "${RED}${VERBOSE_OPT}${NORMAL} to disable verbose mode ${NORMAL}" @@ -1668,11 +1537,12 @@ footer_options(){ systemctl start sshd.service print_ok "Listening on IPs: $(ip -br -f inet a show scope global | grep UP | awk '{ print $3 }' | tr '\n' ' ')" fi - read -p "Press any key to continue." + read -p "Press enter to continue." return 0 ;; "${SHELL_OPT_UP}" | "${SHELL_OPT_LOW}") + clear echo "Entering shell, to leave type exit and press Enter or press LCtrl+D" echo "" send_dts_logs @@ -1685,11 +1555,11 @@ footer_options(){ ;; "${POWEROFF_OPT_UP}" | "${POWEROFF_OPT_LOW}") send_dts_logs - ${CMD_POWEROFF} + ${POWEROFF} ;; "${REBOOT_OPT_UP}" | "${REBOOT_OPT_LOW}") send_dts_logs - ${CMD_REBOOT} + ${REBOOT} ;; "${SEND_LOGS_OPT}" | "${SEND_LOGS_OPT_LOW}") if [ "${SEND_LOGS_ACTIVE}" == "true" ]; then @@ -1712,15 +1582,17 @@ footer_options(){ send_dts_logs(){ if [ "${SEND_LOGS_ACTIVE}" == "true" ]; then + echo "Sending logs..." + log_dir=$(dmidecode -s system-manufacturer)_$(dmidecode -s system-product-name)_$(dmidecode -s bios-version) - uuid_string="$(cat /sys/class/net/$(ip route show default | head -1 | awk '/default/ {print $5}')/address)" + uuid_string="$(cat /sys/class/net/"$(ip route show default | head -1 | awk '/default/ {print $5}')"/address)" uuid_string+="_$(dmidecode -s system-product-name)" uuid_string+="_$(dmidecode -s system-manufacturer)" uuid=`uuidgen -n @x500 -N $uuid_string -s` - log_dir+="_$uuid_$(date +'%Y_%m_%d_%H_%M_%S_%N')" + log_dir+="_${uuid}_$(date +'%Y_%m_%d_%H_%M_%S_%N')" log_dir="${log_dir// /_}" log_dir="${log_dir//\//_}" log_dir="/tmp/${log_dir}" @@ -1753,42 +1625,52 @@ send_dts_logs(){ } check_if_fused() { - file_path="/sys/class/mei/mei0/fw_status" - - if [[ ! -f $file_path ]]; then - echo "File not found: $file_path" + local _file_path + _file_path="/sys/class/mei/mei0/fw_status" + local _file_content + local _hfsts6_value + local _line_number + local _hfsts6_binary + local _binary_length + local _padding + local _zeros + local _bit_30_value + + if ! $FSREAD_TOOL test -f "$_file_path"; then + print_error "File not found: $_file_path" return 2 fi - hfsts6_value="" - line_number=1 + _file_content="$($FSREAD_TOOL cat $_file_path)" + + _fsts6_value="" + _line_number=1 while IFS= read -r line; do - if [[ $line_number -eq 6 ]]; then - hfsts6_value=$line + if [[ $_line_number -eq 6 ]]; then + _hfsts6_value="$line" break fi - ((line_number++)) - done <"$file_path" + ((_line_number++)) + done <<< "$_file_content" - if [[ -z $hfsts6_value ]]; then - echo "Failed to read HFSTS6 value" + if [[ -z "$_hfsts6_value" ]]; then + print_error "Failed to read HFSTS6 value" exit 1 fi - hfsts6_binary=$(echo "ibase=16; obase=2; $hfsts6_value" | bc) - - binary_length=${#hfsts6_binary} + _hfsts6_binary=$(echo "ibase=16; obase=2; $_hfsts6_value" | bc) + _binary_length=${#_hfsts6_binary} # Add leading zeros - if [ $binary_length -lt 32 ]; then - padding=$((32 - $binary_length)) - zeros=$(printf "%${padding}s" | tr ' ' "0") - hfsts6_binary=$zeros$hfsts6_binary + if [ $_binary_length -lt 32 ]; then + _padding=$((32 - $_binary_length)) + _zeros=$(printf "%${_padding}s" | tr ' ' "0") + _hfsts6_binary=$_zeros$_hfsts6_binary fi - bit_30_value=${hfsts6_binary:1:1} + _bit_30_value=${_hfsts6_binary:1:1} - if [ $bit_30_value == 0 ]; then + if [ $_bit_30_value == 0 ]; then return 1 else return 0 @@ -1796,29 +1678,37 @@ check_if_fused() { } check_if_boot_guard_enabled() { + local _msr_hex + local _msr_binary + local _binary_length + local _padding + local _zeros + local _facb_fpf + local _verified_boot + # MSR cannot be read - if ! rdmsr 0x13a -0; then + if ! $RDMSR boot_guard_status_mock 0x13a -0; then return 1 fi - msr_hex=$(rdmsr 0x13a -0 | tr '[:lower:]' '[:upper:]') - msr_binary=$(echo "ibase=16; obase=2; $msr_hex" | bc) - - binary_length=${#msr_binary} + _msr_hex=$($RDMSR boot_guard_status_mock 0x13a -0 | tr '[:lower:]' '[:upper:]') + _msr_binary=$(echo "ibase=16; obase=2; $_msr_hex" | bc) - if [ $binary_length -lt 64 ]; then - padding=$((64 - $binary_length)) - zeros=$(printf "%${padding}s" | tr ' ' "0") - msr_binary=$zeros$msr_binary + _binary_length=${#_msr_binary} +arkuszu + if [ $_binary_length -lt 64 ]; then + _padding=$((64 - $_binary_length)) + _zeros=$(printf "%${_padding}s" | tr ' ' "0") + _msr_binary=$_zeros$_msr_binary fi # Bit 4 - facb_fpf=${msr_binary:59:1} + _facb_fpf=${_msr_binary:59:1} # Bit 6 - verified_boot=${msr_binary:57:1} + _verified_boot=${_msr_binary:57:1} - if [ $facb_fpf == 1 ] && [ $verified_boot == 1 ]; then + if [ $_facb_fpf == 1 ] && [ $_verified_boot == 1 ]; then return 0 fi return 1 @@ -1838,7 +1728,6 @@ check_if_intel() { if [ $cpu_vendor == "GenuineIntel" ]; then return 0 fi - return 1 } set_verbose() { diff --git a/include/dts-subscription.sh b/include/dts-subscription.sh index d9303f36..71d48a9a 100644 --- a/include/dts-subscription.sh +++ b/include/dts-subscription.sh @@ -5,8 +5,6 @@ # SPDX-License-Identifier: Apache-2.0 # shellcheck disable=SC2034 -# shellcheck source=../include/dts-environment.sh -source $DTS_ENV check_for_dasharo_firmware() { # This function checks if Dasharo firmware is available for the current @@ -18,12 +16,12 @@ check_for_dasharo_firmware() { local _check_dwn_req_resp_heads="0" local _check_dwn_req_resp_seabios="0" local _check_logs_req_resp="0" - # Ignore "SC2154 (warning): DPP_credential_file is referenced but not assigned" + # Ignore "SC2154 (warning): DPP_CREDENTIAL_FILE is referenced but not assigned" # for external variable: # shellcheck disable=SC2154 - CLOUDSEND_LOGS_URL=$(sed -n '1p' < ${DPP_credential_file} | tr -d '\n') - CLOUDSEND_DOWNLOAD_URL=$(sed -n '2p' < ${DPP_credential_file} | tr -d '\n') - CLOUDSEND_PASSWORD=$(sed -n '3p' < ${DPP_credential_file} | tr -d '\n') + CLOUDSEND_LOGS_URL=$(sed -n '1p' < ${DPP_CREDENTIAL_FILE} | tr -d '\n') + CLOUDSEND_DOWNLOAD_URL=$(sed -n '2p' < ${DPP_CREDENTIAL_FILE} | tr -d '\n') + CLOUDSEND_PASSWORD=$(sed -n '3p' < ${DPP_CREDENTIAL_FILE} | tr -d '\n') USER_DETAILS="$CLOUDSEND_DOWNLOAD_URL:$CLOUDSEND_PASSWORD" # Check the board information: @@ -33,27 +31,33 @@ check_for_dasharo_firmware() { TEST_LOGS_URL="https://cloud.3mdeb.com/index.php/s/${CLOUDSEND_LOGS_URL}/authenticate/showShare" # If board_config function has not set firmware links - exit with warning: - if [ ! -v BIOS_LINK_DPP ] && [ ! -v HEADS_LINK_DPP ] && [ ! -v BIOS_LINK_DPP_SEABIOS ]; then + if [ -z "$BIOS_LINK_DPP" ] && [ -z "$HEADS_LINK_DPP" ] && [ -z "$BIOS_LINK_DPP_SEABIOS" ] && [ -z "$BIOS_LINK_DPP_CAP" ]; then print_warning "There is no Dasharo Firmware available for your platform." return 1 fi # Check for firmware binaries: if wait_for_network_connection; then - if [ -v BIOS_LINK_DPP ]; then + if [ -n "$BIOS_LINK_DPP" ]; then _check_dwn_req_resp_uefi=$(curl -L -I -s -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$BIOS_LINK_DPP" -o /dev/null -w "%{http_code}") fi - if [ -v HEADS_LINK_DPP ]; then + + if [ -n "$BIOS_LINK_DPP_CAP" ]; then + _check_dwn_req_resp_uefi_cap=$(curl -L -I -s -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$BIOS_LINK_DPP_CAP" -o /dev/null -w "%{http_code}") + fi + + if [ -n "$HEADS_LINK_DPP" ]; then _check_dwn_req_resp_heads=$(curl -L -I -s -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$HEADS_LINK_DPP" -o /dev/null -w "%{http_code}") fi - if [ -v BIOS_LINK_DPP_SEABIOS ]; then + + if [ -n "$BIOS_LINK_DPP_SEABIOS" ]; then _check_dwn_req_resp_seabios=$(curl -L -I -s -f -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$BIOS_LINK_DPP_SEABIOS" -o /dev/null -w "%{http_code}") fi _check_logs_req_resp=$(curl -L -I -s -f -H "$CLOUD_REQUEST" "$TEST_LOGS_URL" -o /dev/null -w "%{http_code}") # Return 0 if any of Dasharo Firmware binaries is available: - if [ ${_check_dwn_req_resp_uefi} -eq 200 ] || [ ${_check_dwn_req_resp_heads} -eq 200 ] || [ ${_check_dwn_req_resp_seabios} -eq 200 ]; then + if [ ${_check_dwn_req_resp_uefi} -eq 200 ] || [ ${_check_dwn_req_resp_uefi_cap} -eq 200 ] || [ ${_check_dwn_req_resp_heads} -eq 200 ] || [ ${_check_dwn_req_resp_seabios} -eq 200 ]; then if [ ${_check_logs_req_resp} -eq 200 ]; then print_ok "A Dasharo Firmware binary has been found for your platform!" return 0 @@ -61,11 +65,11 @@ check_for_dasharo_firmware() { fi fi - print_warning "Something may be wrong with the DPP credentials or you may not\n - have access to Dasharo Firmware. If so, consider getting Dasharo\n - Subscription and improving security of your platform!" + print_warning "Something may be wrong with the DPP credentials or you may not" + print_warning "have access to Dasharo Firmware. If so, consider getting Dasharo" + print_warning "Subscription and improving security of your platform!" - read -p "Press any key to continue" + read -p "Press enter to continue" return 1 } @@ -80,9 +84,9 @@ get_dpp_creds() { # Export DPP creds to a file for future use. Currently these are being used # for both: MinIO (and its mc CLI) and cloudsend (deprecated, all DPP # sibscribtions will be megrated to MinIO): - echo ${TMP_CLOUDSEND_LOGS_URL} > ${DPP_credential_file} - echo ${TMP_CLOUDSEND_DOWNLOAD_URL} >> ${DPP_credential_file} - echo ${TMP_CLOUDSEND_PASSWORD} >> ${DPP_credential_file} + echo ${TMP_CLOUDSEND_LOGS_URL} > ${DPP_CREDENTIAL_FILE} + echo ${TMP_CLOUDSEND_DOWNLOAD_URL} >> ${DPP_CREDENTIAL_FILE} + echo ${TMP_CLOUDSEND_PASSWORD} >> ${DPP_CREDENTIAL_FILE} print_ok "Dasharo DPP credentials have been saved" } @@ -91,10 +95,6 @@ login_to_dpp_server(){ # Check if the user is already logged in, log in if not: if [ -z "$(mc alias list | grep ${CLOUDSEND_DOWNLOAD_URL})" ]; then if ! mc alias set $DPP_SERVER_USER_ALIAS $DPP_SERVER_ADDRESS $CLOUDSEND_DOWNLOAD_URL $CLOUDSEND_PASSWORD >> $ERR_LOG_FILE 2>&1 ; then - print_error "Your credentials do not have access to DPP packages. If you bought one, check the" - print_error "credentials you have used, and contact support. If you did not buy any DPP" - print_error "packages - feel free to continue." - read -p "Press enter to continue" return 1 fi fi @@ -116,10 +116,10 @@ subscription_routine(){ # Each time the main menu is rendered, check for DPP credentials and export # them, if file exists - if [ -e "${DPP_credential_file}" ]; then - CLOUDSEND_LOGS_URL=$(sed -n '1p' < ${DPP_credential_file} | tr -d '\n') - CLOUDSEND_DOWNLOAD_URL=$(sed -n '2p' < ${DPP_credential_file} | tr -d '\n') - CLOUDSEND_PASSWORD=$(sed -n '3p' < ${DPP_credential_file} | tr -d '\n') + if [ -e "${DPP_CREDENTIAL_FILE}" ]; then + CLOUDSEND_LOGS_URL=$(sed -n '1p' < ${DPP_CREDENTIAL_FILE} | tr -d '\n') + CLOUDSEND_DOWNLOAD_URL=$(sed -n '2p' < ${DPP_CREDENTIAL_FILE} | tr -d '\n') + CLOUDSEND_PASSWORD=$(sed -n '3p' < ${DPP_CREDENTIAL_FILE} | tr -d '\n') export USER_DETAILS="$CLOUDSEND_DOWNLOAD_URL:$CLOUDSEND_PASSWORD" export DPP_IS_LOGGED="true" else diff --git a/include/hal/common-mock-func.sh b/include/hal/common-mock-func.sh new file mode 100644 index 00000000..75158d79 --- /dev/null +++ b/include/hal/common-mock-func.sh @@ -0,0 +1,541 @@ +#!/usr/bin/env bash + +################################################################################ +# Helper functions used in this script: +################################################################################ +parse_for_arg_return_next(){ +# This function parses a list of arguments (given as a second argument), looks +# for a specified argument (given as a first argument). In case the specified +# argument has been found in the list - this function returns (to stdout) the +# argument, which is on the list after specified one, and a return value 0, +# otherwise nothing is being printed to stdout and the return value is 1. +# Arguments: +# 1. The argument you are searching for like -r for flashrom; +# 2. Space-separated list of arguments to search in. + local _arg="$1" + shift + + while [[ $# -gt 0 ]]; do + case $1 in + "$_arg") + [ -n "$2" ] && echo "$2" + + return 0 + ;; + *) + shift + ;; + esac + done + + return 1 +} + +# Mocking part of DTS HAL. For format used for mo mocking functions check +# dts-hal.sh script and tool_wrapper func.. + +################################################################################ +# Common mocking function +################################################################################ +common_mock(){ +# This mocking function is being called for all cases where mocking is needed, +# but the result of mocking function execution is not important. + local _tool="$1" + + echo "${FUNCNAME[0]}: using ${_tool}..." + + return 0 +} + +################################################################################ +# flashrom +################################################################################ +TEST_FLASH_LOCK="${TEST_FLASH_LOCK:-}" +TEST_BOARD_HAS_FD_REGION="${TEST_BOARD_HAS_FD_REGION:-true}" +TEST_BOARD_FD_REGION_RW="${TEST_BOARD_FD_REGION_RW:-true}" +TEST_BOARD_HAS_ME_REGION="${TEST_BOARD_HAS_ME_REGION:-true}" +TEST_BOARD_ME_REGION_RW="${TEST_BOARD_ME_REGION_RW:-true}" +TEST_BOARD_ME_REGION_LOCKED="${TEST_BOARD_ME_REGION_LOCKED:-}" +TEST_BOARD_HAS_GBE_REGION="${TEST_BOARD_HAS_GBE_REGION:-true}" +TEST_BOARD_GBE_REGION_RW="${TEST_BOARD_GBE_REGION_RW:-true}" +TEST_BOARD_GBE_REGION_LOCKED="${TEST_BOARD_GBE_REGION_LOCKED:-}" +TEST_COMPATIBLE_EC_VERSINO="${TEST_COMPATIBLE_EC_VERSINO:-}" +TEST_FLASH_CHIP_SIZE="${TEST_FLASH_CHIP_SIZE:-$((2*1024*1024))}" + +flashrom_check_flash_lock_mock(){ +# For flash lock testing, for more inf. check check_flash_lock func.: + if [ "$TEST_FLASH_LOCK" = "true" ]; then + echo "PR0: Warning:.TEST is read-only" 1>&2 + echo "SMM protection is enabled" 1>&2 + + return 1 + fi + + return 0 +} + +flashrom_flash_chip_name_mock(){ +# For flash chip name check emulation, for more inf. check check_flash_chip +# func.: + echo "Test Flash Chip" + + return 0 +} + +flashrom_flash_chip_size_mock(){ +# For flash chip size check emulation, for more inf. check check_flash_chip +# func.. + echo "$TEST_FLASH_CHIP_SIZE" + + return 0 +} + +flashrom_check_intel_regions_mock(){ +# For flash regions check emulation, for more inf. check check_intel_regions +# func.: + if [ "$TEST_BOARD_HAS_FD_REGION" = "true" ]; then + echo -n "Flash Descriptor region (0x00000000-0x00000fff)" + + if [ "$TEST_BOARD_FD_REGION_RW" = "true" ]; then + echo " is read-write" + else + echo " is read-only" + fi + fi + + if [ "$TEST_BOARD_HAS_ME_REGION" = "true" ]; then + echo -n "Management Engine region (0x00600000-0x00ffffff)" + + if [ "$TEST_BOARD_ME_REGION_RW" = "true" ]; then + echo -n " is read-write" + else + echo -n " is read-only" + fi + + [ "$TEST_BOARD_ME_REGION_LOCKED" = "true" ] && echo -n " and is locked" + echo "" + fi + + if [ "$TEST_BOARD_HAS_GBE_REGION" = "true" ]; then + echo -n "Gigabit Ethernet region (0x00001000-0x00413fff)" + + if [ "$TEST_BOARD_GBE_REGION_RW" = "true" ]; then + echo -n " is read-write" + else + echo -n " is read-only" + fi + + [ "$TEST_BOARD_GBE_REGION_LOCKED" = "true" ] && echo -n " and is locked" + echo "" + fi + + return 0 +} + +flashrom_read_flash_layout_mock(){ +# For checking flash layout for further flashrom arguments selection, for more +# inf. check set_flashrom_update_params function. +# +# TODO: this one can be deleted in future and replaced with read_firm_mock, +# which will create a binary with needed bytes appropriately set. + # For -r check flashrom man page: + local _file_to_write_into + _file_to_write_into=$(parse_for_arg_return_next "-r" "$@") + + [ -f "$_file_to_write_into" ] || echo "Testing..." > "$_file_to_write_into" + + return 0 +} + +flashrom_read_firm_mock(){ +# Emulating dumping of the firmware the platform currently uses. Currently it is +# writing into text file, that should be changed to binary instead (TODO). + # For -r check flashrom man page: + local _file_to_write_into + _file_to_write_into=$(parse_for_arg_return_next "-r" "$@") + + [ -f "$_file_to_write_into" ] || echo "Test flashrom read." > "$_file_to_write_into" + + return 0 +} + +flashrom_get_ec_firm_version_mock(){ +# Emulating wrong EC firmware version, check deploy_ec_firmware func. and +# ec_transition script for more inf.: + if [ -n "$TEST_COMPATIBLE_EC_VERSION" ]; then + echo "Mainboard EC Version: $COMPATIBLE_EC_FW_VERSION" + else + echo "Mainboard EC Version: 0000-00-00-0000000" + fi + + return 0 +} + +################################################################################ +# dasharo_ectool +################################################################################ +TEST_USING_OPENSOURCE_EC_FIRM="${TEST_USING_OPENSOURCE_EC_FIRM:-}" +TEST_NOVACUSTOM_MODEL="${TEST_NOVACUSTOM_MODEL:-}" + +dasharo_ectool_check_for_opensource_firm_mock(){ +# Emulating opensource EC firmware presence, check check_for_opensource_firmware +# for more inf.: + if [ "$TEST_USING_OPENSOURCE_EC_FIRM" = "true" ]; then + return 0 + fi + + return 1 +} + +novacustom_check_sys_model_mock(){ + if [ -n "$TEST_NOVACUSTOM_MODEL" ]; then + echo "Dasharo EC Tool Mock - Info Command" + echo "-----------------------------------" + echo "board: novacustom/$TEST_NOVACUSTOM_MODEL" + echo "version: 0000-00-00_0000000" + echo "-----------------------------------" + + return 0 + fi + + return 1 +} + +################################################################################ +# dmidecode +################################################################################ +TEST_SYSTEM_VENDOR="${TEST_SYSTEM_VENDOR:-}" +TEST_SYSTEM_MODEL="${TEST_SYSTEM_MODEL:-}" +TEST_BOARD_MODEL="${TEST_BOARD_MODEL:-}" +TEST_CPU_VERSION="${TEST_CPU_VERSION:-}" +TEST_BIOS_VENDOR="${TEST_BIOS_VENDOR:-}" +TEST_SYSTEM_UUID="${TEST_SYSTEM_UUID:-}" +TEST_BASEBOARD_SERIAL_NUMBER="${TEST_BASEBOARD_SERIAL_NUMBER:-}" + +dmidecode_common_mock(){ +# Emulating dumping dmidecode inf.: + echo "${FUNCNAME[0]}: using dmidecode..." + + return 0 +} + +dmidecode_dump_var_mock(){ +# Emulating dumping specific dmidecode fields, this is the place where the value +# of the fields are being replaced by those defined by testsuite: + local _option_to_read + _option_to_read=$(parse_for_arg_return_next "-s" "$@") + + case "$_option_to_read" in + system-manufacturer) + + [ -z "$TEST_SYSTEM_VENDOR" ] && return 1 + + echo "$TEST_SYSTEM_VENDOR" + ;; + system-product-name) + + [ -z "$TEST_SYSTEM_MODEL" ] && return 1 + + echo "$TEST_SYSTEM_MODEL" + ;; + baseboard-version) + + [ -z "$TEST_BOARD_MODEL" ] && return 1 + + echo "$TEST_BOARD_MODEL" + ;; + baseboard-product-name) + + [ -z "$TEST_BOARD_MODEL" ] && return 1 + + echo "$TEST_BOARD_MODEL" + ;; + processor-version) + + [ -z "$TEST_CPU_VERSION" ] && return 1 + + echo "$TEST_CPU_VERSION" + ;; + bios-vendor) + + [ -z "$TEST_BIOS_VENDOR" ] && return 1 + + echo "$TEST_BIOS_VENDOR" + ;; + bios-version) + + [ -z "$TEST_BIOS_VERSION" ] && return 1 + + echo "$TEST_BIOS_VERSION" + ;; + system-uuid) + + [ -z "$TEST_SYSTEM_UUID" ] && return 1 + + echo "$TEST_SYSTEM_UUID" + ;; + baseboard-serial-number) + + [ -z "$TEST_BASEBOARD_SERIAL_NUMBER" ] && return 1 + + echo "$TEST_BASEBOARD_SERIAL_NUMBER" + ;; + esac + + return 0 +} + +################################################################################ +# ifdtool +################################################################################ +TEST_ME_OFFSET="${TEST_ME_OFFSET:-}" + +ifdtool_check_blobs_in_binary_mock(){ +# Emulating ME offset value check, check check_blobs_in_binary func. for more +# inf.: + echo "Flash Region 2 (Intel ME): $TEST_ME_OFFSET" + + return 0 +} + +################################################################################ +# cbmem +################################################################################ +TEST_ME_DISABLED="${TEST_ME_DISABLED:-true}" + +cbmem_check_if_me_disabled_mock(){ +# Emulating ME state checked in Coreboot table, check check_if_me_disabled func. +# for more inf.: + if [ "$TEST_ME_DISABLED" = "true" ]; then + echo "ME is disabled" + echo "ME is HAP disabled" + + return 0 + fi + + return 1 +} + +################################################################################ +# cbfstool +################################################################################ +TEST_VBOOT_ENABLED="${TEST_VBOOT_ENABLED:-}" +TEST_ROMHOLE_MIGRATION="${TEST_ROMHOLE_MIGRATION:-}" +TEST_DIFFERENT_FMAP="${TEST_DIFFERENT_FMAP:-}" + +cbfstool_layout_mock(){ +# Emulating some fields in Coreboot Files System layout table: + local _file_to_check="$1" + + echo "This image contains the following sections that can be accessed with this tool:" + echo "" + # Emulating ROMHOLE presence, check romhole_migration function for more inf.: + [ "$TEST_ROMHOLE_MIGRATION" = "true" ] && echo "'ROMHOLE' (test)" + # Emulating difference in Coreboot FS, check function + # set_flashrom_update_params for more inf.: + [ "$TEST_DIFFERENT_FMAP" = "true" ] && [ "$_file_to_check" != "$BIOS_DUMP_FILE" ] && echo "test" + + return 0 +} + +cbfstool_read_romhole_mock(){ +# Emulating reading ROMHOLE section from dumped firmware, check +# romhole_migration func for more inf.: + local _file_to_write_into + _file_to_write_into=$(parse_for_arg_return_next "-f" "$@") + + [ -f "$_file_to_write_into" ] || echo "Testing..." > "$_file_to_write_into" + + return 0 +} + +cbfstool_read_bios_conffile_mock(){ +# Emulating reading bios configuration and some fields inside it. + local _file_to_write_into + _file_to_write_into=$(parse_for_arg_return_next "-f" "$@") + + if [ "$TEST_VBOOT_ENABLED" = "true" ]; then + # Emulating VBOOT presence, check firmware_pre_installation_routine and + # firmware_pre_updating_routine funcs for more inf.: + echo "CONFIG_VBOOT=y" > "$_file_to_write_into" + fi + + echo "" >> "$_file_to_write_into" + + return 0 +} + +################################################################################ +# dmesg +################################################################################ +TEST_TOUCHPAD_ENABLED=${TEST_TOUCHPAD_ENABLED:-} + +dmesg_i2c_hid_detect_mock(){ +# Emulating touchpad presence and name detection, check touchpad-info script for +# more inf.: + if [ "$TEST_TOUCHPAD_ENABLED" = "true" ]; then + echo "hid-multitouch: I2C HID Test" + fi + + return 0 +} + +################################################################################ +# futility +################################################################################ +TEST_DIFFERENT_VBOOT_KEYS=${TEST_DIFFERENT_VBOOT_KEYS:-} + +futility_dump_vboot_keys(){ +# Emulating VBOOT keys difference to trigger GBB region migration, check +# check_vboot_keys func. for more inf.: + _local _file_to_check + _file_to_check=$(parse_for_arg_return_next show "$@") + if [ "$TEST_DIFFERENT_VBOOT_KEYS" = "true" ]; then + [ "$_file_to_check" = "$BIOS_UPDATE_FILE" ] && echo "key sha1sum: Test1" + [ "$_file_to_check" = "$BIOS_DUMP_FILE" ] && echo "key sha1sum: Test2" + fi + + return 0 +} +################################################################################ +# fsread_tool +################################################################################ +TEST_HCI_PRESENT="${TEST_HCI_PRESENT:-}" +TEST_TOUCHPAD_HID="${TEST_TOUCHPAD_HID:-}" +TEST_TOUCHPAD_PATH="${TEST_TOUCHPAD_PATH:-}" +TEST_AC_PRESENT="${TEST_AC_PRESENT:-}" +TEST_MEI_CONF_PRESENT="${TEST_MEI_CONF_PRESENT:-true}" +TEST_INTEL_FUSE_STATUS="${TEST_INTEL_FUSE_STATUS:-0}" + +fsread_tool_common_mock(){ +# This functionn emulates read hardware specific file system resources or its +# metadata. It redirects flow into a tool-specific mocking function, which then +# does needed work. e.g. fsread_tool_test_mock for test tool. + local _tool="$1" + shift + + fsread_tool_${_tool}_mock "$@" + + return $? +} + +fsread_tool_test_mock(){ + local _arg_d + local _arg_f + local _arg_e + _arg_d="$(parse_for_arg_return_next -d "$@")" + _arg_f="$(parse_for_arg_return_next -f "$@")" + _arg_e="$(parse_for_arg_return_next -e "$@")" + + if [ "$_arg_d" = "/sys/class/pci_bus/0000:00/device/0000:00:16.0" ]; then + # Here we emulate the HCI hardware presence checked by function + # check_if_heci_present in dts-hal.sh. Currently it is assumed the HCI is + # assigned to a specific sysfs path (check the condition above): + [ "$TEST_HCI_PRESENT" = "true" ] && return 0 + fi + + if [ "$_arg_f" = "/sys/class/mei/mei0/fw_status" ]; then + # Here we emulate MEI controller status file presence, check check_if_fused + # func for more inf.: + [ "$TEST_MEI_CONF_PRESENT" = "true" ] && return 0 + fi + + if [ "$_arg_e" = "/sys/class/power_supply/AC/online" ]; then + # Emulating AC status file presence, check check_if_ac func. for more inf.: + [ "$TEST_AC_PRESENT" = "true" ] && return 0 + fi + + return 1 +} + +fsread_tool_cat_mock(){ + local _file_to_cat + _file_to_cat="$1" + + # Note, Test folder here comes from dmesg_i2c_hid_detect_mock, which is being + # called before fsread_tool_cat_mock in touchpad-info script: + if [ "$_file_to_cat" = "/sys/bus/i2c/devices/Test/firmware_node/hid" ] && [ -n "$TEST_TOUCHPAD_HID" ]; then + # Used in touchpad-info script. + echo "$TEST_TOUCHPAD_HID" + # Note, Test folder here comes from dmesg_i2c_hid_detect_mock, which is being + # called before fsread_tool_cat_mock in touchpad-info script: + elif [ "$_file_to_cat" = "/sys/bus/i2c/devices/Test/firmware_node/path" ] && [ -n "$TEST_TOUCHPAD_PATH" ]; then + # Used in touchpad-info script. + echo "$TEST_TOUCHPAD_PATH" + elif [ "$_file_to_cat" = "/sys/class/power_supply/AC/online" ]; then + # Emulating AC adadpter presence, used in check_if_ac func.: + if [ "$TEST_AC_PRESENT" = "true" ]; then + echo "1" + else + echo "0" + fi + elif [ "$_file_to_cat" = "/sys/class/mei/mei0/fw_status" ] && [ "$TEST_MEI_CONF_PRESENT" = "true" ]; then + # Emulating MEI firmware status file, for more inf., check check_if_fused + # func.: + echo "smth" + echo "smth" + echo "smth" + echo "smth" + echo "smth" + # Emulating Intel Secure Boot Fuse status, check check_if_fused func. for + # more inf. 4... if fused, and 0 if not: + echo "${TEST_INTEL_FUSE_STATUS}0000000" + echo "smth" + else + echo "${FUNCNAME[0]}: ${_file_to_cat}: No such file or directory" + + return 1 + fi + + return 0 +} + +################################################################################ +# setpci +################################################################################ +TEST_ME_OP_MODE="${TEST_ME_OP_MODE:-0}" + +setpci_check_me_op_mode_mock(){ +# Emulating current ME operation mode, check functions check_if_me_disabled and +# check_me_op_mode: + echo "0$TEST_ME_OP_MODE" + + return 0 +} + +################################################################################ +# lscpu +################################################################################ +TEST_CPU_MODEL="${TEST_CPU_MODEL:-test}" + +lscpu_common_mock(){ +# Emulating CPU model, check update_workflow function. The model should look +# like i5-13409: + echo "12th Gen Intel(R) Core(TM) $TEST_CPU_MODEL" + + return 0 +} +################################################################################ +# rdmsr +################################################################################ +TEST_MSR_CAN_BE_READ="${TEST_MSR_CAN_BE_READ:-true}" +TEST_FPF_PROGRAMMED="${TEST_FPF_PROGRAMMED:-0}" +TEST_VERIFIED_BOOT_ENABLED="${TEST_VERIFIED_BOOT_ENABLED:-0}" + +rdmsr_boot_guard_status_mock(){ + local _bits_8_5="0" + # Emulating MSR accessibility, for more inf. check + # check_if_boot_guard_enabled func.: + [ "$TEST_MSR_CAN_BE_READ" != "true" ] && return 1 + + # Emulating Boot Guard status. 0000000000000000 - FPF not fused and Verified + # Boot disabled, 0000000000000010 - FPF fused and Verified Boot disabled, + # 0000000000000020 - FPF not fused and Verified Boot enabled, 0000000000000030 + # - FPF fused and Verified Boot enabled. For more inf. check + # check_if_boot_guard_enabled func.: + _bits_8_5=$((${_bits_8_5} + ${TEST_FPF_PROGRAMMED} + ${TEST_VERIFIED_BOOT_ENABLED})) + + echo "00000000000000${_bits_8_5}0" + + return 0 +} diff --git a/include/hal/dts-hal.sh b/include/hal/dts-hal.sh new file mode 100644 index 00000000..69e3e45f --- /dev/null +++ b/include/hal/dts-hal.sh @@ -0,0 +1,198 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2024 3mdeb +# +# SPDX-License-Identifier: Apache-2.0 +# +# This is a Hardware Abstraction Layer for DTS. The goal of this layer - +# separate all hardware-related code from DTS code to improve readability, +# scalability and testing. +# +# For testing, every hardware-specific tool must utilize DTS_TESTING +# variable, which is declared in dts-environment and set by user. If DTS_TESTING +# is not "true" - HAL communicates with hardware and firmware via specific tools +# otherwise it uses mocking functions and tool_wrapper to emulate behaviour of +# some of the tools. +# +# Real HAL is placed in $DTS_HAL* (* means that, apart from common HAL funcs. +# there could be, in future, files with platform-specific HAL funcs) and the +# Tests HAL is placed in $DTS_MOCK* (* means that, apart from common mocks, +# there could be, in future, files with platform-specific mocking functions). + +# shellcheck disable=SC2034 + +# shellcheck source=../../include/hal/common-mock-func.sh +source $DTS_MOCK_COMMON + +# Set tools wrappers: +DASHARO_ECTOOL="tool_wrapper dasharo_ectool" +FLASHROM="tool_wrapper flashrom" +DMIDECODE="tool_wrapper dmidecode" +IFDTOOL="tool_wrapper ifdtool" +SETPCI="tool_wrapper setpci" +# Emulating to eliminate false negatives, because it might fail on QEMU: +CBMEM="tool_wrapper cbmem" +CBFSTOOL="tool_wrapper cbfstool" +# Emulating to eliminate false negatives, because it fails on QEMU: +SUPERIOTOOL="tool_wrapper superiotool" +# Emulating to eliminate false negatives, because it fails on QEMU: +ECTOOL="tool_wrapper ectool" +# Emulating to eliminate false negatives, because it fails on QEMU: +MSRTOOL="tool_wrapper msrtool" +# Emulating to eliminate false negatives, because it fails on QEMU: +MEI_AMT_CHECK="tool_wrapper mei-amt-check" +# Emulating to eliminate false negatives, because it fails on QEMU: +INTELMETOOL="tool_wrapper intelmetool" +# Emulating, so no to probe every time testing is done +HW_PROBE="tool_wrapper hw-probe" +DMESG="tool_wrapper dmesg" +DCU="tool_wrapper dcu" +FUTILITY="tool_wrapper futility" +IOTOOLS="tool_wrapper iotools" +FSREAD_TOOL="tool_wrapper fsread_tool" +CAP_UPD_TOOL="tool_wrapper cap_upd_tool" +LSCPU="tool_wrapper lscpu" +# System commands: +POWEROFF="tool_wrapper poweroff" +REBOOT="tool_wrapper reboot" +RDMSR="tool_wrapper rdmsr" + +################################################################################ +# Tools wrapper. +################################################################################ +tool_wrapper(){ +# Usage: tool_wrapper TOOL_NAME MOCK_FUNC_NAME TOOL_ARGS +# +# TOOL_NAME: the name of the tool being wrapped +# MOCK_FUNC_NAME: the name of mocking function (optional, check comments +# below for more inf.) +# TOOL_ARGS: the arguments that the tool gets if being called, for example +# for dmidecode -s system-vendor it will be "-s system-vendor". +# +# This function is a bridge between common DTS logic and hardware-specific DTS +# logic or functions. There is two paths a call to this function can be +# redirected to: real HAL for running on real platform and Tests HAL for testing +# on QEMU (depends on whether the var. DTS_TESTING is set or not). +# +# The real HAL are the real tools e.g. cbfstool, etc.. The testing HAL are the +# mocking functions. There are several types of mocking functions, with every +# type having a specific name syntax: +# +# FUNCTIONNAME_mock(){...}: mocking functions specific for every platform, those +# are stored in $DTS_MOCK_PLATFORM file which is sourced at the beginning of +# this file. +# TOOLNAME_FUNCTIONNAME_mock(){...}: mocking functions common for all platforms +# but specific for some tool, those are stored in $DTS_MOCK_COMMON file, which +# is being sourced at the beginning of this file. +# TOOLNAME_common_mock(){...}: standard mocking functions for every tool that +# are common for all platforms, those are stored in $DTS_MOCK_COMMON file, which +# is being sourced at the beginning of this file. +# common_mock(){...}: common mocking function, in case we need to use mocking +# function for a tool but we do not care about its output. +# +# This tool wrapper should only be used with tools which communicate with +# hardware or firmware (read or write, etc.). +# +# TODO: this wrapper deals with arguments as well as with stdout, stderr, and $? +# redirection, but it does not read and redirect stdin (this is not used in any +# mocking functions or tools right now). + # Gets toolname, e.g. poweroff, dmidecode. etc.: + local _tool="$1" + # Gets mocking function name: + local _mock_func="$2" + # It checks if _mock_func contains smth with _mock at the end, if not - + # mocking function is not provided and some common mocking func. will be used + # instead: + if ! echo "$_mock_func" | grep "_mock" &> /dev/null; then + unset _mock_func + shift 1 + else + shift 2 + fi + # Other arguments for this function are the arguments which are sent to a tool + # e.g. -s system-vendor for dmidecode, etc.: + local _arguments=( "$@" ) + + if [ -n "$DTS_TESTING" ]; then + # This is the order of calling mocking functions: + # 1) FUNCTIONNAME_mock; + # 2) TOOLNAME_FUNCTIONNAME_mock; + # 3) TOOLNAME_common_mock; + # 4) common_mock - last resort. + if [ -n "$_mock_func" ] && type $_mock_func &> /dev/null; then + $_mock_func "${_arguments[@]}" + elif type ${_tool}_${_mock_func} &> /dev/null; then + ${_tool}_${_mock_func} "${_arguments[@]}" + elif type ${_tool}_common_mock &> /dev/null; then + ${_tool}_common_mock "${_arguments[@]}" + else + common_mock $_tool + fi + + return $? + fi + + # If not testing - call tool with the arguments instead: + $_tool "${_arguments[@]}" + + return $? +} + +################################################################################ +# Other funcs. +################################################################################ +check_for_opensource_firmware() +{ + echo "Checking for Open Source Embedded Controller firmware..." + $DASHARO_ECTOOL check_for_opensource_firm_mock info > /dev/null 2>&1 + + return $? +} + +fsread_tool(){ +# This func is an abstraction for proper handling of fs hardware-specific (e.g. +# checking devtmpfs, or sysfs, or some other fs that changes its state due to +# changes in hardware and/or firmware) reads by tool_wrapper. +# +# This function does not have arguments in common understanding, it takes a +# command, that is reading smth from some fs, and its arguments as an only +# argument. E.g. if you want to check tty1 device presence: +# +# fsread_tool test -f /dev/tty1 + local _command="$1" + shift + + $_command "$@" + + return $? +} + +cap_upd_tool(){ +# This func is an abstraction for proper handling of UEFI Capsule Update driver +# writing by the tool_wrapper. arguments: capsule update file path, e.g.: +# +# capsule_update_tool /tmp/firm.cap + local _capsule="$1" + + cat "$_capsule" > "$CAP_UPD_DEVICE" + + return $? +} + +check_if_heci_present(){ +# FIXME: what if HECI is not device 16.0? + $FSREAD_TOOL test_mock test -d /sys/class/pci_bus/0000:00/device/0000:00:16.0 + + return $? +} + +check_me_op_mode(){ +# Checks ME Current Operation Mode at offset 0x40 bits 19:16: + local _mode + + _mode="$($SETPCI check_me_op_mode_mock -s 00:16.0 42.B 2> /dev/null | cut -c2-)" + + echo "$_mode" + + return 0 +} diff --git a/reports/dasharo-hcl-report b/reports/dasharo-hcl-report old mode 100755 new mode 100644 index d27adb86..4ccf385f --- a/reports/dasharo-hcl-report +++ b/reports/dasharo-hcl-report @@ -8,6 +8,8 @@ source $DTS_ENV # shellcheck source=../include/dts-functions.sh source $DTS_FUNCS +# shellcheck source=../include/hal/dts-hal.sh +source $DTS_HAL update_result() { TOOL=$1 @@ -15,7 +17,7 @@ update_result() { LOGFILE=`printf $2 | sed 's/[.].*$//' && echo ".log"` # check if status was set as a unknown - if [ ! -v $3 ]; then + if [ -z "$3" ]; then echo -e [$YELLOW"UNKNOWN"$NORMAL]"\t"$TOOL >> result return fi @@ -50,8 +52,6 @@ update_result() { fi } -CMD_DASHARO_DEPLOY="/usr/sbin/dasharo-deploy" - if [ "$(id -u)" -ne 0 ]; then echo "This script must be started as root!" exit 1 @@ -63,39 +63,37 @@ fi FULL_UPLOAD_URL="https://cloud.3mdeb.com/index.php/s/"${CLOUDSEND_LOGS_URL} -check_flash_chip - mkdir logs if [ $DEPLOY_REPORT = "false" ]; then echo "Getting hardware information. It will take a few minutes..." fi # echo "Dumping PCI configuration space and topology..." -lspci -nnvvvxxxx > logs/lspci.log 2> logs/lspci.err.log +$LSPCI -nnvvvxxxx > logs/lspci.log 2> logs/lspci.err.log update_result "PCI configuration space and topology" logs/lspci.err.log printf '## |\r' # echo "Dumping USB devices and topology..." -lsusb -vvv > logs/lsusb.log 2> logs/lsusb.err.log +$LSUSB -vvv > logs/lsusb.log 2> logs/lsusb.err.log update_result "USB devices and topology" logs/lsusb.err.log printf '#### |\r' # echo "Dumping Super I/O configuration..." -superiotool -deV > logs/superiotool.log 2> logs/superiotool.err.log +$SUPERIOTOOL -deV > logs/superiotool.log 2> logs/superiotool.err.log update_result "Super I/O configuration" logs/superiotool.err.log printf '###### |\r' # echo "Dumping Embedded Controller configuration (this may take a while if EC is not present)..." -ectool -ip > logs/ectool.log 2> logs/ectool.err.log +$ECTOOL -ip > logs/ectool.log 2> logs/ectool.err.log update_result "EC configuration" logs/ectool.err.log printf '######## |\r' # echo "Dumping MSRs..." -msrtool > logs/msrtool.log 2> logs/msrtool.err.log +$MSRTOOL > logs/msrtool.log 2> logs/msrtool.err.log update_result "MSRs" logs/msrtool.err.log printf '########## |\r' # echo "Dumping SMBIOS tables..." -dmidecode > logs/dmidecode.log 2> logs/dmidecode.err.log +$DMIDECODE > logs/dmidecode.log 2> logs/dmidecode.err.log update_result "SMBIOS tables" logs/dmidecode.err.log printf '############ |\r' @@ -123,12 +121,12 @@ update_result "GPIO configuration C header files" logs/intelp2m.err.log printf '#################### |\r' # echo "Dumping kernel dmesg..." -dmesg > logs/dmesg.log 2> logs/dmesg.err.log +$DMESG > logs/dmesg.log 2> logs/dmesg.err.log update_result "kernel dmesg" logs/dmesg.err.log printf '###################### |\r' # echo "Dumping ACPI tables..." -acpidump > logs/acpidump.log 2> logs/acpidump.err.log +$ACPIDUMP > logs/acpidump.log 2> logs/acpidump.err.log update_result "ACPI tables" logs/acpidump.err.log printf '######################## |\r' @@ -175,34 +173,39 @@ cat /sys/class/input/input*/id/bustype > logs/input_bustypes.log update_result "Input bus types" logs/ioports.err.log printf '################################ |\r' -# echo "Trying to read firmware image with flashrom..." -# Some regions may be not available so we need to use specific regions to read -check_intel_regions -if [ $BOARD_HAS_FD_REGION -eq 1 ]; then - # Use safe defaults. Descriptor may contain additional regions not detected - # by flashrom and will return failure when attempted to be read. BIOS and - # Flash descriptor regions should always be readable. If not, then we have - # some ugly case, hard to deal with. - FLASHROM_ADD_OPT_READ="--ifd -i fd -i bios" - if [ $BOARD_HAS_ME_REGION -eq 1 ] && [ $BOARD_ME_REGION_LOCKED -eq 0 ]; then - # ME region is not locked, read it as well - FLASHROM_ADD_OPT_READ+=" -i me" - fi - if [ $BOARD_HAS_GBE_REGION -eq 1 ] && [ $BOARD_GBE_REGION_LOCKED -eq 0 ]; then - # GBE region is present and not locked, read it as well - FLASHROM_ADD_OPT_READ+=" -i gbe" - fi +# flashrom does not support QEMU. TODO: this could be handled in a better way: +if [ "${SYSTEM_VENDOR}" != "QEMU" ] && [ "${SYSTEM_VENDOR}" != "Emulation" ]; then + check_flash_chip + check_intel_regions + + # echo "Trying to read firmware image with flashrom..." + # Some regions may be not available so we need to use specific regions to read + if [ $BOARD_HAS_FD_REGION -eq 1 ]; then + # Use safe defaults. Descriptor may contain additional regions not detected + # by flashrom and will return failure when attempted to be read. BIOS and + # Flash descriptor regions should always be readable. If not, then we have + # some ugly case, hard to deal with. + FLASHROM_ADD_OPT_READ="--ifd -i fd -i bios" + if [ $BOARD_HAS_ME_REGION -eq 1 ] && [ $BOARD_ME_REGION_LOCKED -eq 0 ]; then + # ME region is not locked, read it as well + FLASHROM_ADD_OPT_READ+=" -i me" + fi + if [ $BOARD_HAS_GBE_REGION -eq 1 ] && [ $BOARD_GBE_REGION_LOCKED -eq 0 ]; then + # GBE region is present and not locked, read it as well + FLASHROM_ADD_OPT_READ+=" -i gbe" + fi else - # No descriptor, probably safe to read everything - FLASHROM_ADD_OPT_READ="" -fi + # No descriptor, probably safe to read everything + FLASHROM_ADD_OPT_READ="" + fi -$FLASHROM -V -p internal:laptop=force_I_want_a_brick ${FLASH_CHIP_SELECT} -r logs/rom.bin ${FLASHROM_ADD_OPT_READ} > logs/flashrom_read.log 2> logs/flashrom_read.err.log -if [ $? -ne 0 ]; then - echo "CRITICAL ERROR: cannot dump firmware" + $FLASHROM -V -p internal:laptop=force_I_want_a_brick ${FLASH_CHIP_SELECT} -r logs/rom.bin ${FLASHROM_ADD_OPT_READ} > logs/flashrom_read.log 2> logs/flashrom_read.err.log + if [ $? -ne 0 ]; then + echo "CRITICAL ERROR: cannot dump firmware" + fi + update_result "Firmware image" logs/flashrom_read.err.log + printf '################################## |\r' fi -update_result "Firmware image" logs/flashrom_read.err.log -printf '################################## |\r' # echo "Probing all I2C buses..." MAX_I2C_ID=$(i2cdetect -l | awk 'BEGIN{c1=0} //{c1++} END{print "",--c1}') @@ -235,12 +238,12 @@ update_result "DIMMs information" logs/decode-dimms.err.log printf '########################################## |\r' # echo "Getting CBMEM table..." -cbmem > logs/cbmem.log 2> logs/cbmem.err.log +$CBMEM > logs/cbmem.log 2> logs/cbmem.err.log update_result "CBMEM table information" logs/cbmem.err.log printf '############################################ |\r' # echo "Getting CBMEM console..." -cbmem -1 > logs/cbmem_console.log 2> logs/cbmem_console.err.log +$CBMEM -1 > logs/cbmem_console.log 2> logs/cbmem_console.err.log update_result "CBMEM console" logs/cbmem_console.err.log printf '############################################## |\r' @@ -250,12 +253,12 @@ update_result "TPM information" logs/tpm_version.err.log printf '################################################ |\r' # echo "Checking AMT..." -mei-amt-check > logs/amt-check.log 2> logs/amt-check.err.log +$MEI_AMT_CHECK > logs/amt-check.log 2> logs/amt-check.err.log update_result "AMT information" logs/amt-check.err.log printf '################################################## |\r' # echo "Checking ME..." -intelmetool -m > logs/intelmetool.log 2> logs/intelmetool.err.log +$INTELMETOOL -m > logs/intelmetool.log 2> logs/intelmetool.err.log update_result "ME information" logs/intelmetool.err.log printf '##################################################### |\r' @@ -289,9 +292,9 @@ if [ $DEPLOY_REPORT = "false" ]; then fi # Create name for generated report -filename="$(dmidecode -s system-manufacturer)" -filename+=" $(dmidecode -s system-product-name)" -filename+=" $(dmidecode -s bios-version)" +filename="$($DMIDECODE dump_var_mock -s system-manufacturer)" +filename+=" $($DMIDECODE dump_var_mock -s system-product-name)" +filename+=" $($DMIDECODE dump_var_mock -s bios-version)" # MAC address of device that is used to connect the internet # it could return none only when there is no internet connection but @@ -301,8 +304,8 @@ filename+=" $(dmidecode -s bios-version)" # shellcheck disable=SC2046 uuid_string="$(cat /sys/class/net/$(ip route show default | head -1 | awk '/default/ {print $5}')/address)" # next two values are hardware related so they will be always the same -uuid_string+="_$(dmidecode -s system-product-name)" -uuid_string+="_$(dmidecode -s system-manufacturer)" +uuid_string+="_$($DMIDECODE dump_var_mock -s system-product-name)" +uuid_string+="_$($DMIDECODE dump_var_mock -s system-manufacturer)" # using values from above should generate the same uuid all the time if only # the MAC address will not change. @@ -373,7 +376,7 @@ order to participate)\r read -p "[N/y] " case ${REPLY} in yes|y|Y|Yes|YES) - /usr/bin/hw-probe -all -upload + $HW_PROBE -all -upload if [ $? -eq 0 ]; then echo "Thank you for contributing to the \"Hardware for Linux\" project!" else diff --git a/reports/touchpad-info b/reports/touchpad-info index 00ddabdf..e14492d6 100644 --- a/reports/touchpad-info +++ b/reports/touchpad-info @@ -7,14 +7,17 @@ # A script to get information on the touchpad devices. Currently supports only # Clevo devices. -if ! dmesg | grep hid-multitouch | grep "I2C HID" > /dev/null; then +# shellcheck source=../include/hal/dts-hal.sh +source $DTS_HAL + +if ! $DMESG i2c_hid_detect_mock | grep hid-multitouch | grep "I2C HID" > /dev/null; then echo "No I2C touchpads detected. Exiting" exit 2 fi -devname=$(dmesg | grep hid-multitouch | awk 'NF>1{print $NF}') -hid=$(cat "/sys/bus/i2c/devices/$devname/firmware_node/hid") -path=$(cat "/sys/bus/i2c/devices/$devname/firmware_node/path") +devname=$($DMESG i2c_hid_detect_mock | grep hid-multitouch | awk 'NF>1{print $NF}') +hid=$($FSREAD_TOOL cat "/sys/bus/i2c/devices/$devname/firmware_node/hid") +path=$($FSREAD_TOOL cat "/sys/bus/i2c/devices/$devname/firmware_node/path") ACPI_CALL_PATH="/proc/acpi/call" diff --git a/scripts/cloud_list b/scripts/cloud_list old mode 100755 new mode 100644 diff --git a/scripts/dasharo-deploy b/scripts/dasharo-deploy old mode 100755 new mode 100644 index 56169253..64b2d865 --- a/scripts/dasharo-deploy +++ b/scripts/dasharo-deploy @@ -4,90 +4,191 @@ # # SPDX-License-Identifier: Apache-2.0 +# Some variables (especially those with hashes, are being used by functions in +# dts-functions.sh only, shellcheck is unaware of them and marks them as +# unused.) +# shellcheck disable=SC2034 + # shellcheck source=../include/dts-environment.sh source $DTS_ENV # shellcheck source=../include/dts-functions.sh source $DTS_FUNCS +# shellcheck source=../include/hal/dts-hal.sh +source $DTS_HAL [ -z "$SYSTEM_VENDOR" ] && error_exit "SYSTEM_VENDOR not given" [ -z "$SYSTEM_MODEL" ] && error_exit "SYSTEM_MODEL not given" +# Variables used in this script: +# Currently following firmware versions are available: community, community_cap, +# dpp, dpp_cap, seabios, and heads: +declare FIRMWARE_VERSION +declare CAN_SWITCH_TO_HEADS CMD="$1" FUM="$2" +print_firm_access_warning() { +# This function prints standard warning informing user that a specific DPP +# firmware is available but he does not have access to it. Arguments: dpp, +# dpp_cap, seabios, and heads: + local _firm_type="$1" + local _firm_type_print + + case $_firm_type in + dpp) + _firm_type_print="coreboot + UEFI" + ;; + dpp_cap) + _firm_type_print="coreboot + UEFI via Capsule Update" + ;; + seabios) + _firm_type_print="coreboot + SeaBIOS" + ;; + heads) + _firm_type_print="coreboot + Heads" + ;; + *) + return 1 + ;; + esac + + print_warning " DPP version (${_firm_type_print}) available but you don't have access" + print_warning " to it, if you are interested, please visit" + print_warning " https://shop.3mdeb.com/product-category/dasharo-pro-package/" + # Just a new line: + echo + + return 0 +} + +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. There +# are community and DPP firmwares with UEFI Capsule Update support, but they are +# for firmware updates only, but this function is being called during +# installation, so no need to mention them here. + local _option + local _might_be_comm + local _might_be_dpp + local _might_be_seabios + while : ; do echo - echo "Please, select Dasharo firmware version to install" + echo "Please, select Dasharo firmware version to install:" + echo - # -v: True if the shell variable varname is set (has been assigned a value). - if [ -v BIOS_HASH_LINK_COMM ]; then - echo " c) Community version" + # Here we check if user has access to a certain version of Dasharo Firmware. + # The check consists of two stages: + # * does user platform support the firmware - BIOS_LINK_* variables are + # being checked; + # * does user has access rights to the blobs of the supported firmware - a + # call to the server with binaries is done, to check if user can download + # the blobs. + if [ -n "$BIOS_LINK_COMM" ]; then + if check_for_firmware_access community; then + echo " c) Community version" + _might_be_comm="true" + fi fi - if [ -v BIOS_HASH_LINK_DPP ]; then - if [ -v DPP_IS_LOGGED ]; then + + if [ -n "$BIOS_LINK_DPP" ]; 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/" + print_firm_access_warning dpp fi fi - if [ -v BIOS_HASH_LINK_DPP_SEABIOS ]; then - if [ -v DPP_IS_LOGGED ]; then + + if [ -n "$BIOS_LINK_DPP_SEABIOS" ]; 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/" + print_firm_access_warning seabios 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 + # In case of several Dasharo Firmware versions supported we leave the + # decision to user: + case ${_option} in c|C|comm|community|COMMUNITY|COMM|Community) - if [ -v BIOS_HASH_LINK_COMM ]; then - BIOS_LINK=$BIOS_LINK_COMM - BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM - BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM - if [ -v EC_HASH_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 + print_ok "Community (Coreboot + EDK2) version selected" + FIRMWARE_VERSION="community" + break + fi + ;; d|D|dpp|DPP|Dpp) - if [ -v BIOS_HASH_LINK_DPP ]; then - BIOS_LINK=$BIOS_LINK_DPP - BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP - BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP - if [ -v EC_HASH_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 + print_ok "Subscription version (cooreboot + EDK2) selected" + FIRMWARE_VERSION="dpp" + break + fi + ;; s|S|sea|seabios|SeaBIOS) - if [ -v BIOS_HASH_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 + print_ok "Subscription version (coreboot + SeaBIOS) selected" + FIRMWARE_VERSION="seabios" + break + fi + ;; b|B) echo "Returning to main menu..." exit 0 @@ -96,32 +197,208 @@ ask_for_version() { ;; esac done + + return 0 +} + +choose_version(){ +# This function is used for determining Dasharo firmware update version and is +# being used during updates only. We do not ask user to choose firmware update +# versions compared to installation workflow (check ask_for_version function), +# instead we have some priorities: +# 1) Check if Dasharo Heads Firmware available, use it if yes; +# 2) Check if Dasharo EDK2 Firmware available, use it if yes; +# 3) Use Dasharo Community Firmware; +# +# Capsules have higher priority over simple binaries. +# +# TODO: Currently we do not have clear and concise update mechanisms (e.g. what +# and when a specific firmware version can be used, how to handle revisions of +# firmware). + + if [ "$HAVE_HEADS_FW" == "true" ]; then + if check_for_firmware_access heads; then + CAN_SWITCH_TO_HEADS="true" + FIRMWARE_VERSION="heads" + + return 0 + else + print_firm_access_warning heads + fi + fi + + if [ -n "$DASHARO_REL_VER_DPP_CAP" ]; then + [ -z "$DASHARO_SUPPORT_CAP_FROM" ] && print_error "Variable DASHARO_SUPPORT_CAP_FROM must be set!" + + # Check, whether currently installed firmware supports Capsule Update ( + # check comments for DASHARO_SUPPORT_CAP_FROM in dts-environment.sh for more + # inf): + if compare_versions "$DASHARO_VERSION" "$DASHARO_SUPPORT_CAP_FROM" ; then + if check_for_firmware_access dpp_cap; then + FIRMWARE_VERSION="dpp_cap" + + return 0 + else + print_firm_access_warning dpp_cap + fi + fi + fi + + if [ -n "$DASHARO_REL_VER_DPP" ]; then + if check_for_firmware_access dpp; then + FIRMWARE_VERSION="dpp" + + return 0 + else + print_firm_access_warning dpp + fi + fi + + if [ -n "$DASHARO_REL_VER_CAP" ]; then + [ -z "$DASHARO_SUPPORT_CAP_FROM" ] && print_error "Variable DASHARO_SUPPORT_CAP_FROM must be set!" + + # Check, whether currently installed firmware supports Capsule Update ( + # check comments for DASHARO_SUPPORT_CAP_FROM in dts-environment.sh for more + # inf): + if compare_versions "$DASHARO_VERSION" "$DASHARO_SUPPORT_CAP_FROM" ; then + FIRMWARE_VERSION="community_cap" + + return 0 + fi + fi + + # Last resort: + FIRMWARE_VERSION="community" + + return 0 +} + +prepare_env() { +# This function sets all needed variables after user have answered all needed +# questions and before this script does any work. + local _prepare_for + _prepare_for="$1" + + # If firmware is being installed - user should choose what to install, if + # firmware is being updated - final version is being chosen automatically + if [ "$_prepare_for" == "update" ]; then + choose_version + elif [ "$_prepare_for" == "install" ]; then + ask_for_version + fi + + # This is the key variable for this function, should be set either by + # choose_version or by ask_for_version: + if [ -z "$FIRMWARE_VERSION" ]; then + 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 decide which links to use (some + # platforms may support several firmware types). The links being used are + # determined bising on FIRMWARE_VERSION: + if [ "$FIRMWARE_VERSION" == "community" ]; then + BIOS_LINK=$BIOS_LINK_COMM + BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM + + UPDATE_VERSION="$DASHARO_REL_VER" + + # Check EC link additionally, not all platforms have Embedded Controllers: + 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 + + return 0 + elif [ "$FIRMWARE_VERSION" == "community_cap" ]; then + BIOS_LINK=$BIOS_LINK_COMM_CAP + BIOS_HASH_LINK=$BIOS_HASH_LINK_COMM_CAP + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM_CAP + + UPDATE_VERSION="$DASHARO_REL_VER_CAP" + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -n "$EC_LINK_COMM_CAP" ]; then + EC_LINK=$EC_LINK_COMM_CAP + EC_HASH_LINK=$EC_HASH_LINK_COMM_CAP + EC_SIGN_LINK=$EC_SIGN_LINK_COMM_CAP + fi + + return 0 + elif [ "$FIRMWARE_VERSION" == "dpp" ]; then + BIOS_LINK=$BIOS_LINK_DPP + BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP + + UPDATE_VERSION="$DASHARO_REL_VER_DPP" + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -n "$EC_LINK_DPP" ]; then + EC_LINK=$EC_LINK_DPP + EC_HASH_LINK=$EC_HASH_LINK_DPP + EC_SIGN_LINK=$EC_SIGN_LINK_DPP + fi + + return 0 + elif [ "$FIRMWARE_VERSION" == "dpp_cap" ]; then + BIOS_LINK=$BIOS_LINK_DPP_CAP + BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP_CAP + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP_CAP + + UPDATE_VERSION="$DASHARO_REL_VER_DPP_CAP" + + # Check EC link additionally, not all platforms have Embedded Controllers: + if [ -n "$EC_LINK_DPP_CAP" ]; then + EC_LINK=$EC_LINK_DPP_CAP + EC_HASH_LINK=$EC_HASH_LINK_DPP_CAP + EC_SIGN_LINK=$EC_SIGN_LINK_DPP_CAP + fi + + return 0 + elif [ "$FIRMWARE_VERSION" == "seabios" ]; then + BIOS_LINK=$BIOS_LINK_DPP_SEABIOS + BIOS_HASH_LINK=$BIOS_HASH_LINK_DPP_SEABIOS + BIOS_SIGN_LINK=$BIOS_SIGN_LINK_DPP_SEABIOS + + return 0 + fi + + # Must not get here. If it gets here - the above variables are empty and + # script will not be able to continue. + return 1 } -display_flashing_warning() { +display_warning() { +# This function shows user some inf. about platform and binaries and asks if the +# deployment process should be continued. + local _option + while : ; do echo print_warning "Please verify detected hardware!" echo - if [ -v SYSTEM_VENDOR ]; then + if [ -n "$SYSTEM_VENDOR" ]; then echo "Board vendor: $SYSTEM_VENDOR" fi - if [ -v SYSTEM_MODEL ]; then + if [ -n "$SYSTEM_MODEL" ]; then echo "System model: $SYSTEM_MODEL" fi - if [ -v BOARD_MODEL ]; then + if [ -n "$BOARD_MODEL" ]; then echo "Board model: $BOARD_MODEL" fi + echo - read -r -p "Does it match your actual specification? (Y|n) " OPTION + read -r -p "Does it match your actual specification? (Y|n) " _option echo - case ${OPTION} in + case ${_option} in ""|yes|y|Y|Yes|YES) break ;; - n|N) + n|N|no|NO|No) echo "Returning to main menu..." exit 0 ;; @@ -131,44 +408,44 @@ display_flashing_warning() { done while : ; do - echo "Following firmware will be used to install Dasharo" - if [ -v BIOS_HASH_LINK ]; then + echo "Following firmware will be used to deploy Dasharo:" + + if [ -n "$BIOS_LINK" ]; then local _bios_hash _bios_hash="$(cat $BIOS_HASH_FILE | cut -d ' ' -f 1)" echo "Dasharo BIOS firmware:" echo " - link: $BIOS_LINK" echo " - hash: $_bios_hash" fi - if [ -v EC_HASH_LINK ]; then + + if [ -n "$EC_LINK" ]; then local _ec_hash _ec_hash="$(cat $EC_HASH_FILE | cut -d ' ' -f 1)" echo "Dasharo EC firmware:" echo " - link: $EC_LINK" echo " - hash: $_ec_hash" fi + echo echo "You can learn more about this release on: https://docs.dasharo.com/" - if check_if_dasharo; then - echo - read -r -p "Do you want to update Dasharo firmware on your hardware? (Y|n) " OPTION - echo - else - echo - if [ "$CAN_INSTALL_BIOS" == "false" ] && [ "$SYSTEM_VENDOR" == "Notebook" ]; then - echo "Notebook supports installation of only EC firmware!" - echo "Dasharo BIOS will have to be flashed manually. More on:" - echo "https://docs.dasharo.com/unified/novacustom/initial-deployment/" - fi - read -r -p "Do you want to install Dasharo firmware on your hardware? (Y|n) " OPTION - echo + if ! check_if_dasharo && \ + [ "$CAN_INSTALL_BIOS" = "false" ] && \ + [ "$HAVE_EC" = "true" ]; then + print_warning "$SYSTEM_VENDOR $SYSTEM_MODEL supports only EC firmware deployment!" + print_warning "Dasharo BIOS will have to be flashed manually. More on:" + print_warning "https://docs.dasharo.com/unified/novacustom/initial-deployment/" fi - case ${OPTION} in + echo + read -r -p "Do you want to deploy this Dasharo Firmware on your platform (Y|n) " _option + echo + + case ${_option} in ""|yes|y|Y|Yes|YES) break ;; - n|N) + n|N|no|NO|No) echo "Returning to main menu..." exit 0 ;; @@ -176,6 +453,8 @@ display_flashing_warning() { ;; esac done + + return 0 } backup() { @@ -203,17 +482,15 @@ backup() { # No descriptor, probably safe to read everything FLASHROM_ADD_OPT_READ="" fi - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} -r "${FW_BACKUP_DIR}"/rom.bin ${FLASHROM_ADD_OPT_READ} >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + $FLASHROM read_firm_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} -r "${FW_BACKUP_DIR}"/rom.bin ${FLASHROM_ADD_OPT_READ} >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE error_check "Failed to read BIOS firmware backup" if [ "$HAVE_EC" == "true" ]; then - echo "Checking for Open Source Embedded Controller firmware" - $DASHARO_ECTOOL info >> $ERR_LOG_FILE 2>&1 - if [ $? -eq 0 ]; then + if check_for_opensource_firmware; then echo "Device has already Open Source Embedded Controller firmware, do not backup EC..." else echo "Backing up EC firmware..." - $FLASHROM -p "$PROGRAMMER_EC" ${FLASH_CHIP_SELECT} -r "${FW_BACKUP_DIR}"/ec.bin >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + $FLASHROM read_firm_mock -p "$PROGRAMMER_EC" ${FLASH_CHIP_SELECT} -r "${FW_BACKUP_DIR}"/ec.bin >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE error_check "Failed to read EC firmware backup" fi fi @@ -227,14 +504,14 @@ backup() { } romhole_migration() { - cbfstool $BIOS_UPDATE_FILE layout -w | grep -q "ROMHOLE" || return + $CBFSTOOL layout_mock $BIOS_UPDATE_FILE layout -w | grep -q "ROMHOLE" || return - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} -r /tmp/rom.bin --ifd -i bios >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + $FLASHROM read_firm_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} -r /tmp/rom.bin --ifd -i bios >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE error_check "Failed to read current firmware to migrate MSI ROMHOLE" if check_if_dasharo; then - cbfstool /tmp/rom.bin layout -w | grep -q "ROMHOLE" || return + $CBFSTOOL layout_mock /tmp/rom.bin layout -w | grep -q "ROMHOLE" || return # This one is rather unlikely to fail, but just in case print a warning - cbfstool /tmp/rom.bin read -r ROMHOLE -f /tmp/romhole.bin 2> /dev/null + $CBFSTOOL read_romhole_mock /tmp/rom.bin read -r ROMHOLE -f /tmp/romhole.bin 2> /dev/null if [ $? -ne 0 ]; then print_warning "Failed to migrate MSI ROMHOLE, your platform's unique SMBIOS/DMI data may be lost" return @@ -243,59 +520,59 @@ romhole_migration() { dd if=/tmp/rom.bin of=/tmp/romhole.bin skip=$((0x17C0000)) bs=128K count=1 iflag=skip_bytes > /dev/null 2>&1 fi - cbfstool "$BIOS_UPDATE_FILE" write -r ROMHOLE -f /tmp/romhole.bin -u 2> /dev/null + $CBFSTOOL "$BIOS_UPDATE_FILE" write -r ROMHOLE -f /tmp/romhole.bin -u 2> /dev/null } smbios_migration() { - echo -n "$(dmidecode -s system-uuid)" > $SYSTEM_UUID_FILE - echo -n "$(dmidecode -s baseboard-serial-number)" > $SERIAL_NUMBER_FILE + echo -n "$($DMIDECODE dump_var_mock -s system-uuid)" > $SYSTEM_UUID_FILE + echo -n "$($DMIDECODE dump_var_mock -s baseboard-serial-number)" > $SERIAL_NUMBER_FILE - COREBOOT_SEC=$(cbfstool $BIOS_UPDATE_FILE layout -w | grep "COREBOOT") - FW_MAIN_A_SEC=$(cbfstool $BIOS_UPDATE_FILE layout -w | grep "FW_MAIN_A") - FW_MAIN_B_SEC=$(cbfstool $BIOS_UPDATE_FILE layout -w | grep "FW_MAIN_B") + COREBOOT_SEC=$($CBFSTOOL layout_mock $BIOS_UPDATE_FILE layout -w | grep "COREBOOT") + FW_MAIN_A_SEC=$($CBFSTOOL layout_mock $BIOS_UPDATE_FILE layout -w | grep "FW_MAIN_A") + FW_MAIN_B_SEC=$($CBFSTOOL layout_mock $BIOS_UPDATE_FILE layout -w | grep "FW_MAIN_B") if [ -n "$COREBOOT_SEC" ]; then # if the migration can be done there for sure will be COREBOOT section echo "Beginning SMBIOS migration process..." echo "Migrate to COREBOOT section." - cbfstool $BIOS_UPDATE_FILE add -f $SERIAL_NUMBER_FILE -n serial_number -t raw -r COREBOOT - cbfstool $BIOS_UPDATE_FILE add -f $SYSTEM_UUID_FILE -n system_uuid -t raw -r COREBOOT + $CBFSTOOL $BIOS_UPDATE_FILE add -f $SERIAL_NUMBER_FILE -n serial_number -t raw -r COREBOOT + $CBFSTOOL $BIOS_UPDATE_FILE add -f $SYSTEM_UUID_FILE -n system_uuid -t raw -r COREBOOT fi if [ -n "$FW_MAIN_A_SEC" ]; then echo "Migrate to FW_MAIN_A section." - cbfstool $BIOS_UPDATE_FILE expand -r FW_MAIN_A - cbfstool $BIOS_UPDATE_FILE add -f $SERIAL_NUMBER_FILE -n serial_number -t raw -r FW_MAIN_A - cbfstool $BIOS_UPDATE_FILE add -f $SYSTEM_UUID_FILE -n system_uuid -t raw -r FW_MAIN_A - cbfstool $BIOS_UPDATE_FILE truncate -r FW_MAIN_A + $CBFSTOOL $BIOS_UPDATE_FILE expand -r FW_MAIN_A + $CBFSTOOL $BIOS_UPDATE_FILE add -f $SERIAL_NUMBER_FILE -n serial_number -t raw -r FW_MAIN_A + $CBFSTOOL $BIOS_UPDATE_FILE add -f $SYSTEM_UUID_FILE -n system_uuid -t raw -r FW_MAIN_A + $CBFSTOOL $BIOS_UPDATE_FILE truncate -r FW_MAIN_A fi if [ -n "$FW_MAIN_B_SEC" ]; then echo "Migrate to FW_MAIN_B section." - cbfstool $BIOS_UPDATE_FILE expand -r FW_MAIN_B - cbfstool $BIOS_UPDATE_FILE add -f $SERIAL_NUMBER_FILE -n serial_number -t raw -r FW_MAIN_B - cbfstool $BIOS_UPDATE_FILE add -f $SYSTEM_UUID_FILE -n system_uuid -t raw -r FW_MAIN_B - cbfstool $BIOS_UPDATE_FILE truncate -r FW_MAIN_B + $CBFSTOOL $BIOS_UPDATE_FILE expand -r FW_MAIN_B + $CBFSTOOL $BIOS_UPDATE_FILE add -f $SERIAL_NUMBER_FILE -n serial_number -t raw -r FW_MAIN_B + $CBFSTOOL $BIOS_UPDATE_FILE add -f $SYSTEM_UUID_FILE -n system_uuid -t raw -r FW_MAIN_B + $CBFSTOOL $BIOS_UPDATE_FILE truncate -r FW_MAIN_B fi } smmstore_migration() { echo -n "Backing up firmware configuration... " - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} -r /tmp/dasharo_dump.rom ${FLASHROM_ADD_OPT_READ} --fmap -i FMAP -i SMMSTORE >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE - cbfstool /tmp/dasharo_dump.rom read -r SMMSTORE -f /tmp/smmstore.bin >> $ERR_LOG_FILE 2>&1 || \ + $FLASHROM read_firm_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} -r /tmp/dasharo_dump.rom ${FLASHROM_ADD_OPT_READ} --fmap -i FMAP -i SMMSTORE >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + $CBFSTOOL read_smmstore_mock /tmp/dasharo_dump.rom read -r SMMSTORE -f /tmp/smmstore.bin >> $ERR_LOG_FILE 2>&1 || \ print_warning "Failed! Default settings will be used." - cbfstool "$BIOS_UPDATE_FILE" write -r SMMSTORE -f /tmp/smmstore.bin -u >> $ERR_LOG_FILE 2>&1 || \ + $CBFSTOOL "$BIOS_UPDATE_FILE" write -r SMMSTORE -f /tmp/smmstore.bin -u >> $ERR_LOG_FILE 2>&1 || \ print_warning "Failed! Default settings will be used." print_ok Done. } bootsplash_migration() { - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} -r /tmp/dasharo_dump.rom ${FLASHROM_ADD_OPT_READ} --fmap -i FMAP -i BOOTSPLASH >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + $FLASHROM read_firm_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} -r /tmp/dasharo_dump.rom ${FLASHROM_ADD_OPT_READ} --fmap -i FMAP -i BOOTSPLASH >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE # If no custom logo, return from bootsplash_migration early and don't show # unnecessary messages - cbfstool /tmp/dasharo_dump.rom extract -r BOOTSPLASH -n logo.bmp -f /tmp/logo.bmp >> $ERR_LOG_FILE 2>&1 || return 1 + $CBFSTOOL /tmp/dasharo_dump.rom extract -r BOOTSPLASH -n logo.bmp -f /tmp/logo.bmp >> $ERR_LOG_FILE 2>&1 || return 1 echo -n "Backing up custom boot logo... " - dcu logo $BIOS_UPDATE_FILE -l /tmp/logo.bmp >> $ERR_LOG_FILE 2>&1 || \ + $DCU logo $BIOS_UPDATE_FILE -l /tmp/logo.bmp >> $ERR_LOG_FILE 2>&1 || \ print_warning "Failed! Default boot splash will be used." || return 1 print_ok Done. } @@ -316,7 +593,7 @@ check_vboot_keys() { # No FMAP flashing? Also skip grep -q "\--fmap" <<< "$FLASHROM_ADD_OPT_UPDATE" || return - BINARY_KEYS=$(CBFSTOOL=$(which cbfstool) futility show $BIOS_UPDATE_FILE| grep -i 'key sha1sum') + BINARY_KEYS=$(CBFSTOOL=$(which cbfstool) $FUTILITY dump_vboot_keys show $BIOS_UPDATE_FILE| grep -i 'key sha1sum') if [ $BOARD_HAS_FD_REGION -eq 0 ]; then FLASHROM_ADD_OPT_READ="" @@ -324,9 +601,9 @@ check_vboot_keys() { FLASHROM_ADD_OPT_READ="--ifd -i bios" fi echo "Checking vboot keys." - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_READ} -r /tmp/bios.bin > /dev/null 2>/dev/null - if [ $? -eq 0 ] && [ -f "/tmp/bios.bin" ]; then - FLASH_KEYS=$(CBFSTOOL=$(which cbfstool) futility show /tmp/bios.bin | grep -i 'key sha1sum') + $FLASHROM read_firm_mock -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_READ} -r $BIOS_DUMP_FILE > /dev/null 2>/dev/null + if [ $? -eq 0 ] && [ -f $BIOS_DUMP_FILE ]; then + FLASH_KEYS=$(CBFSTOOL=$(which cbfstool) $FUTILITY dump_vboot_keys show $BIOS_DUMP_FILE | grep -i 'key sha1sum') diff <(echo "$BINARY_KEYS") <(echo "$FLASH_KEYS") > /dev/null 2>&1 # If keys are different we must additionally flash at least GBB region as well if [ $? -ne 0 ]; then @@ -367,87 +644,228 @@ blob_transmission() { if [ -n "$SCH5545_FW" ]; then error_file_check "$SCH5545_FW" "Failed to find SCH5545 EC firmware binary." echo -n "Adding SCH5545 EC firmware..." - cbfstool "$BIOS_UPDATE_FILE" add -f "$SCH5545_FW" -n sch5545_ecfw.bin -t raw + $CBFSTOOL "$BIOS_UPDATE_FILE" add -f "$SCH5545_FW" -n sch5545_ecfw.bin -t raw print_ok "Done" fi if [ -n "$ACM_BIN" ]; then error_file_check "$ACM_BIN" "Failed to find BIOS ACM binary." echo -n "Adding BIOS ACM..." - cbfstool "$BIOS_UPDATE_FILE" add -f "$ACM_BIN" -n txt_bios_acm.bin -t raw + $CBFSTOOL "$BIOS_UPDATE_FILE" add -f "$ACM_BIN" -n txt_bios_acm.bin -t raw print_ok "Done" fi if [ -n "$SINIT_ACM" ]; then error_file_check "$SINIT_ACM" "Failed to find Intel SINIT ACM binary." echo -n "Adding SINIT ACM..." - cbfstool "$BIOS_UPDATE_FILE" add -f "$SINIT_ACM" -n txt_sinit_acm.bin -t raw + $CBFSTOOL "$BIOS_UPDATE_FILE" add -f "$SINIT_ACM" -n txt_sinit_acm.bin -t raw print_ok "Done" 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. +# +# TODO: Currently we have here flashrom parameters configuration code, this +# should be done before this function is called, so as to place here only +# deployment-related code. Ideally the deploying calls would look like this: +# +# $DEPLOY_COMMAND $DEPLOY_ARGS &>> $LOGS_FILE + local _mode + _mode="$1" + + if [ "$_mode" == "update" ]; then + echo "Updating EC..." + + # The EC firmware could be updated in two ways: via UEFI Capsule Update or + # via binaries and flashrom: + if [ "$FIRMWARE_VERSION" == "community_cap" ] || [ "$FIRMWARE_VERSION" == "dpp_cap" ]; then + # Linux Kernel driver is responsible for handling UEFI Capsule Updates, so + # the capsule should be fed to a specific device: + $CAP_UPD_TOOL "$EC_UPDATE_FILE" + # Return after updating. The below code is for flashrom updates (using + # binaries) only + return 0 + fi -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 + echo "Updating Embedded Controller firmware. Your computer will power off automatically when done." - check_intel_regions - check_blobs_in_binary $BIOS_UPDATE_FILE - check_if_me_disabled - set_intel_regions_update_params "-N --ifd -i bios" - fi + # Following command will reset device, so the function will not quit: + $DASHARO_ECTOOL flash "$EC_UPDATE_FILE" &>> $ERR_LOG_FILE + error_check "Failed to update EC firmware" - if [ "$HAVE_EC" == "true" ]; then - echo "Checking for Open Source Embedded Controller firmware" - $DASHARO_ECTOOL info >> $ERR_LOG_FILE 2>&1 - if [ $? -eq 0 ]; then + return 0 + elif [ "$_mode" == "install" ]; then + + if check_for_opensource_firmware; 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) + _ec_fw_version=$($FLASHROM get_ec_firm_version_mock check -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 + + return 0 fi - if [ "$CAN_INSTALL_BIOS" == "true" ]; 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="$?" + # Must not get here: + return 1 +} - if [ "$NEED_ROMHOLE_MIGRATION" = "true" ]; then - romhole_migration - fi +firmware_pre_updating_routine(){ +# This function only separates some code from deployment code, so to make clear +# where is deployment code, and what should be executed before it: + check_flash_lock + + if [ "$HAVE_EC" == "true" ]; then + check_for_opensource_firmware + error_check "Device does not have Dasharo EC firmware - cannot continue update!" + fi - if [ "$NEED_BOOTSPLASH_MIGRATION" = "true" ]; then - bootsplash_migration + if [ "$NEED_SMMSTORE_MIGRATION" = "true" ]; then + smmstore_migration + fi + + if [ "$NEED_BOOTSPLASH_MIGRATION" = "true" ]; then + bootsplash_migration + fi + + $CBFSTOOL read_bios_conffile_mock "$BIOS_UPDATE_FILE" extract -r COREBOOT -n config -f "$BIOS_UPDATE_CONFIG_FILE" + grep -q "CONFIG_VBOOT=y" "$BIOS_UPDATE_CONFIG_FILE" + HAVE_VBOOT="$?" + + check_intel_regions + check_blobs_in_binary $BIOS_UPDATE_FILE + check_if_me_disabled + set_flashrom_update_params $BIOS_UPDATE_FILE + set_intel_regions_update_params "-N --ifd" + check_vboot_keys + + return 0 +} + +firmware_pre_installation_routine(){ +# This function only separates some code from deployment code, so to make clear +# where is deployment code, and what should be executed before it: + 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" + + $CBFSTOOL read_bios_conffile_mock "$BIOS_UPDATE_FILE" extract -r COREBOOT -n config -f "$BIOS_UPDATE_CONFIG_FILE" + grep "CONFIG_VBOOT=y" "$BIOS_UPDATE_CONFIG_FILE" + HAVE_VBOOT="$?" + + if [ "$NEED_ROMHOLE_MIGRATION" = "true" ]; then + romhole_migration + fi + + if [ "$NEED_BOOTSPLASH_MIGRATION" = "true" ]; then + bootsplash_migration + fi + + if [ "$NEED_SMBIOS_MIGRATION" = "true" ]; then + smbios_migration + resign_binary + fi + + if [ "$NEED_BLOB_TRANSMISSION" = "true" ]; then + blob_transmission + fi + + return 0 +} + +deploy_firmware(){ +# This function deploys (installs or updates) downloaded firmware either UEFI +# capsules (updates only) or binaries. Parameters: update, install. +# +# TODO: Currently we have here flashrom parameters configuration code, this +# should be done before this function is called, so as to place here only +# deployment-related code. Ideally the deploying calls would look like this: +# +# $DEPLOY_COMMAND $DEPLOY_ARGS &>> $LOGS_FILE + local _mode + _mode="$1" + + if [ "$_mode" == "update" ]; then + echo "Updating Dasharo firmware..." + print_warning "This may take several minutes. Please be patient and do not" + print_warning "power off your computer or touch the keyboard!" + + # Firstly we need to check, whether it is possible to use UEFI Capsule + # Update, this is the preferred way of updating: + if [ "$FIRMWARE_VERSION" == "community_cap" ] || [ "$FIRMWARE_VERSION" == "dpp_cap" ]; then + # Linux Kernel driver is responsible for handling UEFI Capsule Updates, so + # the capsule should be fed to a specific device: + $CAP_UPD_TOOL "$BIOS_UPDATE_FILE" + # Return after updating. The below code is for flashrom updates (using + # binaries) only. + return 0 fi - if [ "$NEED_SMBIOS_MIGRATION" = "true" ]; then - smbios_migration - resign_binary + # Pre-update routine for UEFI Capsule Update is done by drivers and the + # capsule itself, so the routine is required only for flashrom updates: + firmware_pre_updating_routine + + # FLASHROM_ADD_OPT_UPDATE_OVERRIDE takes priority over auto-detected update params. + # It set only by platform-specific and firmware version-specific conditions + if [ -n "$FLASHROM_ADD_OPT_UPDATE_OVERRIDE" ]; then + # To standardize the operation of the FLASHROM_ADD_OPT_UPDATE_OVERRIDE flag, + # by default it contains only the bios section, below we verify the + # downloaded binary and add more sections when they were detected after + # using the `check_blobs_in_binary` function. + set_intel_regions_update_params "$FLASHROM_ADD_OPT_UPDATE_OVERRIDE" + FLASHROM_ADD_OPT_UPDATE_OVERRIDE="$FLASHROM_ADD_OPT_REGIONS" + $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_UPDATE_OVERRIDE} -w "$BIOS_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + error_check "Failed to update Dasharo firmware" + else + $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_UPDATE} -w "$BIOS_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + error_check "Failed to update Dasharo firmware" + + if [ $BINARY_HAS_RW_B -eq 0 ]; then + echo "Updating second firmware partition..." + $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} --fmap -N -i RW_SECTION_B -w "$BIOS_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + error_check "Failed to update second firmware partition" + fi fi - if [ "$NEED_BLOB_TRANSMISSION" = "true" ]; then - blob_transmission + # We use FLASHROM_ADD_OPT_REGIONS for updating ME and IFD. + # If FLASHROM_ADD_OPT_REGIONS remains the same after + # set_intel_regions_update_params or is cleared, it means + # we either cannot update any region, or were not allowed to, + # or platform has no descriptor. + if [ "$FLASHROM_ADD_OPT_REGIONS" != "-N --ifd" ] && [ "$FLASHROM_ADD_OPT_REGIONS" != "" ]; then + UPDATE_STRING="" + grep -q "\-i fd" <<< "$FLASHROM_ADD_OPT_REGIONS" + UPDATE_IFD=$? + grep -q "\-i me" <<< "$FLASHROM_ADD_OPT_REGIONS" + UPDATE_ME=$? + if [ $UPDATE_IFD -eq 0 ]; then + UPDATE_STRING+="Flash Descriptor" + if [ $UPDATE_ME -eq 0 ]; then + UPDATE_STRING+=" and " + fi + fi + if [ $UPDATE_ME -eq 0 ]; then + UPDATE_STRING+="Management Engine" + fi + echo "Updating $UPDATE_STRING" + $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_REGIONS} -w "$BIOS_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + error_check "Failed to update $UPDATE_STRING" fi + return 0 + elif [ "$_mode" == "install" ]; then + firmware_pre_installation_routine + echo "Installing Dasharo firmware..." # FIXME: It seems we do not have an easy way to add some flasrhom extra args # globally for specific platform and variant @@ -457,14 +875,67 @@ 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" + + return 0 fi + # Must not get here. + return 1 +} + +install_workflow() { +# Installation workflow. The installation of firmware is possible only via +# flashrom, capsules cannot do the installation because they need initial +# support inside firmware. The workflow steps are: +# 1) Prepare system for installation (e.g. check connection); +# 2) Prepare environment for installation (e.g. set all needed vars); +# 3) Ask user are the changes that will be done ok; +# 4) Do backup; +# 5) Do the installation; +# 6) Do some after-installation routine. + sync_clocks + + # Verify that the device is not using battery as a power source: + check_if_ac + error_check "Firmware update process interrupted on user request." + + # Set all global variables needed for installation: + prepare_env install + + # Download and verify firmware: + if [ "$HAVE_EC" == "true" ]; then + download_ec + verify_artifacts ec + fi + if [ "$CAN_INSTALL_BIOS" == "true" ]; then + download_bios + verify_artifacts bios + fi + + # Ask user for confirmation: + display_warning + + backup + + # 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 + + send_dts_logs + + 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,238 +954,84 @@ install() { sleep 0.5 echo "Rebooting" sleep 1 - if [ "$NEED_EC_RESET" = "true" ]; then + if [ "$NEED_EC_RESET" == "true" ]; then it5570_shutdown else - send_dts_logs - ${CMD_REBOOT} + ${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() { - local _can_switch_to_heads="false" - +update_workflow() { +# Update workflow. Supported firmware formats: binary, UEFI capsule. The +# workflow steps are: +# 1) Prepare system for update (e.g. check connection); +# 2) Prepare environment for update (e.g. set all needed vars); +# 3) Ask user are the changes that will be done ok; +# 4) Do the updating; +# 5) Do some after-updating routine. + CAN_SWITCH_TO_HEADS="false" sync_clocks + + # Verify that 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..." - echo "Current Dasharo version: $DASHARO_VERSION" - 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 - curl -sfI -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$BIOS_LINK_DPP" -o /dev/null - 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 - curl -sfI -u "$USER_DETAILS" -H "$CLOUD_REQUEST" "$HEADS_LINK_DPP" -o /dev/null - 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 + # Set all global variables needed for installation: + prepare_env update + + print_ok "Current Dasharo version: $DASHARO_VERSION" + print_ok "Latest available Dasharo version for your subscribtion: $UPDATE_VERSION" + + + # TODO: Why do we separate Heads firmware-related code from other code? A + # common way to handle this should be found. + # + # Versions should be compared only in case we are not switching to Heads, + # because heads version is not set at this moment, it is being set and + # compared in handle_fw_switching: + if [ "$CAN_SWITCH_TO_HEADS" = "true" ] || [ "$DASHARO_FLAVOR" == "Dasharo (coreboot+heads)" ]; then + handle_fw_switching $CAN_SWITCH_TO_HEADS 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 - # shellcheck disable=SC2034 - BIOS_SIGN_LINK=$BIOS_SIGN_LINK_COMM - BIOS_LINK=$BIOS_LINK_COMM - if [ "$HAVE_EC" == "true" ]; then - EC_HASH_LINK=$EC_HASH_LINK_COMM - # shellcheck disable=SC2034 - 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" + compare_versions $DASHARO_VERSION $UPDATE_VERSION + if [ $? -ne 1 ]; then + error_exit "No update available for your machine" fi fi - handle_fw_switching $_can_switch_to_heads - + # TODO: It is not a good practice to do some target specific work in the code + # of a scallable product, this should be handled in a more scallable way: if [[ "$UPDATE_VERSION" == "1.1.1" && \ ( "$BOARD_MODEL" == "PRO Z690-A WIFI DDR4(MS-7D25)" || \ "$BOARD_MODEL" == "PRO Z690-A DDR4(MS-7D25)" || \ "$BOARD_MODEL" == "PRO Z690-A (MS-7D25)" || \ "$BOARD_MODEL" == "PRO Z690-A WIFI (MS-7D25)" ) ]]; then - cpu_gen_check=$(lscpu | grep -F "Model name" | grep -E "\-(13|14)[0-9]{3}" | wc -l) + cpu_gen_check=$($LSCPU | grep -F "Model name" | grep -E "\-(13|14)[0-9]{3}" | wc -l) if [ $cpu_gen_check -ne 0 ]; then echo "You have a 13th gen or above CPU and are trying to flash Dasharo v1.1.1 on a MSI PRO Z690-A DDR4 or DDR5 board" 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 - echo - read -r -p "Are you sure you want to proceed with update? (Y|n) " OPTION - echo - - case ${OPTION} in - ""|yes|y|Y|Yes|YES) - break - ;; - n|N) - error_exit "Aborting update process..." - ;; - *) - ;; - esac - done - - download_artifacts - if [ ! "$FUM" == "fum" ]; then - display_flashing_warning - fi - check_flash_lock - - verify_artifacts bios - if [ "$HAVE_EC" == "true" ]; then - $DASHARO_ECTOOL info >> $ERR_LOG_FILE 2>&1 - error_check "Device does not have Dasharo EC firmware - cannot continue update!" + download_ec + verify_artifacts ec fi - if [ "$NEED_SMMSTORE_MIGRATION" = "true" ]; then - smmstore_migration - fi + download_bios + verify_artifacts bios - if [ "$NEED_BOOTSPLASH_MIGRATION" = "true" ]; then - bootsplash_migration + # Warning must be displayed after the artifacts have been downloaded, because + # we check their hashes inside display_warning function: + if [ ! "$FUM" == "fum" ]; then + display_warning fi - cbfstool "$BIOS_UPDATE_FILE" extract -r COREBOOT -n config -f "$BIOS_UPDATE_CONFIG_FILE" - grep -q "CONFIG_VBOOT=y" "$BIOS_UPDATE_CONFIG_FILE" - HAVE_VBOOT="$?" - - check_intel_regions - check_blobs_in_binary $BIOS_UPDATE_FILE - check_if_me_disabled - set_flashrom_update_params $BIOS_UPDATE_FILE - set_intel_regions_update_params "-N --ifd" - check_vboot_keys - - echo "Updating Dasharo firmware..." - print_warning "This may take several minutes. Please be patient and do not power off your computer or touch the keyboard!" - - # FLASHROM_ADD_OPT_UPDATE_OVERRIDE takes priority over auto-detected update params. - # It set only by platform-specific and firmware version-specific conditions - if [ -v FLASHROM_ADD_OPT_UPDATE_OVERRIDE ]; then - # To standardize the operation of the FLASHROM_ADD_OPT_UPDATE_OVERRIDE flag, - # by default it contains only the bios section, below we verify the - # downloaded binary and add more sections when they were detected after - # using the `check_blobs_in_binary` function. - set_intel_regions_update_params "$FLASHROM_ADD_OPT_UPDATE_OVERRIDE" - FLASHROM_ADD_OPT_UPDATE_OVERRIDE="$FLASHROM_ADD_OPT_REGIONS" - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_UPDATE_OVERRIDE} -w "$BIOS_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE - error_check "Failed to update Dasharo firmware" - else - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_UPDATE} -w "$BIOS_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE - error_check "Failed to update Dasharo firmware" - - if [ $BINARY_HAS_RW_B -eq 0 ]; then - echo "Updating second firmware partition..." - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} --fmap -N -i RW_SECTION_B -w "$BIOS_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE - error_check "Failed to update second firmware partition" - fi - fi - - # We use FLASHROM_ADD_OPT_REGIONS for updating ME and IFD. - # If FLASHROM_ADD_OPT_REGIONS remains the same after - # set_intel_regions_update_params or is cleared, it means - # we either cannot update any region, or were not allowed to, - # or platform has no descriptor. - if [ "$FLASHROM_ADD_OPT_REGIONS" != "-N --ifd" ] && [ "$FLASHROM_ADD_OPT_REGIONS" != "" ]; then - UPDATE_STRING="" - grep -q "\-i fd" <<< "$FLASHROM_ADD_OPT_REGIONS" - UPDATE_IFD=$? - grep -q "\-i me" <<< "$FLASHROM_ADD_OPT_REGIONS" - UPDATE_ME=$? - if [ $UPDATE_IFD -eq 0 ]; then - UPDATE_STRING+="Flash Descriptor" - if [ $UPDATE_ME -eq 0 ]; then - UPDATE_STRING+=" and " - fi - fi - if [ $UPDATE_ME -eq 0 ]; then - UPDATE_STRING+="Management Engine" - fi - echo "Updating $UPDATE_STRING" - $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_REGIONS} -w "$BIOS_UPDATE_FILE" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE - error_check "Failed to update $UPDATE_STRING" - fi + deploy_firmware update + # TODO: Could it be placed somewhere else? if [ ! -z "$SWITCHING_TO" ]; then # Any post-branch-switch messaging should go here case "$SWITCHING_TO" in @@ -728,37 +1045,38 @@ update() { print_warning "This is expected. Run OEM Factory Reset / Re-Ownership to finish deploying Heads." ;; esac - read -p "Press any key to continue" # Make sure the user acknowledges. + read -p "Press enter to continue" # Make sure the user acknowledges. else # Regular update flow print_ok "Successfully updated Dasharo firmware." fi + send_dts_logs + + # 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 - else - echo -n "Syncing disks... " - sync - echo "Done." - echo "The computer will reboot automatically in 5 seconds" - sleep 0.5 - echo "Rebooting in 5s:" - echo "5..." - sleep 1 - echo "4..." - sleep 1 - echo "3..." - sleep 1 - echo "2..." - sleep 1 - echo "1..." - sleep 0.5 - echo "Rebooting" - sleep 1 - send_dts_logs - ${CMD_REBOOT} + deploy_ec_firmware update fi + + echo -n "Syncing disks... " + sync + echo "Done." + echo "The computer will reboot automatically in 5 seconds" + sleep 0.5 + echo "Rebooting in 5s:" + echo "5..." + sleep 1 + echo "4..." + sleep 1 + echo "3..." + sleep 1 + echo "2..." + sleep 1 + echo "1..." + sleep 0.5 + echo "Rebooting" + sleep 1 + ${REBOOT} } restore() { @@ -792,8 +1110,8 @@ restore() { if [ ! $? -eq 0 ]; then uuid_string="" fi - uuid_string="${mac_addr}_$(dmidecode -s system-product-name)" - uuid_string+="_$(dmidecode -s system-manufacturer)" + uuid_string="${mac_addr}_$($DMIDECODE dump_var_mock -s system-product-name)" + uuid_string+="_$($DMIDECODE dump_var_mock -s system-manufacturer)" uuid="$(uuidgen -n @x500 -N $uuid_string -s)" case ${OPTION} in @@ -859,7 +1177,7 @@ restore() { check_blobs_in_binary /tmp/logs/rom.bin check_if_me_disabled set_intel_regions_update_params "-N --ifd -i bios" - flashrom -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_REGIONS} -w "/tmp/logs/rom.bin" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE + $FLASHROM -p "$PROGRAMMER_BIOS" ${FLASH_CHIP_SELECT} ${FLASHROM_ADD_OPT_REGIONS} -w "/tmp/logs/rom.bin" >> $FLASHROM_LOG_FILE 2>> $ERR_LOG_FILE error_check "Failed to restore BIOS firmware! You can try one more time." print_ok "Successfully restored firmware" else @@ -879,7 +1197,7 @@ restore() { usage() { echo "Usage:" echo " $0 install - Install Dasharo on this device" - echo " $0 backup - Backup current firmware" + echo " $0 update - Update Dasharo" echo " $0 restore - Restore from a previously saved backup" } @@ -889,15 +1207,23 @@ if ! check_if_dasharo; then fi fi -# for FUM we start in dasharo-deploy so we need to verify that we have internet +# For FUM we start in dasharo-deploy so we need to verify that we have internet # connection to download shasums in board_config if [ "$FUM" == "fum" ]; then wait_for_network_connection fi +# flashrom does not support QEMU. TODO: this could be handled in a better way: +if [ "${SYSTEM_VENDOR}" != "QEMU" ] && [ "${SYSTEM_VENDOR}" != "Emulation" ]; then + # Size of flashchip should be checked before board_config func. because the + # func. assigns some configs based on the chip size detected for ASUS boards + # (FIXME). + check_flash_chip +fi + board_config -check_flash_chip -if [ -v PLATFORM_SIGN_KEY ]; then + +if [ -n "$PLATFORM_SIGN_KEY" ]; then get_signing_keys fi @@ -907,8 +1233,7 @@ case "$CMD" in error_exit "Dasharo Firmware is already installed. This script is only for\r initial deployment of Dasharo Firmware. Aborting..." fi - backup - install + install_workflow ;; update) if [ "$FUM" == "fum" ]; then @@ -925,10 +1250,7 @@ case "$CMD" in echo "1..." sleep 0.5 fi - update - ;; - backup) - backup + update_workflow ;; restore) if ! check_if_dasharo; then diff --git a/scripts/dts-boot b/scripts/dts-boot index 7d71f347..b99d68df 100644 --- a/scripts/dts-boot +++ b/scripts/dts-boot @@ -11,8 +11,17 @@ FUM_EFIVAR="/sys/firmware/efi/efivars/FirmwareUpdateMode-d15b327e-ff2d-4fc1-abf6 export DTS_FUNCS="$SBIN_DIR/dts-functions.sh" export DTS_ENV="$SBIN_DIR/dts-environment.sh" export DTS_SUBS="$SBIN_DIR/dts-subscription.sh" +export DTS_HAL="$SBIN_DIR/dts-hal.sh" +export DTS_MOCK_COMMON="$SBIN_DIR/common-mock-func.sh" export DTS_LOG_FILE="/tmp/dts.log" +# shellcheck source=../include/dts-environment.sh +source $DTS_ENV +# shellcheck source=../include/dts-functions.sh +source $DTS_FUNCS +# shellcheck source=../include/hal/dts-hal.sh +source $DTS_HAL + if [ -f $FUM_EFIVAR ]; then $SBIN_DIR/dasharo-deploy update fum else diff --git a/scripts/ec_transition b/scripts/ec_transition index a22e4c8e..ef199c34 100644 --- a/scripts/ec_transition +++ b/scripts/ec_transition @@ -4,8 +4,12 @@ # # SPDX-License-Identifier: Apache-2.0 +# shellcheck source=../include/dts-environment.sh source $DTS_ENV +# shellcheck source=../include/dts-functions.sh source $DTS_FUNCS +# shellcheck source=../include/hal/dts-hal.sh +source $DTS_HAL board_config() { case "$SYSTEM_VENDOR" in @@ -44,20 +48,9 @@ board_config() { esac } -check_for_opensource_firmware() -{ - echo "Checking for opensource firmware" - $DASHARO_ECTOOL info >> /dev/null 2>&1 - if [ $? -eq 0 ]; then - error_exit "Device has already Open Source Embedded Controller firmware, aborting..." - fi -} - download_files() { wait_for_network_connection - BIOS_UPDATE_FILE="/tmp/biosupdate.rom" - EC_UPDATE_FILE="/tmp/ecupdate.rom" wget -O $EC_UPDATE_FILE $EC_LINK error_check "Cannot download EC update file. Aborting..." wget -O $BIOS_UPDATE_FILE $BIOS_LINK @@ -81,7 +74,7 @@ install() { error_check "Failed to verify Dasharo firmware" if [ "$HAVE_EC" == "true" ]; then - _ec_fw_version=$($FLASHROM -p ${PROGRAMMER_EC} | grep "Mainboard EC Version" | tr -d ' ' | cut -d ':' -f 2) + _ec_fw_version=$($FLASHROM get_ec_firm_version_mock -p ${PROGRAMMER_EC} | grep "Mainboard EC Version" | tr -d ' ' | cut -d ':' -f 2) if [ "$_ec_fw_version" != "$COMPATIBLE_EC_FW_VERSION" ]; then echo "EC version: $_ec_fw_version is not supported, update required" @@ -100,7 +93,7 @@ install() { if [ "$NEED_EC_RESET" = "true" ]; then it5570_shutdown else - ${CMD_POWEROFF} + ${POWEROFF} fi } @@ -115,7 +108,9 @@ ROOT_DIR="/" [ -z "$SYSTEM_VENDOR" ] && error_exit "SYSTEM_VENDOR not given" [ -z "$SYSTEM_MODEL" ] && error_exit "SYSTEM_MODEL not given" -check_for_opensource_firmware +if check_for_opensource_firmware; then + error_exit "Device has already Open Source Embedded Controller firmware, aborting..." +fi board_config download_files install diff --git a/scripts/local-deploy.sh b/scripts/local-deploy.sh old mode 100755 new mode 100644 diff --git a/tests/README.md b/tests/README.md index 1af5fc04..bc887148 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,268 +1,4 @@ -# DTS scripts unit tests +# DTS scripts tests -This directory contains stub scripts for testing DTS update and deploy logic -in complex scenarios. - -## Running on host - -Running test on the host may result in unpredictable results because of the -missing programs and different version of certain tools. It is advised to run -the DTS image in QEMU as a development environment. Running on host is -generally not supported and should be avoided. - -## Running in QEMU - -### Credentials setup - -We need credentials for each test variant. You can use provided template and -fill it in accordingly. - -```bash -cp des-credentials.sh.example des-credentials.sh -``` - -### Running automatically - -Some scenarios are have been already migrated into [OSFV](TBD). - -```bash -robot -L TRACE -v config:qemu -v rte_ip:127.0.0.1 -v snipeit:no dts/dts-tests.robot -``` - -### Running manually - -1. Boot the latest DTS image in QEMU. Recommended steps: - - start QEMU according to - [OSFV documentation](https://github.com/Dasharo/open-source-firmware-validation/blob/develop/docs/qemu.md#booting) - (use `os` switch, not `firmware`) - - enable network boot and boot into DTS via iPXE - - enable SSH server (option `8` in main menu) - -1. Deploy updated scripts and tests into qemu - - ```bash - PORT=5222 ./scripts/local-deploy.sh 127.0.0.1 - ``` - -1. Execute desired test as described in below section. E.g.: - - ```shell - ssh -p 5222 root@127.0.0.1 - export BOARD_VENDOR="Notebook" SYSTEM_MODEL="NV4xPZ" BOARD_MODEL="NV4xPZ" - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.7.2" TEST_DES=y DES_TYPE="heads" && dts-boot - ``` - -## Test cases - -The general idea is that we override some variables, so DTS scripts consider -they are running on the given board. Then we select `Install` or `Update` -actions from DTS menu, and check if the flow is as expected in certain -scenario. - -After each `dts-boot -> 5) Check and apply Dasharo firmware updates` scenario -execution, we can drop to DTS shell and continue with the next scenario. - -### NovaCustom - -```bash -export BOARD_VENDOR="Notebook" SYSTEM_MODEL="NV4xPZ" BOARD_MODEL="NV4xPZ" -``` - -1. Dasharo v1.7.2 on NV4x_PZ eligible for updates to heads with heads DES and - regular update: - - ```bash - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.7.2" TEST_DES=y DES_TYPE="heads" && dts-boot - ``` - - Expected output: - - heads fw should be offered - -1. Dasharo v1.7.2 on NV4x_PZ eligible for updates to heads without DES - (regular update only): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.7.2" TEST_DES=n && dts-boot - ``` - - Expected output: - - no update should be offered - -1. Dasharo v1.6.0 on NV4x_PZ not eligible for updates to heads with heads DES - (regular update only): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.6.0" TEST_DES=y DES_TYPE="heads" && dts-boot - ``` - - Expected output: - - UEFI fw update should be offered (this is too old release to transition to - heads directly, need to flash latest UEFI fw first) - -1. Dasharo v1.6.0 on NV4x_PZ not eligible for updates to heads without heads - DES (regular update only): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.6.0" TEST_DES=n && dts-boot - ``` - - Expected output: - - UEFI fw update should be offered - -1. Dasharo heads v0.9.0 on NV4x_PZ eligible for updates to heads with heads - DES and switch back (heads updates): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+heads) v0.9.0" TEST_DES=y DES_TYPE="heads" && dts-boot - ``` - - Expected output: - - migration to UEFI should be offered first - - if we say `n` to switch, heads update should be offered - -1. Dasharo heads v0.9.0 on NV4x_PZ without DES switch back, no heads updates: - - ```bash - export BIOS_VERSION="Dasharo (coreboot+heads) v0.9.0" TEST_DES=n && dts-boot - ``` - - Expected output: - - migration to UEFI should be offered first - - if we say `n` to switch, no heads update should be offered - -Another case is to edit `dts-functions.sh` and set `DASHARO_REL_VER` to -`v1.7.3` to detect possible regular firmware updates and `HEADS_REL_VER_DES` -to `v0.9.1` to detect possible heads firmware updates and repeat all test -cases. The URLs for non-existing versions may fail. - -The NovaCustom test binaries for credentials in `dts-boot` are placed in -[/projects/projects/2022/novacustom/dts_test](https://cloud.3mdeb.com/index.php/f/659609) -on 3mdeb cloud. These are just public coreboot+UEFI v1.7.2 binaries. -Analogically with MSI, cloud directory is -[/projects/projects/2022/msi/dts_test](https://cloud.3mdeb.com/index.php/f/667474) -and binaries are simply Z690-A public coreboot+UEFI v1.1.1 binaries with -changed names for both Z690-A and Z790-P (resigned with appropriate keys). - -### MSI MS-7D25 - -```bash -export BOARD_VENDOR="Micro-Star International Co., Ltd." SYSTEM_MODEL="MS-7D25" BOARD_MODEL="PRO Z690-A WIFI DDR4(MS-7D25)" -``` - -1. Dasharo v1.1.1 on MS-7D25 eligible for updates to heads with heads DES and - regular update: - - ```bash - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.1.1" TEST_DES=y DES_TYPE="heads" && dts-boot - ``` - -1. Dasharo v1.1.1 on MS-7D25 eligible for updates to heads without DES - (regular update only): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.1.1" TEST_DES=n && dts-boot - ``` - -1. Dasharo v1.1.2 on MS-7D25 eligible for updates to heads with heads DES - (regular update only through regular DES): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.1.2" TEST_DES=y DES_TYPE="heads" && dts-boot - ``` - -1. Dasharo v1.1.2 on MS-7D25 not eligible for updates to heads without heads - DES (regular update only through regular DES): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+UEFI) v1.1.2" TEST_DES=n && dts-boot - ``` - -1. Dasharo heads v0.9.0 on MS-7D25 eligible for updates to heads with heads - DES and switch back (regular update and switch-back): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+heads) v0.9.0" TEST_DES=y DES_TYPE="heads" && dts-boot - ``` - -1. Dasharo heads v0.9.0 on MS-7D25 without DES switch back, no heads updates - (regular update and switch-back): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+heads) v0.9.0" TEST_DES=n && dts-boot - ``` - -### MSI MS-7E06 - -```bash -export BOARD_VENDOR="Micro-Star International Co., Ltd." SYSTEM_MODEL="MS-7E06" BOARD_MODEL="PRO Z790-P WIFI (MS-7E06)" -``` - -1. Dasharo heads v0.9.0 on MS-7E06 eligible for updates to heads with heads - DES and switch back (regular update and switch-back only through regular - DES, no community release): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+heads) v0.9.0" TEST_DES=y DES_TYPE=heads && dts-boot - ``` - - Expected output: - - migration to UEFI should be offered first - - if we say `n` to switch, no heads (no more recent update available yet) - -1. Dasharo heads v0.9.0 on MS-7E06 without DES switch back, no heads updates - (regular update and switch-back only through regular DES, no community - release): - - ```bash - export BIOS_VERSION="Dasharo (coreboot+heads) v0.9.0" TEST_DES=n && dts-boot - ``` - - Expected output: - - should print info on DES availability in the shop - - migration to UEFI should be offered - -### PC Engines - -```bash -export BOARD_VENDOR="PC Engines" SYSTEM_MODEL="APU2" BOARD_MODEL="APU2" -``` - -1. Initial deployment from legacy firmware (no DES credentials) - - ```bash - export BIOS_VERSION="v4.19.0.1" TEST_DES=n && dts-boot - ``` - - Expected output: - - no DES - no deployment should be offered - - info on DES availailbity in the shop should be shown - -1. Initial deployment from legacy firmware (UEFI DES credentials) - - ```bash - export BIOS_VERSION="v4.19.0.1" TEST_DES=y DES_TYPE="UEFI" && dts-boot - ``` - - Expected output: - - UEFI deployment should be offered - - info on DES availailbity in the shop should not be shown - -1. Initial deployment from legacy firmware (seabios DES credentials) - - ```bash - export BIOS_VERSION="v4.19.0.1" TEST_DES=y DTS_TYPE="seabios" && dts-boot - ``` - - Expected output: - - Seabios deployment should be offered - - info on DES availailbity in the shop should not be shown - -1. Initial deployment from legacy firmware (correct DES credentials) - - ```bash - export BIOS_VERSION="v4.19.0.1" TEST_DES=n && dts-boot - ``` - - Expected output: - - seabios deployment should be offered - - info on DES availailbity in the shop should not be shown +This folder contains dts-scripts test cases that are still to be implemented in +[Dasharo OSFV](https://github.com/Dasharo/open-source-firmware-validation). diff --git a/tests/README_tests.md b/tests/README_tests.md deleted file mode 100644 index 3dd779fe..00000000 --- a/tests/README_tests.md +++ /dev/null @@ -1,4 +0,0 @@ -# Readme - -This directory contains test cases for some parts of the code in this -repository. TODO: manage repository testing properly. diff --git a/tests/cloud-pass b/tests/cloud-pass deleted file mode 100644 index bed949cf..00000000 --- a/tests/cloud-pass +++ /dev/null @@ -1,3 +0,0 @@ -SHY8Lfteq2bCLGD -diCqE9Q5wL8eLZH -%K5RKof! diff --git a/tests/compare_version.sh b/tests/compare_version.sh old mode 100755 new mode 100644 diff --git a/tests/dasharo-ectool-mock.sh b/tests/dasharo-ectool-mock.sh deleted file mode 100755 index e5023614..00000000 --- a/tests/dasharo-ectool-mock.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Function to print usage -usage() { - echo "Usage: $0 info" - exit 1 -} - -# Check if the first argument is 'info' -if [[ "$1" != "info" ]]; then - usage -fi - -# Mock info command output -echo "Dasharo EC Tool Mock - Info Command" -echo "-----------------------------------" -echo "board: novacustom/nv4x_adl" -echo "version: 2023-03-10_c0fe220" -echo "-----------------------------------" - -exit 0 diff --git a/tests/dpp-credentials.example b/tests/dpp-credentials.example deleted file mode 100644 index e2ead919..00000000 --- a/tests/dpp-credentials.example +++ /dev/null @@ -1,24 +0,0 @@ -# NovaCustom heads keys -NCM_HEADS_LOGS_KEY='' -NCM_HEADS_DL_KEY='' -NCM_HEADS_PWD='' - -# MSI heads keys -MSI_HEADS_LOGS_KEY='' -MSI_HEADS_DL_KEY='' -MSI_HEADS_PWD='' - -# MSI UEFI keys -MSI_UEFI_LOGS_KEY='' -MSI_UEFI_DL_KEY='' -MSI_UEFI_PWD='' - -# PC Engines SeaBIOS keys -PCE_SEABIOS_LOGS_KEY='' -PCE_SEABIOS_DL_KEY='' -PCE_SEABIOS_PWD='' - -# PC Engines UEFI keys -PCE_UEFI_LOGS_KEY='' -PCE_UEFI_DL_KEY='' -PCE_UEFI_PWD='' diff --git a/tests/dts-boot b/tests/dts-boot deleted file mode 100755 index f838965c..00000000 --- a/tests/dts-boot +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash -source /usr/sbin/dpp-credentials.sh - -SBIN_DIR="/usr/sbin" -export DTS_FUNCS="$SBIN_DIR/dts-functions.sh" -export DTS_ENV="$SBIN_DIR/dts-environment.sh" -export DTS_SUBS="$SBIN_DIR/dts-subscription.sh" - -# QEMU does not support flashrom read/write yet, provide some basic mock to pass flashrom calls -export FLASHROM="/usr/sbin/flashrom-mock.sh" -export DASHARO_ECTOOL="/usr/sbin/dasharo-ectool-mock.sh" -# Skip HCL report in Dasharo deployment, which takes a lot of time -# and creates many reports in cloud. -export LOGS_SENT="1" - -CLOUD_PASS_FILE="/etc/cloud-pass" - -rm -f "${CLOUD_PASS_FILE}" -if [ "$BOARD_VENDOR" = "Notebook" ] && [ "$DPP_TYPE" = "heads" ]; then - echo "$NCM_HEADS_LOGS_KEY" >> "${CLOUD_PASS_FILE}" - echo "$NCM_HEADS_DL_KEY" >> "${CLOUD_PASS_FILE}" - echo "$NCM_HEADS_PWD" >> "${CLOUD_PASS_FILE}" -elif [ "$BOARD_VENDOR" = "Micro-Star International Co., Ltd." ] && [ "$DPP_TYPE" = "heads" ]; then - echo "$MSI_HEADS_LOGS_KEY" >> "${CLOUD_PASS_FILE}" - echo "$MSI_HEADS_DL_KEY" >> "${CLOUD_PASS_FILE}" - echo "$MSI_HEADS_PWD" >> "${CLOUD_PASS_FILE}" -elif [ "$BOARD_VENDOR" = "Micro-Star International Co., Ltd." ] && [ "$DPP_TYPE" = "UEFI" ]; then - echo "$MSI_UEFI_LOGS_KEY" >> "${CLOUD_PASS_FILE}" - echo "$MSI_UEFI_DL_KEY" >> "${CLOUD_PASS_FILE}" - echo "$MSI_UEFI_PWD" >> "${CLOUD_PASS_FILE}" -elif [ "$BOARD_VENDOR" = "PC Engines" ] && [ "$DPP_TYPE" = "UEFI" ]; then - echo "$PCE_UEFI_LOGS_KEY" >> "${CLOUD_PASS_FILE}" - echo "$PCE_UEFI_DL_KEY" >> "${CLOUD_PASS_FILE}" - echo "$PCE_UEFI_PWD" >> "${CLOUD_PASS_FILE}" -elif [ "$BOARD_VENDOR" = "PC Engines" ] && [ "$DPP_TYPE" = "seabios" ]; then - echo "$PCE_SEABIOS_LOGS_KEY" >> "${CLOUD_PASS_FILE}" - echo "$PCE_SEABIOS_DL_KEY" >> "${CLOUD_PASS_FILE}" - echo "$PCE_SEABIOS_PWD" >> "${CLOUD_PASS_FILE}" -fi - -if [ -f /tmp/bios.bin ]; then - rm /tmp/bios.bin -fi - -export HAVE_EC="false" - -$SBIN_DIR/dts diff --git a/tests/flashrom-mock.sh b/tests/flashrom-mock.sh deleted file mode 100755 index a4b36673..00000000 --- a/tests/flashrom-mock.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -# Initialize variables -PROGRAMMER="" -READ_FLAG="" -OUTPUT_FILE="" -EXTRA_OPTIONS="" - -# Function to print usage -usage() { - echo "Usage: $0 -p PROGRAMMER -r OUTPUT_FILE [EXTRA_OPTIONS]" - exit 1 -} - -# Parse command-line arguments -while [[ "$#" -gt 0 ]]; do - case $1 in - -p) - PROGRAMMER="$2" - shift 2 - ;; - -r) - READ_FLAG="-r" - OUTPUT_FILE="$2" - shift 2 - ;; - *) - EXTRA_OPTIONS+="$1 " - shift - ;; - esac -done - -# Check if required arguments are provided -if [[ -z "$PROGRAMMER" ]]; then - usage -fi - -# Create the directory for the output file if it doesn't exist -OUTPUT_DIR=$(dirname "$OUTPUT_FILE") -mkdir -p "$OUTPUT_DIR" - -# Mock flashrom functionality -echo "Mock flashrom: Programmer = $PROGRAMMER" -echo "Mock flashrom: Extra options = $EXTRA_OPTIONS" - -if [[ -n "$READ_FLAG" ]]; then - if [[ -z "$OUTPUT_FILE" ]]; then - usage - fi - echo "Mock flashrom: Reading BIOS into $OUTPUT_FILE" - - # Create a mock rom.bin file with some dummy data - echo "This is a mock rom.bin file for testing purposes." > "$OUTPUT_FILE" - - # Verify if the file is created - if [ -f "$OUTPUT_FILE" ]; then - echo "Mock flashrom: Successfully created $OUTPUT_FILE" - else - echo "Mock flashrom: Failed to create $OUTPUT_FILE" - exit 1 - fi -fi