From 7af9953463c65fe2f02704e6bce815d830e58d7d Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Mon, 14 Nov 2022 00:51:12 +0000 Subject: pragmatic system distribution guideline compliance osboot is now part of libreboot, and will soon shut down. libreboot now conforms to osboot policy. --- resources/scripts/blobs/download | 151 ++++++++++++++++++++++++++++++++++++++ resources/scripts/blobs/extract | 89 +++++++++++++++++++++++ resources/scripts/blobs/inject | 152 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 392 insertions(+) create mode 100755 resources/scripts/blobs/download create mode 100755 resources/scripts/blobs/extract create mode 100755 resources/scripts/blobs/inject (limited to 'resources/scripts/blobs') 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 +# 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 +# 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 +# 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 -- cgit v1.2.1