summaryrefslogtreecommitdiff
path: root/resources/scripts/blobs
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2022-11-14 00:51:12 +0000
committerLeah Rowe <leah@libreboot.org>2022-11-14 00:51:12 +0000
commit7af9953463c65fe2f02704e6bce815d830e58d7d (patch)
treedce6c19484fd27288c65ac33092040601d8a0622 /resources/scripts/blobs
parentb5c25efed46f0a9121023997c6758eda5c3f5017 (diff)
pragmatic system distribution guideline compliancepsdg
osboot is now part of libreboot, and will soon shut down. libreboot now conforms to osboot policy.
Diffstat (limited to 'resources/scripts/blobs')
-rwxr-xr-xresources/scripts/blobs/download151
-rwxr-xr-xresources/scripts/blobs/extract89
-rwxr-xr-xresources/scripts/blobs/inject152
3 files changed, 392 insertions, 0 deletions
diff --git a/resources/scripts/blobs/download b/resources/scripts/blobs/download
new file mode 100755
index 00000000..c274e9d1
--- /dev/null
+++ b/resources/scripts/blobs/download
@@ -0,0 +1,151 @@
+#!/usr/bin/env bash
+
+# SPDX-FileCopyrightText: 2022 Caleb La Grange <thonkpeasant@protonmail.com>
+# SPDX-License-Identifier: GPL-3.0-only
+
+board="${1}"
+# A shorthand for each board so as not to duplicate blobs for boards of different sizes
+board_short=${board%%_*mb}
+
+# Allow adding only blobs that can be legally redistributed (ifd+gbe)
+if [ "${2}" = "redistributable" ]; then
+ redistributable=true
+else
+ redistributable=false
+fi
+
+Download_needed(){
+ for need in ${needs}; do
+ case ${need} in
+ *ME*)
+ Extract_me || _failed+=" me"
+ ;;
+ *MRC*)
+ ./download mrc || _failed+=" mrc"
+ ;;
+ esac
+ done
+
+ if [ ! -z ${_failed+x} ]; then
+ printf "\nERROR: failed to obtain${_failed}\nrun: './blobutil extract ${board} /path/to/romdump.rom' to extract the remaining blobs\n"
+ exit 1
+ fi
+}
+
+Extract_me(){
+ _me_destination=${CONFIG_ME_BIN_PATH#../../}
+
+ if [ -f "${_me_destination}" ]; then
+ printf 'me already downloaded\n'
+ return 0
+ fi
+
+ if [ -z "${me_dl+x}" ]; then
+ printf 'no me download available for this board\n'
+ return 1
+ fi
+
+ if [ ! -d "${_me_destination%/*}" ]; then
+ mkdir -p ${_me_destination%/*}
+ fi
+
+ printf "Extracting neutered me for ${board}\n"
+
+ # Delete old me downloads in case user is building for multiple boards
+ if [ -f "blobs/me.exe" ]; then
+ rm blobs/me.exe
+ fi
+
+ if [ -d "blobs/app" ]; then
+ rm -r blobs/app
+ fi
+
+ curl ${me_dl} > blobs/me.exe || curl ${me_dl_bkup} > blobs/me.exe
+
+ if [ ! "$(sha1sum blobs/me.exe)" = "${me_hash} blobs/me.exe" ]; then
+ printf 'checksum of downloaded me did not mactch\ncorrupted me downloaded or wrong me for board\n'
+ rm blobs/me.exe
+ return 1
+ fi
+
+ ( cd blobs && innoextract me.exe )
+ printf 'extracting and stripping intel management engine\n'
+ ./me_cleaner/me_cleaner.py -r -t -O ${_me_destination} blobs/app/*ME*.bin \
+ || ./resources/blobs/me7_update_parser.py -O ${_me_destination} blobs/app/ME7*.bin
+ printf "Truncated and cleaned me output to ${_me_destination}\n"
+}
+
+Build_deps(){
+ if [ ! -d me_cleaner ]; then
+ printf "downloading me_cleaner\n"
+ ./download me_cleaner
+ fi
+
+ if [ ! -d coreboot/default ]; then
+ printf "downloading coreboot\n"
+ ./download coreboot default
+ fi
+
+ if [ ! -f "coreboot/default/util/ifdtool/ifdtool" ]; then
+ printf "building ifdtool from coreboot\n"
+ ( cd coreboot/default/util/ifdtool && make )
+ fi
+}
+
+set -- "resources/coreboot/${board}/config/*"
+. ${1} 2>/dev/null
+. "resources/coreboot/${board}/board.cfg"
+
+if [ "${CONFIG_HAVE_MRC}" = "y" ]; then
+ if [ "${redistributable}" = "false" ]; then
+ printf 'haswell board detected, downloading mrc\n'
+ needs+=" MRC"
+ fi
+
+fi
+
+if [ "${CONFIG_HAVE_IFD_BIN}" = "y" ]; then
+ printf 'board needs intel firmware descriptor\n'
+ needs+=" IFD"
+fi
+
+if [ "${CONFIG_HAVE_ME_BIN}" = "y" ]; then
+ if [ "${redistributable}" = "false" ]; then
+ printf 'board needs intel management engine\n'
+ needs+=" ME"
+ fi
+fi
+
+if [ "${CONFIG_HAVE_GBE_BIN}" = "y" ]; then
+ printf 'board needs gigabit ethernet firmware\n'
+ needs+=" GBE"
+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
+
+Build_deps
+
+while read -r line ; do
+ case ${line} in
+ ME_hash*)
+ set ${line}
+ me_hash=${2}
+ ;;
+ ME_dl*)
+ set ${line}
+ me_dl=${2}
+ ;;
+ ME_bkup_dl*)
+ set ${line}
+ me_dl_bkup=${2}
+ ;;
+ esac
+done <<< $(eval "awk ' /\{.*${board_short}.*}{/ {flag=1;next} /\}/{flag=0} flag { print }' resources/blobs/sources")
+
+Download_needed
+
+
diff --git a/resources/scripts/blobs/extract b/resources/scripts/blobs/extract
new file mode 100755
index 00000000..cdb55cfe
--- /dev/null
+++ b/resources/scripts/blobs/extract
@@ -0,0 +1,89 @@
+#!/usr/bin/env bash
+# script to automate extracting blobs from an existing vendor bios
+
+# SPDX-FileCopyrightText: 2022 Caleb La Grange <thonkpeasant@protonmail.com>
+# SPDX-License-Identifier: GPL-3.0-only
+
+board="${1}"
+vendor_rom="${2}"
+
+Print_help(){
+ printf "Usage: ./blobutil extract {boardname} {path/to/vendor_rom}\n"
+ printf "Example: ./blobutil extract x230 12mb_flash.bin\n"
+ printf "\nYou need to specify exactly 2 arguments\n"
+}
+
+Build_deps(){
+ if [ ! -d me_cleaner ]; then
+ printf "downloading me_cleaner\n"
+ ./download me_cleaner
+ else
+ printf "me_cleaner already downloaded. Skipping.\n"
+ printf "run ./download me_cleaner to manually overwrite\n"
+ fi
+
+ if [ ! -d coreboot/default ]; then
+ printf "downloading coreboot\n"
+ ./download coreboot default
+ else
+ printf "coreboot already downloaded. Skipping.\n"
+ printf "run ./download coreboot to manually overwrite\n"
+ fi
+
+ printf "building ifdtool from coreboot\n"
+ ( cd coreboot/default/util/ifdtool && make )
+}
+
+Error_out(){
+ printf "failed to extract ${1}\nmake sure that your rom dump is valid\n"
+ exit 1
+}
+
+
+Extract_blobs(){
+ # TODO: find a better way to know which coreboot config to source
+ 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'
+ ./download mrc
+ fi
+
+ _me_destination=${CONFIG_ME_BIN_PATH#../../}
+ _gbe_destination=${CONFIG_GBE_BIN_PATH#../../}
+ _ifd_destination=${CONFIG_IFD_BIN_PATH#../../}
+
+ printf "extracting clean ime and modified ifd\n"
+ ./me_cleaner/me_cleaner.py -D ${_ifd_destination} -M ${_me_destination} ${vendor_rom} -t -r -S || Error_out me
+
+ printf "extracting gigabit ethernet firmware"
+ ./coreboot/default/util/ifdtool/ifdtool -x ${vendor_rom}
+ mv flashregion*gbe.bin ${_gbe_destination} || Error_out gbe
+
+ # Cleans up other files extracted with ifdtool
+ rm flashregion*.bin 2> /dev/null
+ printf "gbe, ifd, and me extracted to ${_me_destination%/*}\n"
+}
+
+if [ ! -f "${vendor_rom}" ] ; then
+ Print_help
+ exit 1
+fi
+
+if [ ! -d "resources/coreboot/${board}" ]; then
+ Print_help
+ printf "build/roms: Target %s does not exist in the %s build system. Skipping build.\n" "${projectname}" "${board}"
+ exit 1
+fi
+
+if [ ! -f "resources/coreboot/${board}/board.cfg" ]; then
+ Print_help
+ printf "build/roms: Target %s does not have a board.cfg. Skipping build.\n" "${board}"
+ exit 1
+fi
+
+printf "extracting blobs for ${board} from ${vendor_rom}\n"
+Build_deps
+Extract_blobs
diff --git a/resources/scripts/blobs/inject b/resources/scripts/blobs/inject
new file mode 100755
index 00000000..545a5800
--- /dev/null
+++ b/resources/scripts/blobs/inject
@@ -0,0 +1,152 @@
+#!/usr/bin/env bash
+
+# SPDX-FileCopyrightText: 2022 Caleb La Grange <thonkpeasant@protonmail.com>
+# SPDX-License-Identifier: GPL-3.0-only
+
+Error_out(){
+ if [ ! -z ${@+x} ]; then
+ printf "ERROR: ${@}\n"
+ fi
+
+ cat <<- EOF
+ USAGE: ./blobutil inject -r [/path/to/rom] -b [boardname] -m [macaddress]
+ Example: ./blobutil inject -r x230_12mb.rom -b x230_12mb
+
+ Adding a macadress to the gbe is optional.
+ If the [-m] parameter is left blank, the gbe will not be touched.
+
+ Type './blobutil inject listboards' to get a list of valid boards
+ EOF
+
+ exit 1
+}
+
+Modify_gbe(){
+ printf "changing mac address in gbe to ${new_mac}\n"
+ _gbe_location=${CONFIG_GBE_BIN_PATH#../../}
+
+ if [ ! -d nvmutils/ ]; then
+ git clone https://notabug.org/osboot/nvmutils
+ if [ ! -d nvmutils/ ]; then
+ printf "E: could not download nvmutils"
+ exit 1
+ fi
+ (
+ cd nvmutils/
+ git reset --hard ba9f5ada6a05d7ef8af45e30b700cd627a055867
+ )
+ fi
+ if [ ! -f nvmutils/nvmmac ]; then
+ ( cd nvmutils/ && make )
+ fi
+
+ _gbe_tmp=$(mktemp -t gbeXXXX.bin)
+ cp ${_gbe_location} ${_gbe_tmp}
+ ./nvmutils/nvmmac ${_gbe_tmp} ${new_mac} || Error_out 'failed to modify mac address\nmake sure the mac address in the correct format'
+
+ ./coreboot/default/util/ifdtool/ifdtool -i GbE:${_gbe_tmp} ${rom} -O ${rom} || exit 1
+
+ rm ${_gbe_tmp}
+}
+
+listboards() {
+ for boarddir in resources/coreboot/*; do
+ if [ ! -d "${boarddir}" ]; then continue; fi
+ board="${boarddir##resources/coreboot/}"
+ board="${board%/}"
+ printf '%s\n' "${board##*/}"
+ done
+}
+
+# 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(){
+ filename=$(basename ${rom})
+ case ${filename} in
+ grub_*)
+ board=$(cut -d '_' -f2-3 <<<${filename})
+ ;;
+ seabios_grubfirst_*|seabios_withgrub_*)
+ board=$(cut -d '_' -f3-4 <<<${filename})
+ ;;
+ *)
+ return 1
+ esac
+
+ if [ -d "resources/coreboot/${board}/" ]; then
+ printf '%s\n' "${board}"
+ else
+ return 1
+ fi
+}
+
+Patch(){
+set -- "resources/coreboot/${board}/config/*"
+. ${1} 2>/dev/null
+. "resources/coreboot/${board}/board.cfg"
+
+ if [ "$CONFIG_HAVE_MRC" = "y" ]; then
+ printf 'adding mrc\n'
+ ./coreboot/default/util/cbfstool/cbfstool ${rom} add -f mrc/haswell/mrc.bin -n mrc.bin -t mrc || exit 1
+ fi
+
+ if [ "${CONFIG_HAVE_ME_BIN}" = "y" ]; then
+ _me_location=${CONFIG_ME_BIN_PATH#../../}
+ printf 'adding intel management engine\n'
+ ./coreboot/default/util/ifdtool/ifdtool -i me:${_me_location} ${rom} -O ${rom} || exit 1
+ fi
+
+ if [ "${modifygbe}" = "true" ]; then
+ Modify_gbe
+ fi
+}
+
+if [ "${1}" = "listboards" ]; then
+ listboards
+ exit 0
+fi
+
+# Implementing parameter parsing now so more options can be added later
+while getopts r:b:m: option
+do
+ case "${option}"
+ in
+ r)rom=${OPTARG};;
+ b)board=${OPTARG};;
+ m)
+ modifygbe=true
+ new_mac=${OPTARG}
+ ;;
+ esac
+done
+
+if [ -z ${rom+x} ]; then
+ Error_out 'no rom specified'
+elif [ ! -f "${rom}" ]; then
+ Error_out "${rom} is not a valid path"
+elif [ -z ${board+x} ]; then
+ board=$(Detect_board) || \
+ Error_out 'no board specified'
+fi
+
+if [ ! -d "resources/coreboot/${board}/" ]; then
+ printf "board ${board} not found\n"
+ Error_out
+fi
+
+if [ ! -d coreboot/default ]; then
+ printf "downloading coreboot\n"
+ ./download coreboot default
+fi
+
+if [ ! -f "coreboot/default/util/ifdtool/ifdtool" ]; then
+printf "building ifdtool from coreboot\n"
+( cd coreboot/default/util/ifdtool && make )
+fi
+
+if [ ! -f "coreboot/default/util/cbfstool/cbfstool" ]; then
+printf "building cbfstool from coreboot\n"
+( cd coreboot/default/util/cbfstool && make )
+fi
+
+./blobutil download ${board} && Patch