mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 14:02:52 +02:00
6ebab10caa
in shell scripts, a function named the same as a program included in the $PATH will override that program. for example, you could make a function called ls() and this would override the standand "ls". in lbmk, a part of it was first trying to run the "fail" command, deferring to "err", because some scripts call fail() which does some minor cleanup before calling err. in most cases, fail() is not defined, and it's possible that the user could have a program called "fail" in their $PATH, the behaviour of which we could not determine, and it could have disastrous effects. lbmk error handling has been re-engineered in such a way that the err function is defined in a variable, which defaults to err_ which calls err_, so defined under include/err.sh. in functions that require cleanup prior to error handling, a fail() function is still defined, and err is overridden, thus: err="fail" this change has made xx_() obsolete, so now only x_ is used. the x_ function is a wrapper that can be used to run a command and exit with non-zero status (from lbmk) if the command fails. the xx_ command did the same thing, but called fail() which would have called err(); now everything is $err example: rm -f "$filename" || err "could not delete file" this would now be: rm -f "$filename" || $err "could not delete file" overriding of err= must be done *after* including err.sh. for example: err="fail" . "include/err.sh" ^ this is wrong. instead, one must do: . "include/err.sh" err="fail" this is because err is set as a global variable under err.sh the new error handling is much cleaner, and safer. it also reduces the chance of mistakes such as: calling err when you meant to call fail. this is because the standard way is now to call $err, so you set err="fail" at the top of the script and all is well. Signed-off-by: Leah Rowe <leah@libreboot.org>
267 lines
8.5 KiB
Bash
Executable File
267 lines
8.5 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
# SPDX-FileCopyrightText: 2022 Caleb La Grange <thonkpeasant@protonmail.com>
|
|
# SPDX-FileCopyrightText: 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
|
|
# SPDX-FileCopyrightText: 2023-2024 Leah Rowe <leah@libreboot.org>
|
|
|
|
. "include/err.sh"
|
|
. "include/option.sh"
|
|
. "include/mrc.sh"
|
|
|
|
export PATH="${PATH}:/sbin"
|
|
|
|
_ua="Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0"
|
|
_7ztest="a"
|
|
|
|
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}/src/uefitool/uefiextract"
|
|
|
|
eval "$(setvars "" _b _dl EC_url EC_url_bkup EC_hash DL_hash DL_url DL_url_bkup \
|
|
E6400_VGA_DL_hash E6400_VGA_DL_url E6400_VGA_DL_url_bkup E6400_VGA_offset \
|
|
E6400_VGA_romname SCH5545EC_DL_url SCH5545EC_DL_url_bkup SCH5545EC_DL_hash \
|
|
tree mecleaner kbc1126_ec_dump MRC_refcode_cbtree cbfstoolref MRC_refcode_gbe)"
|
|
|
|
main()
|
|
{
|
|
[ $# -gt 0 ] || $err "No argument given"
|
|
board="${1}"
|
|
boarddir="${cbcfgsdir}/${board}"
|
|
_b="${board%%_*mb}" # shorthand (no duplication per rom size)
|
|
|
|
check_defconfig "${boarddir}" && exit 0
|
|
detect_firmware && exit 0
|
|
scan_config "${_b}" "config/vendor"
|
|
|
|
build_dependencies
|
|
download_vendorfiles
|
|
}
|
|
|
|
detect_firmware()
|
|
{
|
|
_cfg_exists="n"
|
|
for _chk_file in "${boarddir}/config/"*; do
|
|
[ -f "${_chk_file}" ] && _cfg_exists="y" && break
|
|
done
|
|
[ "${_cfg_exists}" = "n" ] && return 1
|
|
|
|
set -- "${boarddir}/config/"*
|
|
. "${1}" 2>/dev/null
|
|
. "${boarddir}/target.cfg" 2>/dev/null
|
|
[ -z "$tree" ] && $err "detect_firmware $boarddir: tree undefined"
|
|
cbdir="src/coreboot/$tree"
|
|
cbfstool="cbutils/$tree/cbfstool"
|
|
|
|
mecleaner="${PWD}/${cbdir}/util/me_cleaner/me_cleaner.py"
|
|
kbc1126_ec_dump="${PWD}/${cbdir}/util/kbc1126/kbc1126_ec_dump"
|
|
|
|
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 "[ -z \"\${${c}}\" ] || return 1"
|
|
done
|
|
printf "Vendor files not needed for: %s\n" "${board}" 1>&2
|
|
}
|
|
|
|
build_dependencies()
|
|
{
|
|
[ -d "${cbdir}" ] || x_ ./update trees -f coreboot ${cbdir##*/}
|
|
for d in uefitool biosutilities bios_extract; do
|
|
[ -d "src/${d}" ] && continue
|
|
x_ ./update trees -f "${d}"
|
|
done
|
|
[ -f "${uefiextract}" ] || x_ ./update trees -b uefitool
|
|
[ ! -d "${kbc1126_ec_dump%/*}" ] || [ -f "${kbc1126_ec_dump}" ] || x_ \
|
|
make -C "${cbdir}/util/kbc1126"
|
|
[ -n "$MRC_refcode_cbtree" ] && \
|
|
cbfstoolref="cbutils/$MRC_refcode_cbtree/cbfstool"
|
|
[ -z "$cbfstoolref" ] || [ -f "$cbfstoolref" ] || \
|
|
x_ ./update trees -b coreboot utils $MRC_refcode_cbtree
|
|
[ -f "${cbfstool}" ] && [ -f "${ifdtool}" ] && return 0
|
|
x_ ./update trees -b coreboot utils $tree
|
|
}
|
|
|
|
download_vendorfiles()
|
|
{
|
|
[ -z "${CONFIG_HAVE_ME_BIN}" ] || \
|
|
fetch intel_me "$DL_url" "$DL_url_bkup" "$DL_hash" \
|
|
"${CONFIG_ME_BIN_PATH}"
|
|
[ -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}"
|
|
[ -z "${CONFIG_VGA_BIOS_FILE}" ] || \
|
|
fetch "e6400vga" "$E6400_VGA_DL_url" "$E6400_VGA_DL_url_bkup" \
|
|
"$E6400_VGA_DL_hash" "$CONFIG_VGA_BIOS_FILE"
|
|
[ -z "${CONFIG_HAVE_MRC}" ] && return 0
|
|
fetch "mrc" "$MRC_url" "$MRC_url_bkup" "$MRC_hash" "$CONFIG_MRC_FILE"
|
|
|
|
# in case only mrc downloaded before, in a pair of mrc/refcode:
|
|
[ -n "$CONFIG_REFCODE_BLOB_FILE" ] && fetch "ref" "$MRC_url" \
|
|
"$MRC_url_bkup" "$MRC_hash" "$CONFIG_REFCODE_BLOB_FILE"; return 0
|
|
}
|
|
|
|
fetch()
|
|
{
|
|
dl_type="${1}"
|
|
dl="${2}"
|
|
dl_bkup="${3}"
|
|
dlsum="${4}"
|
|
[ "${5}" = "/dev/null" ] && return 0
|
|
[ "${5# }" = "$5" ] || $err "fetch: space not allowed in _dest: '$5'"
|
|
[ "${5#/}" = "$5" ] || $err "fetch: absolute path not allowed: '$5'"
|
|
_dest="${5##*../}"
|
|
_dl="${vendir}/cache/${dlsum}"
|
|
dl_fail="n"
|
|
|
|
x_ mkdir -p "${_dl%/*}"
|
|
|
|
dl_fail="y"
|
|
vendor_checksum "${dlsum}" "${_dl}" || dl_fail="n"
|
|
for url in "${dl}" "${dl_bkup}"; do
|
|
[ "${dl_fail}" = "n" ] && break
|
|
[ -z "${url}" ] && continue
|
|
x_ rm -f "${_dl}"
|
|
curl --location --retry 3 -A "$_ua" "$url" -o "$_dl" || \
|
|
wget --tries 3 -U "$_ua" "$url" -O "$_dl" || continue
|
|
vendor_checksum "${dlsum}" "${_dl}" || dl_fail="n"
|
|
done
|
|
[ "${dl_fail}" = "y" ] && \
|
|
$err "fetch ${dlsum}: matched file unavailable"
|
|
|
|
x_ rm -Rf "${_dl}_extracted"
|
|
mkdirs "${_dest}" "extract_${dl_type}" || return 0
|
|
eval "extract_${dl_type}"
|
|
|
|
[ -f "${_dest}" ] && return 0
|
|
$err "extract_${dl_type} (fetch): missing file: '${_dest}'"
|
|
}
|
|
|
|
vendor_checksum()
|
|
{
|
|
[ "$(sha512sum "$2" | awk '{print $1}')" != "$1" ] || return 1
|
|
printf "Bad checksum for file: %s\n" "$2" 1>&2
|
|
rm -f "$2" || :
|
|
}
|
|
|
|
mkdirs()
|
|
{
|
|
if [ -f "${1}" ]; then
|
|
printf "mkdirs %s %s: already downloaded\n" "$1" "$2" 1>&2
|
|
return 1
|
|
fi
|
|
mkdir -p "${1%/*}" || $err "mkdirs: !mkdir -p ${1%/*}"
|
|
remkdir "${appdir}"
|
|
extract_archive "${_dl}" "${appdir}" || \
|
|
[ "${2}" = "extract_e6400vga" ] || \
|
|
$err "mkdirs ${1} ${2}: !extract"
|
|
}
|
|
|
|
extract_intel_me()
|
|
{
|
|
[ ! -f "$mecleaner" ] && \
|
|
$err "extract_intel_me $cbdir: me_cleaner missing"
|
|
|
|
_me="${PWD}/${_dest}" # must always be an absolute path
|
|
cdir="${PWD}/${appdir}" # must always be an absolute path
|
|
[ $# -gt 0 ] && _me="${1}" && cdir="${2}"
|
|
[ -f "${_me}" ] && return 0
|
|
|
|
sdir="$(mktemp -d)"
|
|
mkdir -p "$sdir" || $err "extract_intel_me: !mkdir -p \"$sdir\""
|
|
(
|
|
[ "${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}"
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
extract_kbc1126ec()
|
|
{
|
|
[ ! -f "$kbc1126_ec_dump" ] && \
|
|
$err "extract_kbc1126ec $cbdir: kbc1126_ec_dump 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 "extract_kbc1126_ec ${board}: can't extract ecfw1/2.bin"
|
|
) || $err "can't extract kbc1126 ec firmware"
|
|
ec_ex="y"
|
|
for i in 1 2; do
|
|
[ -f "${appdir}/ec.bin.fw${i}" ] || ec_ex="n"
|
|
done
|
|
[ "${ec_ex}" = "y" ] || \
|
|
$err "extract_kbc1126_ec ${board}: didn't extract ecfw1/2.bin"
|
|
cp "${appdir}/"ec.bin.fw* "${_dest%/*}/" || \
|
|
$err "extract_kbc1126_ec ${board}: can't copy ec binaries"
|
|
}
|
|
|
|
extract_e6400vga()
|
|
{
|
|
for v in E6400_VGA_offset E6400_VGA_romname; do
|
|
eval "[ -z \"\$$v\" ] && $err \"extract_e6400vga: $v undefined\""
|
|
done
|
|
tail -c +$E6400_VGA_offset "$_dl" | gunzip > "$appdir/bios.bin" || :
|
|
(
|
|
x_ cd "${appdir}"
|
|
[ -f "bios.bin" ] || $err "extract_e6400vga: can't extract bios.bin"
|
|
"${e6400_unpack}" bios.bin || printf "TODO: fix dell extract util\n"
|
|
[ -f "${E6400_VGA_romname}" ] || \
|
|
$err "extract_e6400vga: can't extract vga rom from bios.bin"
|
|
) || $err "can't extract e6400 vga rom"
|
|
cp "${appdir}/${E6400_VGA_romname}" "${_dest}" || \
|
|
$err "extract_e6400vga ${board}: can't copy vga rom to ${_dest}"
|
|
}
|
|
|
|
extract_sch5545ec()
|
|
{
|
|
# full system ROM (UEFI), to extract with UEFIExtract:
|
|
_bios="${_dl}_extracted/Firmware/1 ${dlsum} -- 1 System BIOS vA.28.bin"
|
|
# this is the SCH5545 firmware, inside of the extracted UEFI ROM:
|
|
_sch5545ec_fw="${_bios}.dump/4 7A9354D9-0468-444A-81CE-0BF617D890DF"
|
|
_sch5545ec_fw="${_sch5545ec_fw}/54 D386BEB8-4B54-4E69-94F5-06091F67E0D3"
|
|
_sch5545ec_fw="${_sch5545ec_fw}/0 Raw section/body.bin" # <-- this!
|
|
|
|
# this makes the file defined by _sch5545ec_fw available to copy
|
|
"${uefiextract}" "${_bios}" || \
|
|
$err "extract_sch5545ec: cannot extract from uefi image"
|
|
cp "${_sch5545ec_fw}" "${_dest}" || \
|
|
$err "extract_sch5545ec: cannot copy sch5545ec firmware file"
|
|
}
|
|
|
|
main $@
|