diff options
Diffstat (limited to 'include/vendor.sh')
-rw-r--r-- | include/vendor.sh | 568 |
1 files changed, 289 insertions, 279 deletions
diff --git a/include/vendor.sh b/include/vendor.sh index c5b6560d..55373913 100644 --- a/include/vendor.sh +++ b/include/vendor.sh @@ -1,201 +1,206 @@ # SPDX-License-Identifier: GPL-3.0-only # Copyright (c) 2022 Caleb La Grange <thonkpeasant@protonmail.com> # Copyright (c) 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com> -# Copyright (c) 2023-2024 Leah Rowe <leah@libreboot.org> +# Copyright (c) 2023-2025 Leah Rowe <leah@libreboot.org> -e6400_unpack="$PWD/src/bios_extract/dell_inspiron_1100_unpacker.py" -me7updateparser="$PWD/util/me7_update_parser/me7_update_parser.py" -pfs_extract="$PWD/src/biosutilities/Dell_PFS_Extract.py" -uefiextract="$PWD/elf/uefitool/uefiextract" -vendir="vendorfiles" -appdir="$vendir/app" -cbcfgsdir="config/coreboot" +# These are variables and functions, extending the functionality of +# inject.sh, to be used with lbmk; they are kept separate here, so that +# the main inject.sh can be as similar as possible between lbmk and cbmk, +# so that cherry-picking lbmk patches into cbmk yields fewer merge conflicts. -cv="CONFIG_HAVE_ME_BIN CONFIG_ME_BIN_PATH CONFIG_INCLUDE_SMSC_SCH5545_EC_FW \ - CONFIG_SMSC_SCH5545_EC_FW_FILE CONFIG_KBC1126_FIRMWARE CONFIG_KBC1126_FW1 \ - CONFIG_KBC1126_FW2 CONFIG_KBC1126_FW1_OFFSET CONFIG_KBC1126_FW2_OFFSET \ - CONFIG_VGA_BIOS_FILE CONFIG_VGA_BIOS_ID CONFIG_BOARD_DELL_E6400 \ - CONFIG_HAVE_MRC CONFIG_MRC_FILE CONFIG_HAVE_REFCODE_BLOB \ - CONFIG_REFCODE_BLOB_FILE CONFIG_GBE_BIN_PATH CONFIG_IFD_BIN_PATH" +# When reading this file, you should imagine that it is part of inject.sh, +# with inject.sh concatenated onto vendor.sh; they are inexorably intertwined. +# The main "mk" script sources vendor.sh first, and then inject.sh, in lbmk. -eval `setvars "" EC_url_bkup EC_hash DL_hash DL_url_bkup MRC_refcode_gbe vcfg \ +e6400_unpack="$xbmkpwd/src/bios_extract/dell_inspiron_1100_unpacker.py" +me7updateparser="$xbmkpwd/util/me7_update_parser/me7_update_parser.py" +pfs_extract="$xbmkpwd/src/biosutilities/Dell_PFS_Extract.py" +uefiextract="$xbmkpwd/elf/uefitool/uefiextract" +vendir="vendorfiles" +appdir="$vendir/app" +vfix="DO_NOT_FLASH_YET._FIRST,_INJECT_FILES_VIA_INSTRUCTIONS_ON_LIBREBOOT.ORG_" + +# lbmk-specific extension to the "cv" variable (not suitable for cbmk) +cvchk="CONFIG_INCLUDE_SMSC_SCH5545_EC_FW CONFIG_HAVE_MRC CONFIG_HAVE_ME_BIN \ + CONFIG_LENOVO_TBFW_BIN CONFIG_VGA_BIOS_FILE CONFIG_FSP_M_FILE \ + CONFIG_FSP_S_FILE CONFIG_KBC1126_FW1 CONFIG_KBC1126_FW2" + +# lbmk-specific extensions to the "cv" variable (not suitable for cbmk) +cvxbmk="CONFIG_ME_BIN_PATH CONFIG_SMSC_SCH5545_EC_FW_FILE CONFIG_FSP_FULL_FD \ + CONFIG_KBC1126_FW1_OFFSET CONFIG_KBC1126_FW2_OFFSET CONFIG_FSP_USE_REPO \ + CONFIG_VGA_BIOS_ID CONFIG_BOARD_DELL_E6400 CONFIG_FSP_S_CBFS \ + CONFIG_HAVE_REFCODE_BLOB CONFIG_REFCODE_BLOB_FILE CONFIG_FSP_FD_PATH \ + CONFIG_IFD_BIN_PATH CONFIG_MRC_FILE CONFIG_FSP_M_CBFS" + +# lbmk-specific extensions; mostly used for downloading vendor files +eval "`setvars "" has_hashes EC_hash DL_hash DL_url_bkup MRC_refcode_gbe vcfg \ E6400_VGA_DL_hash E6400_VGA_DL_url E6400_VGA_DL_url_bkup E6400_VGA_offset \ - E6400_VGA_romname SCH5545EC_DL_url_bkup SCH5545EC_DL_hash _dest tree \ - mecleaner kbc1126_ec_dump MRC_refcode_cbtree new_mac _dl SCH5545EC_DL_url \ - archive EC_url boarddir rom cbdir DL_url nukemode cbfstoolref vrelease \ - verify _7ztest ME_bootguard $cv` - -vendor_download() -{ - [ $# -gt 0 ] || $err "No argument given"; export PATH="$PATH:/sbin" - board="$1"; readcfg && readkconfig && bootstrap && getfiles; : -} - -readkconfig() + E6400_VGA_romname SCH5545EC_DL_url_bkup SCH5545EC_DL_hash _dest mecleaner \ + kbc1126_ec_dump MRC_refcode_cbtree _dl SCH5545EC_DL_url EC_url rom DL_url \ + nuke cbfstoolref FSPFD_hash _7ztest ME11bootguard ME11delta xromsize \ + ME11version ME11sku ME11pch _me _metmp mfs TBFW_url_bkup TBFW_url cbdir \ + TBFW_hash TBFW_size hashfile EC_url_bkup FSPM_bin_hash FSPS_bin_hash \ + EC_FW1_hash EC_FW2_hash ME_bin_hash MRC_bin_hash REF_bin_hash _dl_bin \ + SCH5545EC_bin_hash TBFW_bin_hash E6400_VGA_bin_hash _pre_dest`" + +download() { - check_defconfig "$boarddir" 1>"$TMPDIR/vendorcfg.list" && return 1 - - rm -f "$TMPDIR/tmpcbcfg" || $err "!rm -f \"$TMPDIR/tmpcbcfg\"" - while read -r cbcfgfile; do - for cbc in $cv; do - rm -f "$TMPDIR/tmpcbcfg2" || \ - $err "!rm $TMPDIR/tmpcbcfg2" - grep "$cbc" "$cbcfgfile" 1>"$TMPDIR/tmpcbcfg2" \ - 2>/dev/null || : - [ -f "$TMPDIR/tmpcbcfg2" ] || continue - cat "$TMPDIR/tmpcbcfg2" >> "$TMPDIR/tmpcbcfg" || \ - $err "!cat $TMPDIR/tmpcbcfg2" - done - done < "$TMPDIR/vendorcfg.list" - - eval `setcfg "$TMPDIR/tmpcbcfg"` - - for c in CONFIG_HAVE_MRC CONFIG_HAVE_ME_BIN CONFIG_KBC1126_FIRMWARE \ - CONFIG_VGA_BIOS_FILE CONFIG_INCLUDE_SMSC_SCH5545_EC_FW; do - eval "[ \"\${$c}\" = \"/dev/null\" ] && continue" - eval "[ -z \"\${$c}\" ] && continue" - eval `setcfg "config/vendor/$vcfg/pkg.cfg"`; return 0 - done - printf "Vendor files not needed for: %s\n" "$board" 1>&2; return 1 -} - -bootstrap() -{ - x_ ./mk -f coreboot ${cbdir##*/} - mk -b uefitool biosutilities bios_extract - [ -d "${kbc1126_ec_dump%/*}" ] && x_ make -C "$cbdir/util/kbc1126" - [ -n "$MRC_refcode_cbtree" ] && \ - cbfstoolref="elf/cbfstool/$MRC_refcode_cbtree/cbfstool" && \ - x_ ./mk -d coreboot $MRC_refcode_cbtree; return 0 + [ $# -gt 0 ] || err "No argument given" + export PATH="$PATH:/sbin" + board="$1" && check_target && readkconfig download } getfiles() { [ -z "$CONFIG_HAVE_ME_BIN" ] || fetch intel_me "$DL_url" \ - "$DL_url_bkup" "$DL_hash" "$CONFIG_ME_BIN_PATH" + "$DL_url_bkup" "$DL_hash" "$CONFIG_ME_BIN_PATH" curl "$ME_bin_hash" [ -z "$CONFIG_INCLUDE_SMSC_SCH5545_EC_FW" ] || fetch sch5545ec \ "$SCH5545EC_DL_url" "$SCH5545EC_DL_url_bkup" "$SCH5545EC_DL_hash" \ - "$CONFIG_SMSC_SCH5545_EC_FW_FILE" - [ -z "$CONFIG_KBC1126_FIRMWARE" ] || fetch kbc1126ec "$EC_url" \ - "$EC_url_bkup" "$EC_hash" "$CONFIG_KBC1126_FW1" + "$CONFIG_SMSC_SCH5545_EC_FW_FILE" "curl" "$SCH5545EC_bin_hash" + [ -z "$CONFIG_KBC1126_FW1" ] || fetch kbc1126ec "$EC_url" \ + "$EC_url_bkup" "$EC_hash" "$CONFIG_KBC1126_FW1" curl "$EC_FW1_hash" + [ -z "$CONFIG_KBC1126_FW2" ] || fetch kbc1126ec "$EC_url" \ + "$EC_url_bkup" "$EC_hash" "$CONFIG_KBC1126_FW2" curl "$EC_FW2_hash" [ -z "$CONFIG_VGA_BIOS_FILE" ] || fetch e6400vga "$E6400_VGA_DL_url" \ - "$E6400_VGA_DL_url_bkup" "$E6400_VGA_DL_hash" "$CONFIG_VGA_BIOS_FILE" + "$E6400_VGA_DL_url_bkup" "$E6400_VGA_DL_hash" \ + "$CONFIG_VGA_BIOS_FILE" "curl" "$E6400_VGA_bin_hash" [ -z "$CONFIG_HAVE_MRC" ] || fetch "mrc" "$MRC_url" "$MRC_url_bkup" \ - "$MRC_hash" "$CONFIG_MRC_FILE"; return 0 + "$MRC_hash" "$CONFIG_MRC_FILE" "curl" "$MRC_bin_hash" + [ -z "$CONFIG_REFCODE_BLOB_FILE" ] || fetch "refcode" "$MRC_url" \ + "$MRC_url_bkup" "$MRC_hash" "$CONFIG_REFCODE_BLOB_FILE" "curl" \ + "$REF_bin_hash" + [ -z "$CONFIG_LENOVO_TBFW_BIN" ] || fetch "tbfw" "$TBFW_url" \ + "$TBFW_url_bkup" "$TBFW_hash" "$CONFIG_LENOVO_TBFW_BIN" "curl" \ + "$TBFW_bin_hash" + [ -z "$CONFIG_FSP_M_FILE" ] || fetch "fsp" "$CONFIG_FSP_FD_PATH" \ + "$CONFIG_FSP_FD_PATH" "$FSPFD_hash" "$CONFIG_FSP_M_FILE" "copy" \ + "$FSPM_bin_hash" + [ -z "$CONFIG_FSP_S_FILE" ] || fetch "fsp" "$CONFIG_FSP_FD_PATH" \ + "$CONFIG_FSP_FD_PATH" "$FSPFD_hash" "$CONFIG_FSP_S_FILE" "copy" \ + "$FSPS_bin_hash"; : } fetch() { - dl_type="$1"; dl="$2"; dl_bkup="$3"; dlsum="$4"; _dest="${5##*../}" - [ "$5" = "/dev/null" ] && return 0; _dl="$XBMK_CACHE/file/$dlsum" - - download "$dl" "$dl_bkup" "$_dl" "$dlsum" - - rm -Rf "${_dl}_extracted" || $err "!rm -Rf ${_ul}_extracted" - e "$_dest" f && return 0 - - mkdir -p "${_dest%/*}" || $err "mkdirs: !mkdir -p ${_dest%/*}" - remkdir "$appdir"; extract_archive "$_dl" "$appdir" || \ - [ "$dl_type" = "e6400vga" ] || $err "mkd $_dest $dl_type: !extract" + dl_type="$1" + dl="$2" + dl_bkup="$3" + dlsum="$4" + _dest="${5##*../}" + _pre_dest="$XBMK_CACHE/tmpdl/check" || err "!fetch, mktemp, $*" + dlop="$6" + binsum="$7" + + [ "$5" = "/dev/null" ] && return 0 + _dl="$XBMK_CACHE/file/$dlsum" # internet file to extract from e.g. .exe + _dl_bin="$XBMK_CACHE/file/$binsum" # extracted file e.g. me.bin + + # an extracted vendor file will be placed in pre_dest first, for + # verifying its checksum. if it matches, it is later moved to _dest + remkdir "${_pre_dest%/*}" "$appdir" + + # HACK: if grabbing fsp from coreboot, fix the path for lbmk + [ "$dl_type" = "fsp" ] && for _cdl in dl dl_bkup; do + eval "$_cdl=\"\${$_cdl##*../}\"; _cdp=\"\$$_cdl\"" + [ -f "$_cdp" ] || _cdp="$cbdir/$_cdp" + [ -f "$_cdp" ] && eval "$_cdl=\"$_cdp\""; : + done; : + + # download the file (from the internet) to extract from + xbget "$dlop" "$dl" "$dl_bkup" "$_dl" "$dlsum" + x_ rm -Rf "${_dl}_extracted" + + # skip extraction if a cached extracted file exists + ( xbget copy "$_dl_bin" "$_dl_bin" "$_dest" "$binsum" 2>/dev/null ) || : + [ -f "$_dest" ] && return 0 + + x_ mkdir -p "${_dest%/*}" + [ "$dl_type" = "fsp" ] || extract_archive "$_dl" "$appdir" || \ + [ "$dl_type" = "e6400vga" ] || err "$_dest $dl_type: !extract" + + x_ extract_$dl_type "$_dl" "$appdir" + set -u -e + + # some functions don't output directly to the given file, _pre_dest. + # instead, they put multiple files there, but we need the one matching + # the given hashsum. So, search for a matching file via bruteforce: + ( fx_ "eval mkdst \"$binsum\"" x_ find "${_pre_dest%/*}" -type f ) || : + + bad_checksum "$binsum" "$_dest" || [ ! -f "$_dest" ] || return 0 + [ -z "$binsum" ] && printf "'%s': checksum undefined\n" "$_dest" 1>&2 + [ -L "$_dest" ] && printf "WARNING: '%s' is a link!\n" "$_dest" 1>&2 + [ -L "$_dest" ] || x_ rm -f "$_dest" + err "Could not safely extract '$_dest', for board '$board'" +} - eval "extract_$dl_type"; set -u -e - e "$_dest" f missing && $err "!extract_$dl_type"; : +mkdst() +{ + bad_checksum "$1" "$2" && x_ rm -f "$2" && return 0 + x_ mv "$2" "$_dl_bin" + x_ cp "$_dl_bin" "$_dest" + exit 1 } extract_intel_me() { - e "$mecleaner" f not && $err "$cbdir: me_cleaner missing" - - _me="$PWD/$_dest"; cdir="$PWD/$appdir" - if [ "$ME_bootguard" = "me11disreguard" ]; then - # run mkukri's util to extract me.bin and disable bootguard - # for Dell OptiPlex 3050 Micro, using the deguard util. - extract_deguard_me "$cdir" "$_me" - return 0 - fi - # All other ME setups are extracted with brute force and me_cleaner: - - [ $# -gt 0 ] && _me="${1}" && cdir="$2" + e "$mecleaner" f not && err "$cbdir: me_cleaner missing" - e "$_me" f && return 0 + _7ztest="$xbloc/metmp/a" + _metmp="$xbloc/me.bin" + x_ rm -f "$_metmp" "$xbloc/a" - sdir="$(mktemp -d)"; [ -z "$sdir" ] && return 0 - mkdir -p "$sdir" || $err "extract_intel_me: !mkdir -p \"$sdir\"" + mfs="" && [ "$ME11bootguard" = "y" ] && mfs="--whitelist MFS" && \ + chkvars ME11delta ME11version ME11sku ME11pch + [ "$ME11bootguard" = "y" ] && x_ ./mk -f deguard set +u +e + x_ rm -Rf "$xbmkpwd/metmp" + ( fx_ find_me x_ find "$xbmkpwd/$appdir" -type f ) || : + [ "$ME11bootguard" != "y" ] && x_ mv "$_metmp" "$_pre_dest" && return 0 + ( - [ "${cdir#/a}" != "$cdir" ] && cdir="${cdir#/}" - cd "$cdir" || $err "extract_intel_me: !cd \"$cdir\"" - for i in *; do - [ -f "$_me" ] && break - [ -L "$i" ] && continue - if [ -f "$i" ]; then - "$mecleaner" -r -t -O "$sdir/vendorfile" \ - -M "$_me" "$i" && break - "$mecleaner" -r -t -O "$_me" "$i" && break - "$me7updateparser" -O "$_me" "$i" && break - _7ztest="${_7ztest}a" - extract_archive "$i" "$_7ztest" || continue - extract_intel_me "$_me" "$cdir/$_7ztest" - elif [ -d "$i" ]; then - extract_intel_me "$_me" "$cdir/$i" - else - continue - fi - cdir="$1"; [ "${cdir#/a}" != "$cdir" ] && cdir="${cdir#/}" - cd "$cdir" || : - done - ) - rm -Rf "$sdir" || $err "extract_intel_me: !rm -Rf $sdir" + x_ cd src/deguard/ + x_ ./finalimage.py --delta "data/delta/$ME11delta" --version \ + "$ME11version" --pch "$ME11pch" --sku "$ME11sku" \ + --fake-fpfs data/fpfs/zero --input "$_metmp" --output "$_pre_dest" + ) || err "Error running deguard for $_dest"; : } -extract_deguard_me() +find_me() { - x_ ./mk -f deguard - cp -R src/deguard "$1/disreguard" || \ - $err "Cannot make temporary deguard clone in $1/disreguard" - if [ ! -e "$1/disreguard/.git" ]; then - git -C "$1/disreguard" init || $err "!init $1/disreguard" - git -C "$1/disreguard" add -A . || $err "!add $1/disreguard" - git -C "$1/disreguard" commit -m "tmp" || \ - $err "!commit $1/disreguard" - fi - git -C "$1/disreguard" am config/data/deguard/appdir.patch || \ - $err "Cannot temporarily patch deguard clone in $1/disreguard" - ( - cd "$1/disreguard" || $err "Cannot cd to '$1/disreguard'" - x_ ./RUNME.sh - ) - "$mecleaner" --whitelist MFS --truncate "$1/disreguard/me.bin" || \ - $err "extract_intel_me: Can't truncate disreguarded ME" - cp "$cdir/disreguard/me.bin" "$2" || \ - $err "extract_intel_me: Can't move disreguarded me.bin" + [ -f "$_metmp" ] && exit 1 + [ -L "$1" ] && return 0 + + _7ztest="${_7ztest}a" && _r="-r" && [ -n "$mfs" ] && _r="" + + "$mecleaner" $mfs $_r -t -O "$xbloc/a" -M "$_metmp" "$1" || \ + "$mecleaner" $mfs $_r -t -O "$_metmp" "$1" || "$me7updateparser" \ + -O "$_metmp" "$1" || extract_archive "$1" "$_7ztest" || return 0 + + [ -f "$_metmp" ] && exit 1 + ( fx_ find_me x_ find "$_7ztest" -type f ) || exit 1; : } extract_archive() { innoextract "$1" -d "$2" || python "$pfs_extract" "$1" -e || 7z x \ "$1" -o"$2" || unar "$1" -o "$2" || unzip "$1" -d "$2" || return 1 + + [ ! -d "${_dl}_extracted" ] || x_ cp -R "${_dl}_extracted" "$2"; : } extract_kbc1126ec() { - e "$kbc1126_ec_dump" f missing && $err "$cbdir: kbc1126 util missing" ( - x_ cd "$appdir/"; mv Rompaq/68*.BIN ec.bin || : - if [ ! -f "ec.bin" ]; then - unar -D ROM.CAB Rom.bin || unar -D Rom.CAB Rom.bin || \ - unar -D 68*.CAB Rom.bin || $err "can't extract Rom.bin" - x_ mv Rom.bin ec.bin - fi - [ -f ec.bin ] || $err "extract_kbc1126_ec $board: can't extract" - "$kbc1126_ec_dump" ec.bin || $err "!1126ec $board extract ecfw" - ) || $err "can't extract kbc1126 ec firmware" - - e "$appdir/ec.bin.fw1" f not && $err "$board: kbc1126ec fetch failed" - e "$appdir/ec.bin.fw2" f not && $err "$board: kbc1126ec fetch failed" - - cp "$appdir/"ec.bin.fw* "${_dest%/*}/" || $err "!cp 1126ec $_dest" + x_ cd "$appdir/" + mv Rompaq/68*.BIN ec.bin || unar -D ROM.CAB Rom.bin || unar -D \ + Rom.CAB Rom.bin || unar -D 68*.CAB Rom.bin || err "!kbc1126 unar" + [ -f "ec.bin" ] || x_ mv Rom.bin ec.bin + x_ e ec.bin f && x_ "$kbc1126_ec_dump" ec.bin + ) || err "$board: can't extract kbc1126 ec firmware" + + x_ e "$appdir/ec.bin.fw1" f && x_ e "$appdir/ec.bin.fw2" f + x_ cp "$appdir/"ec.bin.fw* "${_pre_dest%/*}/" } extract_e6400vga() @@ -205,11 +210,10 @@ extract_e6400vga() tail -c +$E6400_VGA_offset "$_dl" | gunzip > "$appdir/bios.bin" || : ( x_ cd "$appdir" - [ -f "bios.bin" ] || $err "extract_e6400vga: can't extract bios.bin" + x_ e "bios.bin" f "$e6400_unpack" bios.bin || printf "TODO: fix dell extract util\n" - ) || $err "can't extract e6400 vga rom" - cp "$appdir/$E6400_VGA_romname" "$_dest" || \ - $err "extract_e6400vga $board: can't copy vga rom to $_dest" + ) || err "can't extract e6400 vga rom" + x_ cp "$appdir/$E6400_VGA_romname" "$_pre_dest" } extract_sch5545ec() @@ -221,172 +225,178 @@ extract_sch5545ec() _sch5545ec_fw="$_sch5545ec_fw/54 D386BEB8-4B54-4E69-94F5-06091F67E0D3" _sch5545ec_fw="$_sch5545ec_fw/0 Raw section/body.bin" # <-- this! - "$uefiextract" "$_bios" || $err "sch5545 !extract" - cp "$_sch5545ec_fw" "$_dest" || $err "$_dest: !sch5545 copy" + x_ "$uefiextract" "$_bios" + x_ cp "$_sch5545ec_fw" "$_pre_dest" } -vendor_inject() +# Lenovo ThunderBolt firmware updates: +# https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/thinkpad-t-series-laptops/thinkpad-t480-type-20l5-20l6/20l5/solutions/ht508988 +extract_tbfw() { - set +u +e; [ $# -lt 1 ] && $err "No options specified." - [ "$1" = "listboards" ] && eval "ls -1 config/coreboot || :; exit 0" - - archive="$1"; while getopts n:r:b:m: option; do - case "$option" in - n) nukemode="$OPTARG" ;; - r) rom="$OPTARG" ;; - b) board="$OPTARG" ;; - m) new_mac="$OPTARG"; chkvars new_mac ;; - *) : ;; - esac - done - - check_board || return 0 - [ "$nukemode" = "nuke" ] || x_ ./vendor download $board - [ "$vrelease" != "y" ] && patch_rom "$rom" - [ "$vrelease" = "y" ] && patch_release_roms; : + chkvars TBFW_size + fx_ copytb x_ find "$appdir" -type f -name "TBT.bin" } -check_board() +copytb() { - failcheck="y" && check_release "$archive" && failcheck="n" - if [ "$failcheck" = "y" ]; then - [ -f "$rom" ] || $err "check_board \"$rom\": invalid path" - [ -z "${rom+x}" ] && $err "check_board: no rom specified" - [ -n "${board+x}" ] || board="$(detect_board "$rom")" - else - vrelease="y"; board="$(detect_board "$archive")" - fi - readcfg || return 1; return 0 + [ -f "$1" ] && [ ! -L "$1" ] && x_ dd if=/dev/null of="$1" bs=1 \ + seek=$TBFW_size && x_ mv "$1" "$_pre_dest" && return 1; : } -check_release() +extract_fsp() { - [ -f "$archive" ] || return 1 - [ "${archive##*.}" = "xz" ] || return 1 - printf "%s\n" "Release archive $archive detected" + x_ python "$cbdir/3rdparty/fsp/Tools/SplitFspBin.py" split -f "$1" \ + -o "${_pre_dest%/*}" -n "Fsp.fd" } -# This function tries to determine the board from the filename of the rom. -# It will only succeed if the filename is not changed from the build/download -detect_board() +setvfile() { - path="$1"; filename="$(basename "$path")" - case "$filename" in - grub_*|seagrub_*|custom_*) - board="$(echo "$filename" | cut -d '_' -f2-3)" ;; - seabios_withgrub_*) - board="$(echo "$filename" | cut -d '_' -f3-4)" ;; - *.tar.xz) _stripped_prefix="${filename#*_}" - board="${_stripped_prefix%.tar.xz}" ;; - *) $err "detect_board $filename: could not detect board type" - esac; printf "%s\n" "$board" + [ -n "$vcfg" ] && for c in $cvchk; do + vcmd="[ \"\${$c}\" != \"/dev/null\" ] && [ -n \"\${$c}\" ]" + eval "$vcmd && getvfile \"\$@\" && return 0" + done && return 1; : } -readcfg() +getvfile() { - if [ "$board" = "serprog_rp2040" ] || \ - [ "$board" = "serprog_stm32" ]; then - return 1 - fi; boarddir="$cbcfgsdir/$board" - eval `setcfg "$boarddir/target.cfg"`; chkvars vcfg tree + eval "`setcfg "config/vendor/$vcfg/pkg.cfg" 1`" + bootstrap && [ $# -gt 0 ] && getfiles && return 0 # download + fx_ prep x_ find "$tmpromdir" -maxdepth 1 -type f -name "*.rom" + ( check_vendor_hashes ) || err "$archive: Can't verify hashes"; : +} +bootstrap() +{ cbdir="src/coreboot/$tree" - cbfstool="elf/cbfstool/$tree/cbfstool" - mecleaner="$PWD/$cbdir/util/me_cleaner/me_cleaner.py" - kbc1126_ec_dump="$PWD/$cbdir/util/kbc1126/kbc1126_ec_dump" - cbfstool="elf/cbfstool/$tree/cbfstool" - ifdtool="elf/ifdtool/$tree/ifdtool" + mecleaner="$xbmkpwd/$cbdir/util/me_cleaner/me_cleaner.py" + kbc1126_ec_dump="$xbmkpwd/$cbdir/util/kbc1126/kbc1126_ec_dump" + cbfstool="elf/coreboot/$tree/cbfstool" + rmodtool="elf/coreboot/$tree/rmodtool" - x_ ./mk -d coreboot $tree + x_ ./mk -f coreboot "${cbdir##*/}" + fx_ "x_ ./mk -b" printf "uefitool\nbiosutilities\nbios_extract\n" + [ -d "${kbc1126_ec_dump%/*}" ] && x_ make -C "$cbdir/util/kbc1126" + [ -n "$MRC_refcode_cbtree" ] && \ + cbfstoolref="elf/coreboot/$MRC_refcode_cbtree/cbfstool" && \ + x_ ./mk -d coreboot "$MRC_refcode_cbtree"; : } -patch_release_roms() +prep() { - remkdir "tmp/romdir"; tar -xf "$archive" -C "tmp/romdir" || \ - $err "patch_release_roms: !tar -xf \"$archive\" -C \"tmp/romdir\"" + _xrom="$1" + _xromname="${1##*/}" + _xromnew="${_xrom%/*}/${_xromname#"$vfix"}" + [ "$nuke" = "nuke" ] && _xromnew="${_xrom%/*}/$vfix${_xrom##*/}" - for x in "tmp/romdir/bin/"*/*.rom ; do - patch_rom "$x" - done + e "$_xrom" f missing && return 0 + [ -z "${_xromname#"$vfix"}" ] && err "$_xromname / $vfix: name match" - ( - cd "tmp/romdir/bin/"* || $err "patch roms: !cd tmp/romdir/bin/*" - - # NOTE: For compatibility with older rom releases, defer to sha1 - [ "$verify" != "y" ] || [ "$nukemode" = "nuke" ] || \ - sha512sum --status -c vendorhashes || \ - sha1sum --status -c vendorhashes || sha512sum --status -c \ - blobhashes || sha1sum --status -c blobhashes || \ - $err "patch_release_roms: ROMs did not match expected hashes" - ) || $err "can't verify vendor hashes" - - [ -n "$new_mac" ] && for x in "tmp/romdir/bin/"*/*.rom ; do - [ -f "$x" ] && modify_gbe "$x" - done - - x_ mkdir -p bin/release - mv tmp/romdir/bin/* bin/release/ || $err "$board: !mv release roms" + # Remove the prefix and 1-byte pad + if [ "$nuke" != "nuke" ] && \ + [ "${_xromname#"$vfix"}" != "$_xromname" ]; then + xromsize="$(expr $(stat -c '%s' "$_xrom") - 1)" || err "!int" + [ $xromsize -lt 524288 ] && err "too small, $xromsize: $_xrom" + + x_ dd if="$_xrom" of="$_xromnew" bs=$xromsize count=1 + x_ rm -f "$_xrom" + + _xrom="$_xromnew" + fi + + [ "$nuke" != "nuke" ] || ( mksha512 "$_xrom" "vendorhashes" ) || err + + add_vfiles "$_xrom" || return 1 # if break return, can still change MAC + [ "$nuke" != "nuke" ] && return 0 + + # Rename the file, prefixing a warning saying not to flash + cat "$_xrom" config/data/coreboot/0 > "$_xromnew" || err "!pad $_xrom" + x_ rm -f "$_xrom" +} + +mksha512() +{ + [ "${1%/*}" != "$1" ] && x_ cd "${1%/*}" + sha512sum ./"${1##*/}" >> "$2" || err "!sha512sum \"$1\" > \"$2\"" } -patch_rom() +add_vfiles() { rom="$1" - readkconfig || exit 0 - [ "$CONFIG_HAVE_MRC" = "y" ] && inject "mrc.bin" "$CONFIG_MRC_FILE" \ - "mrc" "0xfffa0000" - [ -n "$CONFIG_HAVE_REFCODE_BLOB" ] && inject "fallback/refcode" \ + if [ "$has_hashes" != "y" ] && [ "$nuke" != "nuke" ]; then + printf "'%s' has no hash file. Skipping.\n" "$archive" 1>&2 + return 1 + elif [ "$has_hashes" = "y" ] && [ "$nuke" = "nuke" ]; then + printf "'%s' has a hash file. Skipping nuke.\n" "$archive" 1>&2 + return 1 + fi + + [ -n "$CONFIG_HAVE_REFCODE_BLOB" ] && vfile "fallback/refcode" \ "$CONFIG_REFCODE_BLOB_FILE" "stage" - [ "$CONFIG_HAVE_ME_BIN" = "y" ] && inject IFD "$CONFIG_ME_BIN_PATH" me - [ "$CONFIG_KBC1126_FIRMWARE" = "y" ] && inject ecfw1.bin \ - "$CONFIG_KBC1126_FW1" raw "$CONFIG_KBC1126_FW1_OFFSET" && inject \ - ecfw2.bin "$CONFIG_KBC1126_FW2" raw "$CONFIG_KBC1126_FW2_OFFSET" + [ "$CONFIG_HAVE_MRC" = "y" ] && vfile "mrc.bin" "$CONFIG_MRC_FILE" \ + "mrc" "0xfffa0000" + [ "$CONFIG_HAVE_ME_BIN" = "y" ] && vfile IFD "$CONFIG_ME_BIN_PATH" me + [ -n "$CONFIG_KBC1126_FW1" ] && vfile ecfw1.bin \ + "$CONFIG_KBC1126_FW1" raw "$CONFIG_KBC1126_FW1_OFFSET" + [ -n "$CONFIG_KBC1126_FW2" ] && vfile ecfw2.bin \ + "$CONFIG_KBC1126_FW2" raw "$CONFIG_KBC1126_FW2_OFFSET" [ -n "$CONFIG_VGA_BIOS_FILE" ] && [ -n "$CONFIG_VGA_BIOS_ID" ] && \ - inject "pci$CONFIG_VGA_BIOS_ID.rom" "$CONFIG_VGA_BIOS_FILE" optionrom + vfile "pci$CONFIG_VGA_BIOS_ID.rom" "$CONFIG_VGA_BIOS_FILE" optionrom [ "$CONFIG_INCLUDE_SMSC_SCH5545_EC_FW" = "y" ] && \ [ -n "$CONFIG_SMSC_SCH5545_EC_FW_FILE" ] && \ - inject sch5545_ecfw.bin "$CONFIG_SMSC_SCH5545_EC_FW_FILE" raw - [ -n "$new_mac" ] && [ "$vrelease" != "y" ] && modify_gbe "$rom" + vfile sch5545_ecfw.bin "$CONFIG_SMSC_SCH5545_EC_FW_FILE" raw + [ -z "$CONFIG_FSP_USE_REPO" ] && [ -z "$CONFIG_FSP_FULL_FD" ] && \ + [ -n "$CONFIG_FSP_M_FILE" ] && \ + vfile "$CONFIG_FSP_M_CBFS" "$CONFIG_FSP_M_FILE" fsp --xip + [ -z "$CONFIG_FSP_USE_REPO" ] && [ -z "$CONFIG_FSP_FULL_FD" ] && \ + [ -n "$CONFIG_FSP_S_FILE" ] && \ + vfile "$CONFIG_FSP_S_CBFS" "$CONFIG_FSP_S_FILE" fsp printf "ROM image successfully patched: %s\n" "$rom" + xchanged="y" } -inject() +vfile() { - [ $# -lt 3 ] && $err "$@, $rom: usage: inject name path type (offset)" - [ "$2" = "/dev/null" ] && return 0; verify="y" + [ "$2" = "/dev/null" ] && return 0 - eval `setvars "" cbfsname _dest _t _offset` - cbfsname="$1"; _dest="${2##*../}"; _t="$3" + cbfsname="$1" + _dest="${2##*../}" + _t="$3" - [ $# -gt 3 ] && _offset="-b $4" && [ -z "$4" ] && \ - $err "inject $@, $rom: offset passed, but empty (not defined)" + _offset="" + + if [ "$_t" = "fsp" ] && [ $# -gt 3 ]; then + _offset="$4" + elif [ $# -gt 3 ] && _offset="-b $4" && [ -z "$4" ]; then + err "vfile $*, $rom: offset given but empty (undefined)" + fi - e "$_dest" f n && [ "$nukemode" != "nuke" ] && $err "!inject $dl_type" + [ "$nuke" = "nuke" ] || x_ e "$_dest" f if [ "$cbfsname" = "IFD" ]; then - [ "$nukemode" = "nuke" ] || "$ifdtool" -i $_t:$_dest "$rom" \ - -O "$rom" || $err "failed: inject '$_t' '$_dest' on '$rom'" - [ "$nukemode" != "nuke" ] || "$ifdtool" --nuke $_t "$rom" \ - -O "$rom" || $err "$rom: can't nuke $_t in IFD"; return 0 - elif [ "$nukemode" = "nuke" ]; then - "$cbfstool" "$rom" remove -n "$cbfsname" || \ - $err "inject $rom: can't remove $cbfsname"; return 0 + [ "$nuke" = "nuke" ] || x_ "$ifdtool" $ifdprefix -i \ + $_t:$_dest "$rom" -O "$rom" + [ "$nuke" != "nuke" ] || x_ "$ifdtool" $ifdprefix --nuke \ + $_t "$rom" -O "$rom" + elif [ "$nuke" = "nuke" ]; then + x_ "$cbfstool" "$rom" remove -n "$cbfsname" + elif [ "$_t" = "stage" ]; then # the only stage we handle is refcode + x_ rm -f "$xbloc/refcode" + x_ "$rmodtool" -i "$_dest" -o "$xbloc/refcode" + x_ "$cbfstool" "$rom" add-stage -f "$xbloc/refcode" \ + -n "$cbfsname" -t stage + else + x_ "$cbfstool" "$rom" add -f "$_dest" -n "$cbfsname" \ + -t $_t $_offset fi - [ "$_t" != "stage" ] || "$cbfstool" "$rom" add-stage -f \ - "$_dest" -n "$cbfsname" -t stage -c lzma || $err "$rom: !add ref" - [ "$_t" = "stage" ] || "$cbfstool" "$rom" add -f "$_dest" \ - -n "$cbfsname" -t $_t $_offset || $err "$rom !add $_t ($_dest)"; : + xchanged="y"; : } -modify_gbe() +check_vendor_hashes() { - chkvars CONFIG_GBE_BIN_PATH - - e "${CONFIG_GBE_BIN_PATH##*../}" f n && $err "missing gbe file" - x_ make -C util/nvmutil - - x_ cp "${CONFIG_GBE_BIN_PATH##*../}" "$TMPDIR/gbe" - x_ "util/nvmutil/nvm" "$TMPDIR/gbe" setmac $new_mac - x_ "$ifdtool" -i GbE:"$TMPDIR/gbe" "$1" -O "$1" + x_ cd "$tmpromdir" + [ "$has_hashes" = "n" ] || [ "$nuke" = "nuke" ] || sha512sum \ + --status -c "$hashfile" || x_ sha1sum --status -c "$hashfile" + x_ rm -f "$hashfile" } |