blob: a6b2e1ebb0302b5c7a0e21f4d3fc026b6404164a [file] [log] [blame]
#!/bin/bash
set -eu
declare FIRMWARE_ROOT=/build/zork/firmware
declare KEYDIR=/usr/share/vboot/devkeys
: "${CACHE_DIR:=/tmp/coreboot}"
: "${VBOOT_SOURCE:=/mnt/host/source//src/platform/vboot_reference}"
: "${HOSTCC:=x86_64-pc-linux-gnu-clang}"
: "${HOSTPKGCONFIG:=x86_64-pc-linux-gnu-pkg-config}"
if [[ "$#" -eq 0 ]]; then
echo "Usage: $0 <board|config file>..."
echo "e.g., $0 trembyle mandolin-hardcore"
exit 1
fi
declare -a CONFIGS
declare -a CONFIG_PATHS=(
"$HOME/trunk/src/overlays/overlay-zork/sys-boot/coreboot-zork/files/configs"
"$HOME/trunk/src/overlays/overlay-zork/sys-boot/coreboot/files/configs"
"./configs"
)
em100=
psp_verstage=
while [[ "$#" -gt 0 ]]; do
arg="$1"
shift
if [[ "$arg" = "--" ]]; then
break;
fi
if [[ "$arg" = "-e" ]]; then
em100=y
echo "Using em100 mode"
continue
fi
if [[ "$arg" = "--psp-verstage" ]]; then
psp_verstage=y
echo "Building PSP verstage"
continue
fi
if [[ -e "$arg" ]]; then
CONFIGS+=("$arg")
continue
fi
found=0
for config_path in "${CONFIG_PATHS[@]}"; do
if [[ -e "$config_path/config.$arg" ]]; then
CONFIGS+=("$config_path/config.$arg")
found=1
break
fi
done
if [[ "$found" -eq 0 ]]; then
echo "Failed to find config for '$arg'"
exit 1
fi
done
declare -a MAKE_OPTS=("$@")
declare -a CLEANUP
function finish {
local dir
for dir in "${CLEANUP[@]+"${CLEANUP[@]}"}"; do
if [[ -e "$dir" ]]; then
rm -r "$dir"
fi
done
}
trap finish EXIT
#
# Replace local paths with paths to $FIRMWARE_ROOT/coreboot-private
#
# $1: full config
#
function replace-paths() {
local full_config="$1"
local private="$FIRMWARE_ROOT/coreboot-private"
local full_path
local -a replace
while read -r key val; do
full_path="$private/$val"
if [[ -e $full_path ]]; then
replace+=(-e "s|^${key}=.*|${key}=\"${full_path}\"|")
elif [[ "$key" = "CONFIG_PSP_BOOTLOADER_NAME" ]]; then
# We need this because the binary assumes it's relative
# to all the other AMD blobs
local relative="3rdparty/blobs/soc/amd/picasso/PSP/$val"
if [[ -e "$private/$relative" ]]; then
full_path="$(realpath --relative-to="$relative" "$private/$relative")"
replace+=(-e "s|^${key}=.*|${key}=\"${full_path}\"|")
fi
fi
done <<<"$(sed -En \
-e 's/^([A-Z0-9_]+)="(3rdparty\/blobs\/.*)"$/\1 \2/p' \
-e 's/^(CONFIG_PSP_BOOTLOADER_NAME)="(.*)"$/\1 \2/p' \
"$full_config")"
if [[ "${replace[@]+"${#replace[@]}"}" -gt 0 ]]; then
sed -iE "${replace[@]}" "$full_config"
fi
}
# $1: cache_dir
# $2: work_dir
# $3: config_path
function build-coreboot-rom() {
local cache_dir="$1" work_dir="$2" config_path="$3"
cp "$config_path" "$work_dir/.config"
{
declare serial_config="$HOME/trunk/src/overlays/overlay-zork/sys-boot/coreboot-zork/files/configs/fwserial.zork"
cat "${serial_config}"
echo CONFIG_APCB_BLOB_DIR=\""$FIRMWARE_ROOT/coreboot-private/3rdparty/blobs/mainboard"\"
if [[ -n "${em100}" ]]; then
echo CONFIG_EM100=y
fi
if [[ -n "${psp_verstage}" ]]; then
echo CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK=y
echo CONFIG_PSP_BOOTLOADER_NAME=\"PspBootLoader_test_RV_dbg.sbin\"
fi
} >> "$work_dir/.config"
make \
obj="$work_dir" \
DOTCONFIG="$work_dir/.config" \
HOSTCC="$HOSTCC"\
HOSTPKGCONFIG="$HOSTPKGCONFIG" \
VBOOT_SOURCE="$VBOOT_SOURCE" \
olddefconfig
replace-paths "$work_dir/.config"
if [[ ! -e "$cache_dir/.config" ]] || ! cmp "$work_dir/.config" "$cache_dir/.config"; then
echo "Cache busted: $cache_dir"
# Bust the cache anytime the .config is updated
rm -rf "$cache_dir"
mkdir -p "$cache_dir"
cp "$work_dir/.config" "$cache_dir/.config"
else
echo "Reusing cache at $cache_dir"
fi
make -j \
obj="$cache_dir" \
DOTCONFIG="$cache_dir/.config" \
HOSTCC="$HOSTCC"\
HOSTPKGCONFIG="$HOSTPKGCONFIG" \
VBOOT_SOURCE="$VBOOT_SOURCE" \
"${MAKE_OPTS[@]+${MAKE_OPTS[@]}}"
# Kconfig generates a dummy file that doesn't get removed.
rm -f ..config.tmp.*
echo "Successfully built $cache_dir"
}
# Use make compress assets in parallel
# $1: src
# $2: dst
# $3: image.bin
function compress-assets() {
local src="$1" dest="$2"
make -j -f - src="$src" dest="$dest" << 'EOF'
.DELETE_ON_ERROR:
inputs:=$(wildcard $(src)/*)
outputs:=$(inputs:$(src)/%=$(dest)/%)
.PHONY: all
all: $(outputs)
$(dest):
mkdir -p "$@"
$(dest)/%: $(src)/% | $(dest)
cbfs-compression-tool compress "$<" "$@" LZMA
EOF
}
# $1: work_dir
# $2: image.bin
# $3: slot
function sign-region() {
local work_dir="$1" image="$2" slot="$3"
local main="FW_MAIN_${slot}" vblock="VBLOCK_${slot}"
local -i size
size="$(cbfstool "${image}" truncate -r "$main")"
cbfstool "${image}" read -r "$main" -f "$work_dir/$main"
truncate -s "$size" "$work_dir/$main"
cbfstool "${image}" write --force -u -i 255 \
-r "$main" -f "$work_dir/$main"
futility vbutil_firmware \
--keyblock "${KEYDIR}/firmware.keyblock" \
--signprivate "${KEYDIR}/firmware_data_key.vbprivk" \
--kernelkey "${KEYDIR}/kernel_subkey.vbpubk" \
--fv "$work_dir/$main" \
--vblock "$work_dir/$vblock"
cbfstool "${image}" write -u -i 255 -r "${vblock}" \
-f "$work_dir/$vblock"
}
# $1: cache_dir
# $2: work_dir
# $3: image.bin
function add-depthcharge() {
local cache_dir="$1" work_dir="$2" image="$3"
local payload="$FIRMWARE_ROOT/zork/depthcharge/depthcharge.elf"
compress-assets "$FIRMWARE_ROOT/cbfs-ro-compress" \
"$cache_dir/compressed-assets-ro"
local file
for file in "$cache_dir/compressed-assets-ro"/*; do
cbfstool "${image}" add -r COREBOOT -f "${file}" \
-n "$(basename "${file}")" -t raw -c precompression
done
cbfstool "${image}" expand -r FW_MAIN_A,FW_MAIN_B
cbfstool "${image}" add-payload -r COREBOOT,FW_MAIN_A,FW_MAIN_B \
-f "${payload}" -n fallback/payload -c lzma
sign-region "$work_dir" "$image" "A"
sign-region "$work_dir" "$image" "B"
}
# $1: config_path
function build-boot-image() {
local config_path="$1"
local work_dir build_name cache_dir image_name
work_dir="$(mktemp -d)" && CLEANUP+=("$work_dir")
build_name="${config_path##*.}"
cache_dir="$CACHE_DIR/$build_name"
image_name="image-$build_name.serial.bin"
echo "Building $config_path"
build-coreboot-rom "$cache_dir" "$work_dir" "$config_path"
if grep -q CONFIG_VBOOT=y "$cache_dir/.config"; then
cp "$cache_dir/coreboot.rom" "$work_dir/$image_name"
add-depthcharge "$cache_dir" "$work_dir" "$work_dir/$image_name"
cp "$work_dir/$image_name" "$cache_dir/$image_name"
else
cp "$cache_dir/coreboot.rom" "$cache_dir/$image_name"
fi
FINAL_IMAGES+=("$cache_dir/$image_name")
}
# Ugh, still in the src tree
rm -f .xcompile
util/xcompile/xcompile /opt/coreboot-sdk/bin/ > .xcompile
declare -a FINAL_IMAGES
for config in "${CONFIGS[@]}"; do
build-boot-image "$config"
done
echo
for image in "${FINAL_IMAGES[@]}"; do
echo "*** Built $image ***"
done