mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 14:02:52 +02:00
560642c585
i downloaded this file from git manually at some point, when rebasing changes (i think it was the ec ones) the logic in the file is correct but i forgot to mark it executable without this commit, lbmk fails utterly, on all the newer intel boards
334 lines
7.2 KiB
Bash
Executable File
334 lines
7.2 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
|
|
# SPDX-FileCopyrightText: 2022 Caleb La Grange <thonkpeasant@protonmail.com>
|
|
# SPDX-FileCopyrightText: 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
|
|
# SPDX-FileCopyrightText: 2023 Leah Rowe <info@minifree.org>
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
ec_url=""
|
|
ec_url_bkup=""
|
|
ec_hash=""
|
|
|
|
blobdir="blobs"
|
|
dl_path="${blobdir}/vendorupdate"
|
|
appdir="${blobdir}/app"
|
|
_7ztest="a"
|
|
mecleaner="$(pwd)/me_cleaner/me_cleaner.py"
|
|
me7updateparser="$(pwd)/resources/blobs/me7_update_parser.py"
|
|
kbc1126_ec_dump="$(pwd)/coreboot/default/util/kbc1126/kbc1126_ec_dump"
|
|
board="${1}"
|
|
# A shorthand for each board, to avoid duplicating configs per flash size
|
|
board_short=${board%%_*mb}
|
|
|
|
set -- "resources/coreboot/${board}/config/*"
|
|
. ${1} 2>/dev/null
|
|
. "resources/coreboot/${board}/board.cfg"
|
|
|
|
if [ "${CONFIG_HAVE_MRC}" = "y" ]; then
|
|
printf 'haswell board detected, downloading mrc\n'
|
|
needs="${needs} MRC"
|
|
fi
|
|
|
|
if [ "${CONFIG_HAVE_IFD_BIN}" = "y" ]; then
|
|
printf 'board needs intel firmware descriptor\n'
|
|
needs="${needs} IFD"
|
|
fi
|
|
|
|
if [ "${CONFIG_HAVE_ME_BIN}" = "y" ]; then
|
|
printf 'board needs intel management engine\n'
|
|
needs="${needs} ME"
|
|
fi
|
|
|
|
if [ "${CONFIG_HAVE_GBE_BIN}" = "y" ]; then
|
|
printf 'board needs gigabit ethernet firmware\n'
|
|
needs="${needs} GBE"
|
|
fi
|
|
|
|
if [ "${CONFIG_KBC1126_FIRMWARE}" = "y" ]; then
|
|
printf "HP board with KBC1126 EC detected, downloading ec\n"
|
|
needs="${needs} EC"
|
|
fi
|
|
|
|
# Quickly exit without wasting more time if there are no blobs needed (GM45)
|
|
if [ -z ${needs+x} ]; then
|
|
printf 'No binary blobs needed for this board\n'
|
|
exit 0
|
|
fi
|
|
|
|
while read -r line ; do
|
|
case ${line} in
|
|
EC_url*)
|
|
set ${line}
|
|
ec_url=${2}
|
|
;;
|
|
EC_url_bkup*)
|
|
set ${line}
|
|
ec_url_bkup=${2}
|
|
;;
|
|
EC_hash*)
|
|
set ${line}
|
|
ec_hash=${2}
|
|
;;
|
|
DL_hash*)
|
|
set ${line}
|
|
dl_hash=${2}
|
|
;;
|
|
DL_url*)
|
|
set ${line}
|
|
dl_url=${2}
|
|
;;
|
|
DL_url_bkup*)
|
|
set ${line}
|
|
dl_url_bkup=${2}
|
|
;;
|
|
esac
|
|
done << EOF
|
|
$(eval "awk ' /\{.*${board_short}.*}{/ {flag=1;next} /\}/{flag=0} flag { print }' resources/blobs/sources")
|
|
EOF
|
|
|
|
Main() {
|
|
Build_deps
|
|
Download_needed
|
|
}
|
|
|
|
Fail(){
|
|
printf "\nERROR: $@\n"
|
|
exit 1
|
|
}
|
|
|
|
Build_deps(){
|
|
if [ ! -d me_cleaner ]; then
|
|
printf "downloading me_cleaner\n"
|
|
./download me_cleaner || Fail 'could not download me_cleaner'
|
|
fi
|
|
|
|
if [ ! -d coreboot/default ]; then
|
|
printf "downloading coreboot\n"
|
|
./download coreboot default || Fail 'could not download coreboot'
|
|
fi
|
|
|
|
if [ ! -f coreboot/default/util/kbc1126/kbc1126_ec_dump ]; then
|
|
printf "Building kbc1126_ec_dump from coreboot\n"
|
|
make -BC coreboot/default/util/kbc1126 || Fail \
|
|
"could not build kbc1126_ec_dump"
|
|
fi
|
|
|
|
if [ ! -f "coreboot/default/util/ifdtool/ifdtool" ]; then
|
|
printf "building ifdtool from coreboot\n"
|
|
make -C coreboot/default/util/ifdtool || Fail 'could not build ifdtool'
|
|
fi
|
|
}
|
|
|
|
Download_needed(){
|
|
for need in ${needs}; do
|
|
case ${need} in
|
|
*ME*)
|
|
Download_me || _failed="${_failed} me"
|
|
;;
|
|
*MRC*)
|
|
./download mrc || _failed="${_failed} mrc"
|
|
;;
|
|
*EC*)
|
|
Download_ec || _failed="${_failed} ec"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ ! -z ${_failed+x} ]; then
|
|
Fail "failed to obtain ${_failed}\nYou may try manually extracting blobs with './blobutil extract'"
|
|
fi
|
|
}
|
|
|
|
Download_me() {
|
|
printf "Downloading neutered ME for board: %s\n" ${board}
|
|
|
|
Fetch_update me || return 1
|
|
Extract_me || return 1
|
|
|
|
return 0
|
|
}
|
|
|
|
Extract_me(){
|
|
printf "Extracting neutered ME for ${board}\n"
|
|
|
|
_me_destination=${CONFIG_ME_BIN_PATH#../../}
|
|
|
|
if [ ! -d "${_me_destination%/*}" ]; then
|
|
mkdir -p ${_me_destination%/*}
|
|
fi
|
|
|
|
if [ -d "${appdir}" ]; then
|
|
rm -r ${appdir}
|
|
fi
|
|
|
|
if [ -f "${_me_destination}" ]; then
|
|
printf 'me already downloaded\n'
|
|
return 0
|
|
fi
|
|
|
|
printf 'extracting and stripping intel management engine\n'
|
|
innoextract ${dl_path} -d ${blobdir} \
|
|
|| 7z x ${dl_path} -o${appdir} \
|
|
|| Fail 'could not extract me executable with innoextract'
|
|
|
|
Bruteforce_extract_me "$(pwd)/${_me_destination}" "$(pwd)/${appdir}" \
|
|
|| return 1
|
|
|
|
printf "Truncated and cleaned me output to ${_me_destination}\n"
|
|
return 0
|
|
}
|
|
|
|
# cursed, carcinogenic code. TODO rewrite it better
|
|
Bruteforce_extract_me() {
|
|
_me_destination="${1}"
|
|
cdir="${2}" # must be an absolute path, not relative
|
|
|
|
if [ -f "${_me_destination}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
sdir="$(mktemp -d)"
|
|
mkdir -p "${sdir}" || return 1
|
|
|
|
(
|
|
printf "Entering %s\n" "${cdir}"
|
|
cd "${cdir}" || exit 1
|
|
for i in *; do
|
|
if [ -f "${_me_destination}" ]; then
|
|
# me.bin found, so avoid needless further traversal
|
|
break
|
|
elif [ -L "${i}" ]; then
|
|
# symlinks are a security risk, in this context
|
|
continue
|
|
elif [ -f "${i}" ]; then
|
|
"${mecleaner}" -r -t -O "${sdir}/vendorfile" -M "${_me_destination}" "${i}" \
|
|
&& break # (we found me.bin)
|
|
"${mecleaner}" -r -t -O "${_me_destination}" "${i}" \
|
|
&& break # (we found me.bin)
|
|
"${me7updateparser}" -O ${_me_destination} "${i}" \
|
|
&& break
|
|
_7ztest="${_7ztest}a"
|
|
7z x "${i}" -o${_7ztest} || continue
|
|
Bruteforce_extract_me "${_me_destination}" "${cdir}/${_7ztest}"
|
|
cdir="${1}"
|
|
cd "${cdir}"
|
|
elif [ -d "$i" ]; then
|
|
Bruteforce_extract_me "${_me_destination}" "${cdir}/${i}"
|
|
cdir="${1}"
|
|
cd "${cdir}"
|
|
else
|
|
printf "SKIPPING: %s\n" "${i}"
|
|
fi
|
|
done
|
|
)
|
|
|
|
rm -Rf "${sdir}"
|
|
|
|
if [ ! -f "${_me_destination}" ]; then
|
|
printf "me.bin not found in vendor update for board: %s\n" ${board}
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
Download_ec() {
|
|
printf "Downloading KBC1126 EC firmware for HP laptop\n"
|
|
|
|
Fetch_update ec || return 1
|
|
Extract_ec || return 1
|
|
|
|
return 0
|
|
}
|
|
|
|
Extract_ec() {
|
|
printf "Extracting KBC1126 EC firmware for board: %s\n" ${board}
|
|
|
|
_ec_destination=${CONFIG_KBC1126_FW1#../../}
|
|
|
|
if [ ! -d "${_ec_destination%/*}" ]; then
|
|
mkdir -p "${_ec_destination%/*}"
|
|
fi
|
|
|
|
if [ -d "${appdir}" ]; then
|
|
rm -Rf "${appdir}"
|
|
fi
|
|
|
|
if [ -f "${_ec_destination}" ]; then
|
|
printf "ec already downloaded\n"
|
|
return 0
|
|
fi
|
|
|
|
unar "${dl_path}" -o "${appdir}"
|
|
|
|
(
|
|
cd "${appdir}/${dl_path##*/}"
|
|
|
|
mv Rompaq/68*.BIN ec.bin
|
|
"${kbc1126_ec_dump}" ec.bin
|
|
)
|
|
|
|
for i in 1 2; do
|
|
if [ ! -f "${appdir}/${dl_path##*/}/ec.bin.fw${i}" ]; then
|
|
printf "Not found: %s/%s/ec.bin.fw%s\n" \
|
|
${appdir} ${dl_path##*/} ${i}
|
|
printf "Could not extract EC firmware for board: %s\n" \
|
|
${board}
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
cp "${appdir}/${dl_path##*/}"/ec.bin.fw* "${_ec_destination%/*}/"
|
|
}
|
|
|
|
Fetch_update() {
|
|
printf "Fetching vendor update for board: %s\n" ${board}
|
|
|
|
fw_type="${1}"
|
|
dl=""
|
|
dl_bkup=""
|
|
dlsum=""
|
|
if [ "${fw_type}" = "me" ]; then
|
|
dl=${dl_url}
|
|
dl_bkup=${dl_url_bkup}
|
|
dlsum=${dl_hash}
|
|
elif [ "${fw_type}" = "ec" ]; then
|
|
dl=${ec_url}
|
|
dl_bkup=${ec_url_bkup}
|
|
dlsum=${ec_hash}
|
|
else
|
|
printf "Unsupported download type: %s\n" ${fw_type}
|
|
return 1
|
|
fi
|
|
|
|
if [ -z "${dl_url+x}" ]; then
|
|
printf "No vendor update specified for board: %s\n" ${board}
|
|
return 1
|
|
fi
|
|
|
|
Vendor_checksum ${dlsum} || \
|
|
curl ${dl} > ${dl_path} || curl ${dl_bkup} > ${dl_path}
|
|
|
|
Vendor_checksum ${dlsum} || Fail \
|
|
"Cannot guarantee intergity of vendor update for board: ${board}"
|
|
|
|
return 0
|
|
}
|
|
|
|
Vendor_checksum() {
|
|
sha1=$1
|
|
|
|
if [ ! -f "${dl_path}" ]; then
|
|
printf "Vendor update not found on disk for board: %s\n" ${board}
|
|
return 1
|
|
fi
|
|
if [ "$(sha1sum ${dl_path} | awk '{print $1}')" != "${sha1}" ]; then
|
|
printf "Bad checksum on vendor update for board: %s\n" ${board}
|
|
rm ${dl_path}
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
Main
|