Files
lbmk/script/roms
T
Leah Rowe 1ce7e33976 move rom tarball creation to script/roms
export LBMK_RELEASE="y"

if this is done, the tarball is created instead
of a directory, and the rom images are nuked using
./vendor inject with the nuke option, inserting the
correct version files; the rom directory is deleted

now the release script logic simple renames existing
tarballs. the benefit of this change is fewer lines of
code, and now lbmk doesn't use an insane amount of disk
space when building a *lot* of release images (the
uncompressed directories are deleted after each build)

Signed-off-by: Leah Rowe <leah@libreboot.org>
2024-05-14 23:44:28 +01:00

526 lines
16 KiB
Bash
Executable File

#!/usr/bin/env sh
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2014-2016,2020,2021,2023,2024 Leah Rowe <leah@libreboot.org>
# SPDX-FileCopyrightText: 2021,2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
# SPDX-FileCopyrightText: 2022 Caleb La Grange <thonkpeasant@protonmail.com>
# SPDX-FileCopyrightText: 2022-2023 Alper Nebi Yasak <alpernebiyasak@gmail.com>
# SPDX-FileCopyrightText: 2023 Riku Viitanen <riku.viitanen@protonmail.com>
set -u -e
. "include/option.sh"
serprog_usage="usage: ./build roms serprog <rp2040|stm32> [board]"
seavgabiosrom="elf/seabios/default/libgfxinit/vgabios.bin"
grub_background="background1280x800.png"
grubelf="elf/grub/grub.elf"
cfgsdir="config/coreboot"
pico_src_dir="src/pico-serprog"
pico_sdk_dir="src/pico-sdk"
stm32_src_dir="src/stm32-vserprog"
# Disable all payloads by default.
# target.cfg files have to specifically enable [a] payload(s)
pv="payload_grub payload_grub_withseabios payload_seabios payload_memtest t"
pv="${pv} payload_seabios_withgrub payload_seabios_grubonly payload_uboot memtest_bin"
v="romdir cbrom initmode displaymode cbcfg targetdir tree keymaps release"
v="${v} grub_timeout ubdir board grub_scan_disk uboot_config"
eval "$(setvars "n" ${pv} serprog)"
eval "$(setvars "" ${v} boards _displaymode _payload _keyboard all targets \
serprog_boards_dir)"
main()
{
check_project
while [ $# -gt 0 ]; do
case ${1} in
help)
usage
exit 0 ;;
list)
x_ items config/coreboot
return 0 ;;
serprog)
serprog="y"
shift 1; break ;;
-d) _displaymode="${2}" ;;
-p) _payload="${2}" ;;
-k) _keyboard="${2}" ;;
*)
[ "${1}" = "all" ] && all="y"
boards="${1} ${boards}"
shift && continue ;;
esac
shift 2
done
if [ "$serprog" = "y" ]; then
handle_serprog $@
return 0
else
[ "${all}" != "y" ] || boards=$(items config/coreboot) || \
$err "Cannot generate list of boards for building"
for x in ${boards}; do
handle_coreboot_target "$x"
done
fi
bstr="directories"
[ "$lbmk_release" = "y" ] && bstr="tarballs"
[ -z "${targets}" ] && $err "No ROM images were compiled"
printf "\nROM images available in these %s:\n" "$bstr"
eval "printf \"${targets}\""
printf "^^ ROM images available in these %s.\n\n" "$bstr"
[ "$lbmk_release" = "y" ] && \
printf "Always run the inject command on release images!\n"
printf "DO NOT flash images from elf/ - please use bin/ instead.\n"
}
handle_serprog()
{
[ -z "${1+x}" ] && $err "${serprog_usage}"
[ "$1" != "rp2040" ] && [ "$1" != "stm32" ] && $err "$serprog_usage"
if [ "${1}" = "rp2040" ]; then
serprog_boards_dir=${pico_sdk_dir}/src/boards/include/boards
[ -d "$pico_src_dir" ] || x_ ./update trees -f "pico-serprog"
elif [ "${1}" = "stm32" ]; then
serprog_boards_dir=${stm32_src_dir}/boards
[ -d "$stm32_src_dir" ] || x_ ./update trees -f "stm32-vserprog"
fi
x_ mkdir -p "bin/serprog_${1}"
if [ $# -gt 1 ] && [ "${2}" = "list" ]; then
print_serprog_boards ${serprog_boards_dir}
return 0
elif [ $# -gt 1 ]; then
build_${1}_rom "${2}"
else
printf "Building all serprog targets\n"
list_serprog_boards "${serprog_boards_dir}" | \
while read -r board; do
build_${1}_rom "${board}"
done
fi
[ "$lbmk_release" = "y" ] && mktar_release "bin/serprog_$1"; return 0
}
build_rp2040_rom()
{
board=${1}
printf "Building pico-serprog for %s\n" "${board}"
x_ cmake -DPICO_BOARD="$board" -DPICO_SDK_PATH="$pico_sdk_dir" \
-B "${pico_src_dir}/build" "${pico_src_dir}"
x_ cmake --build "${pico_src_dir}/build"
x_ mv ${pico_src_dir}/build/pico_serprog.uf2 \
bin/serprog_rp2040/serprog_${board}.uf2
printf "output to bin/serprog_rp2040/serprog_%s.uf2\n" "$board"
}
build_stm32_rom()
{
board=${1}
printf "Building stm32-vserprog for %s\n" "${board}"
x_ make -C $stm32_src_dir libopencm3-just-make BOARD=$board
x_ make -C ${stm32_src_dir} BOARD=${board}
x_ mv ${stm32_src_dir}/stm32-vserprog.hex \
bin/serprog_stm32/serprog_${board}.hex
printf "output to bin/serprog_stm32/serprog_%s.hex\n" "$board"
}
print_serprog_boards()
{
printf "Available boards:\n"
list_serprog_boards "${1}"
}
list_serprog_boards()
{
basename -a -s .h "${1}/"*.h || $err "list_boards $1: can't list boards"
}
handle_coreboot_target()
{
eval "$(setvars "n" ${pv}) $(setvars "" ${v})"
grub_background="background1280x800.png"
board="$1"
configure_target
[ "$board" = "$tree" ] && return 0
if [ "$lbmk_release" = "y" ] && [ "$release" = "n" ]; then
printf "Target '%s' disabled for release.\n" "$board"
return 0
fi
build_payloads
build_target_mainboard
[ -d "bin/${board}" ] || return 0
[ "$lbmk_release" = "y" ] || targets="* bin/${board}\n${targets}"
[ "$lbmk_release" = "y" ] && targets="* bin/$board.tar.xz\n$targets"
[ "$lbmk_release" = "y" ] && mktar_release "bin/$board"; return 0
}
configure_target()
{
targetdir="${cfgsdir}/${board}"
[ -f "${targetdir}/target.cfg" ] || \
$err "Missing target.cfg for target: ${board}"
# Override the above defaults using target.cfg
. "${targetdir}/target.cfg"
[ -z "${grub_scan_disk}" ] && grub_scan_disk="both"
[ "$grub_scan_disk" != "both" ] && [ "$grub_scan_disk" != "ata" ] \
&& [ "${grub_scan_disk}" != "ahci" ] && \
grub_scan_disk="both"
[ -z "$tree" ] && $err "$board: tree not defined"
[ "${payload_memtest}" != "y" ] && payload_memtest="n"
[ "${payload_grub_withseabios}" = "y" ] && payload_grub="y"
[ "${payload_grub_withseabios}" = "y" ] && \
eval "$(setvars "y" payload_seabios payload_seabios_withgrub)"
[ "$payload_seabios_withgrub" = "y" ] && payload_seabios="y"
[ "$payload_seabios_grubonly" = "y" ] && payload_seabios="y"
[ "$payload_seabios_grubonly" = "y" ] && payload_seabios_withgrub="y"
# The reverse logic must not be applied. If SeaBIOS-with-GRUB works,
# that doesn't mean GRUB-withSeaBIOS will. For example, the board
# might have a graphics card whose vga rom coreboot doesn't execute
[ "$payload_grub" != "y" ] && [ "$payload_seabios" != "y" ] && \
[ "${payload_uboot}" != "y" ] && \
for configfile in "${targetdir}/config/"*; do
[ -e "${configfile}" ] || continue
$err "target '${board}' defines no payload"
done
[ "$payload_uboot" != "n" ] && [ "$payload_uboot" != "y" ] && \
payload_uboot="n"
[ "$payload_uboot" = "y" ] && [ -z "$uboot_config" ] && \
uboot_config="default"
# Override all payload directives with cmdline args
[ -z "${_payload}" ] && return 0
printf "setting payload to: %s\n" "${_payload}"
eval "$(setvars "n" payload_grub payload_memtest payload_seabios \
payload_seabios_withgrub payload_uboot payload_grub_withseabios \
payload_seabios_grubonly)"
eval "payload_${_payload}=y"
}
build_payloads()
{
romdir="bin/${board}"
cbdir="src/coreboot/${board}"
[ "${board}" = "${tree}" ] || cbdir="src/coreboot/${tree}"
cbfstool="cbutils/${tree}/cbfstool"
cbrom="${cbdir}/build/coreboot.rom"
[ -f "$cbfstool" ] || x_ ./update trees -b coreboot utils $tree
memtest_bin="memtest86plus/build64/memtest.bin"
[ "${payload_memtest}" != "y" ] || [ -f "src/${memtest_bin}" ] || \
x_ ./update trees -b memtest86plus
[ "$payload_seabios" = "y" ] && x_ ./update trees -b seabios
if [ "$payload_grub" = "y" ] || [ "$payload_seabios_withgrub" = "y" ] \
|| [ "$payload_seabios_grubonly" = "y" ]; then build_grub_payload
fi
[ "${payload_uboot}" = "y" ] && build_uboot_payload; return 0
}
build_grub_payload()
{
x_ mkdir -p elf/grub
for keymapfile in config/grub/keymap/*.gkb; do
[ -f "${keymapfile}" ] || continue
keymaps="${keymaps} ${keymapfile}"
done
[ -z "$_keyboard" ] || [ -f "$grubcfgsdir/keymap/$_keyboard.gkb" ] || \
$err "build_grub_payload: $_keyboard layout not defined"
[ -n "$_keyboard" ] && keymaps="${grubcfgsdir}/keymap/${_keyboard}.gkb"
[ -f "$grubelf" ] && return 0
[ -f "src/grub/grub-mkstandalone" ] || x_ ./update trees -b grub
./src/grub/grub-mkstandalone \
--grub-mkimage="src/grub/grub-mkimage" \
-O i386-coreboot \
-o "elf/grub/grub.elf" \
-d "src/grub/grub-core/" \
--fonts= --themes= --locales= \
--modules="${grub_modules}" \
--install-modules="${grub_install_modules}" \
"/boot/grub/grub.cfg=${grubcfgsdir}/config/grub_memdisk.cfg" \
"/boot/grub/grub_default.cfg=${grubcfgsdir}/config/grub.cfg" || \
$err "could not generate grub.elf"
}
build_uboot_payload()
{
x_ ./update trees -b u-boot ${board}
ubdir="elf/u-boot/${board}/${uboot_config}"
ubootelf="${ubdir}/u-boot.elf"
[ ! -f "${ubootelf}" ] && [ -f "${ubdir}/u-boot" ] && \
ubootelf="${ubdir}/u-boot"
[ -f "${ubootelf}" ] && return 0
$err "Can't find u-boot build for board, $board";
}
build_target_mainboard()
{
x_ rm -Rf "${romdir}"
for x in "normal" "vgarom" "libgfxinit"; do
initmode="${x}"
hmode="vesafb"
[ "${initmode}" = "vgarom" ] || hmode="corebootfb"
modes="${hmode} txtmode"
[ -z "${_displaymode}" ] || modes="${_displaymode}"
for y in ${modes}; do
displaymode="${y}"
[ "${initmode}" = "normal" ] && \
[ "$displaymode" != "txtmode" ] && continue
cbcfg="${targetdir}/config/${initmode}_${displaymode}"
[ "${initmode}" = "normal" ] && cbcfg="${cbcfg%_*}"
build_roms "${cbcfg}"
x_ rm -f "$cbrom"
done
done
}
# Main ROM building function. This calls all other functions below
build_roms()
{
cbcfg="${1}"
if [ ! -f "${cbcfg}" ]; then
printf "'%s' does not exist. Skipping build for %s %s %s\n" \
"$cbcfg" "$board" "$displaymode" "$initmode" 1>&2
return 0
fi
x_ ./update trees -b coreboot ${board}
_cbrom="elf/coreboot_nopayload_DO_NOT_FLASH"
_cbrom="${_cbrom}/${board}/${initmode}_${displaymode}"
[ "${initmode}" = "normal" ] && \
_cbrom="${_cbrom%"_${displaymode}"}"
_cbrom="${_cbrom}/coreboot.rom"
cbrom="$(mktemp -t coreboot_rom.XXXXXXXXXX)"
x_ cp "${_cbrom}" "${cbrom}"
[ "${payload_memtest}" != "y" ] || \
x_ "${cbfstool}" "${cbrom}" add-payload \
-f "src/${memtest_bin}" -n img/memtest -c lzma
[ "${payload_seabios}" = "y" ] && build_seabios_roms
[ "$payload_grub" != "y" ] || x_ build_grub_roms "$cbrom" "grub"
[ "${payload_uboot}" = "y" ] || return 0
x_ cp "${_cbrom}" "${cbrom}"
build_uboot_roms
}
build_seabios_roms()
{
if [ "${payload_seabios_withgrub}" = "y" ]; then
t=$(mktemp -t coreboot_rom.XXXXXXXXXX)
x_ cp "${cbrom}" "${t}"
x_ build_grub_roms "${t}" "seabios_withgrub"
else
t=$(mkSeabiosRom "${cbrom}" "fallback/payload") || \
$err "build_seabios_roms: cannot build tmprom"
newrom="${romdir}/seabios_${board}_${initmode}_${displaymode}"
[ "${initmode}" = "normal" ] && newrom="${romdir}/seabios" \
&& newrom="${newrom}_${board}_${initmode}"
x_ moverom "${t}" "${newrom}.rom"
fi
x_ rm -f "${t}"
}
# Make separate ROM images with GRUB payload, for each supported keymap
build_grub_roms()
{
tmprom="${1}"
payload1="${2}" # allow values: grub, seabios, seabios_withgrub
grub_cbfs="fallback/payload"
if [ "$payload1" = "grub" ] && [ "$payload_grub_withseabios" = "y" ]
then
_tmpmvrom=$(mkSeabiosRom "$tmprom" "seabios.elf") || \
$err "build_grub_roms 1 $board: can't build tmprom"
x_ mv "$_tmpmvrom" "$tmprom"
elif [ "$payload1" != "grub" ] && [ "$payload_seabios_withgrub" = "y" ]
then
grub_cbfs="img/grub2"
_tmpmvrom=$(mkSeabiosRom "$tmprom" fallback/payload) || \
$err "build_grub_roms 2 $board: can't build tmprom"
x_ mv "$_tmpmvrom" "$tmprom"
fi
# we only need insert grub.elf once, for each coreboot config:
x_ "${cbfstool}" "${tmprom}" add-payload -f "${grubelf}" \
-n ${grub_cbfs} -c lzma
# we only need insert background.png once, for each coreboot config:
if [ "${displaymode}" = "vesafb" ] || \
[ "${displaymode}" = "corebootfb" ]; then
backgroundfile="config/grub/background/${grub_background}"
"${cbfstool}" "${tmprom}" add -f ${backgroundfile} \
-n background.png -t raw || \
$err "insert background, ${backgroundfile}"
fi
tmpcfg=$(mktemp -t coreboot_rom.XXXXXXXXXX)
printf "set grub_scan_disk=\"%s\"\n" "$grub_scan_disk" >"$tmpcfg" \
|| $err "set grub_scandisk, $grub_scan_disk, $tmpcfg"
[ "${grub_scan_disk}" = "both" ] || \
x_ "$cbfstool" "$tmprom" add -f "$tmpcfg" -n scan.cfg -t raw
printf "set timeout=%s\n" "${grub_timeout}" > "${tmpcfg}" || \
$err "set timeout, ${grub_timeout}, ${tmpcfg}"
[ -z "${grub_timeout}" ] || x_ "${cbfstool}" "${tmprom}" add \
-f "${tmpcfg}" -n timeout.cfg -t raw
x_ rm -f "${tmpcfg}"
for keymapfile in ${keymaps}; do
[ -f "${keymapfile}" ] || continue
keymap="${keymapfile##*/}"
keymap="${keymap%.gkb}"
tmpgrubrom="$(mktemp -t coreboot_rom.XXXXXXXXXX)"
x_ cp "${tmprom}" "${tmpgrubrom}"
x_ "$cbfstool" "$tmpgrubrom" add -f "$keymapfile" \
-n keymap.gkb -t raw
newrom="${romdir}/${payload1}_${board}_${initmode}_"
newrom="${newrom}${displaymode}_${keymap}.rom"
[ "${initmode}" = "normal" ] && \
newrom="${romdir}/${payload1}_${board}_" && \
newrom="${newrom}${initmode}_${keymap}.rom"
x_ moverom "${tmpgrubrom}" "${newrom}"
if [ "${payload_seabios_grubonly}" = "y" ]; then
x_ "$cbfstool" "$tmpgrubrom" add \
-f "config/grub/bootorder" -n bootorder -t raw
x_ moverom "$tmpgrubrom" "${newrom%.rom}_grubfirst.rom"
x_ "$cbfstool" "$tmpgrubrom" add-int -i 0 \
-n etc/show-boot-menu
x_ moverom "$tmpgrubrom" "${newrom%.rom}_grubonly.rom"
fi
x_ rm -f "${tmpgrubrom}"
done
}
# make a rom in /tmp/ and then print the path of that ROM
mkSeabiosRom() {
_cbrom="${1}" # rom to insert seabios in. will not be touched
# (a tmpfile will be made instead)
_seabios_cbfs_path="${2}" # e.g. fallback/payload
_seabioself="elf/seabios/default/${initmode}/bios.bin.elf"
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
x_ cp "${_cbrom}" "${tmprom}"
x_ "$cbfstool" "$tmprom" add-payload -f "$_seabioself" \
-n "${_seabios_cbfs_path}" -c lzma
x_ "$cbfstool" "$tmprom" add-int -i 3000 -n etc/ps2-keyboard-spinup
z="2"; [ "$initmode" = "vgarom" ] && z="0"
x_ "$cbfstool" "$tmprom" add-int -i $z -n etc/pci-optionrom-exec
x_ "$cbfstool" "$tmprom" add-int -i 0 -n etc/optionroms-checksum
[ "$initmode" != "libgfxinit" ] || \
x_ "$cbfstool" "$tmprom" add -f "$seavgabiosrom" \
-n vgaroms/seavgabios.bin -t raw
printf "%s\n" "${tmprom}"
}
build_uboot_roms()
{
tmprom=$(mkUbootRom "${cbrom}" "fallback/payload") || \
$err "build_uboot_roms $board: could not create tmprom"
newrom="${romdir}/uboot_payload_${board}_${initmode}_${displaymode}.rom"
x_ moverom "${tmprom}" "${newrom}"
x_ rm -f "${tmprom}"
}
# make a rom in /tmp/ and then print the path of that ROM
mkUbootRom() {
_cbrom="${1}"
_uboot_cbfs_path="${2}"
_ubdir="elf/u-boot/${board}/${uboot_config}"
_ubootelf="${_ubdir}/u-boot.elf"
[ -f "${_ubootelf}" ] || _ubootelf="${_ubdir}/u-boot"
[ -f "$_ubootelf" ] || $err "mkUbootRom: $board: cant find u-boot"
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
x_ cp "${_cbrom}" "${tmprom}"
x_ "$cbfstool" "$tmprom" add-payload -f "$_ubootelf" \
-n "${_uboot_cbfs_path}" -c lzma
printf "%s\n" "${tmprom}"
}
moverom()
{
printf "Creating target image: %s\n" "$2"
x_ mkdir -p "${2%/*}"
x_ cp "$1" "$2"
[ "$lbmk_release" = "y" ] || return 0
(
cd "${2%/*}" || $err "moverom, !cd \"${2%/*}\""
sha512sum ./"${2##*/}" >> vendorhashes || $err "!$2 vendorhashes"
) || $err "Cannot create checksum for '$2'"
x_ ./vendor inject -r "${2}" -b "$board" -n nuke
}
usage()
{
cat <<- EOF
USAGE: ./build roms targetname
To build *all* boards, do this: ./build roms all
To list *all* boards, do this: ./build roms list
Optional Flags:
-d: displaymode
-p: payload
-k: keyboard layout
Example commands:
./build roms x60
./build roms x200_8mb x60
./build roms x60 -p grub -d corebootfb -k usqwerty
to see possible values for 'target':
./build roms list
Can also build serprog images:
${serprog_usage}
to see targets of only a given status (stable, unstable,
broken, untested and unknown), try e.g.
./build roms list stable
./build roms list unstable untested
./build roms list unknown
./build roms list broken
./build roms list broken stable
the value is set in target.cfg for each board. if status
is unitialised, it defaults to "unknown". only stable/unstable
targets are permitted in releases; broken, untested and
unknown are not allowed, but are accessible via normal building
Refer to the ${projectname} documentation for more information.
EOF
}
main $@