107072b189
due to lbmk issue #216, it is now unwise to use grub as the primary payload on any machine; the sheer complexity of grub and the number of memory corruption bugs that have been fixed due to auditing over the years, means more such bugs exist. we now provide seabios as the primary payload on all x86 ports, but provide a "grubfirst" configuration where a bootorder file in seabios can be added via cbfs, which tells seabios to load grub from cbfs first, while still allowing use of the boot select menu by pressing esc in seabios. well, the "grubonly" option also disables the seabios esc menu, so that *only* grub runs. there is no point in using this unless you want to harden your setup, for example if you want to set up encrypted /boot and boot that from grub, and have a grub password disallowing unauthorised bootup of your machine. see grub hardening guide; https://libreboot.org/docs/linux/grub_hardening.html at least as of today, 22 June 2024, that page already says how to manually disable the seabios menu in the same way, if that is the setup you want. alternatively, a user may be wily enough to edit target.cfg for their board and compile a rom that only has the grub payload in it, if that is what the user wishes to do. regardless, the default configurations provided by lbmk must never be unsafe, norc should the build system support such unsafe settings; yes, grub as primary payload is technically still supported in lbmk. actually, at the time of this revision, i have half a mind to remove that functionality altogether, so that only seabios is allowed as primary payload, when compiling a rom image that also has grub, chainloading grub from the seabios menu instead. Signed-off-by: Leah Rowe <leah@libreboot.org>
277 lines
8.6 KiB
Bash
Executable file
277 lines
8.6 KiB
Bash
Executable file
#!/usr/bin/env sh
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# Copyright (c) 2014-2016,2020-2021,2023-2024 Leah Rowe <leah@libreboot.org>
|
|
# Copyright (c) 2021-2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
|
|
# Copyright (c) 2022 Caleb La Grange <thonkpeasant@protonmail.com>
|
|
# Copyright (c) 2022-2023 Alper Nebi Yasak <alpernebiyasak@gmail.com>
|
|
# Copyright (c) 2023 Riku Viitanen <riku.viitanen@protonmail.com>
|
|
|
|
set -u -e
|
|
|
|
. "include/lib.sh"
|
|
|
|
seavgabiosrom="elf/seabios/default/libgfxinit/vgabios.bin"
|
|
cfgsdir="config/coreboot"
|
|
rp2040src="src/pico-serprog"
|
|
rp2040x="$rp2040src/build/pico_serprog.uf2"
|
|
picosdk="src/pico-sdk"
|
|
rp2040dir="$picosdk/src/boards/include/boards"
|
|
stm32src="src/stm32-vserprog"
|
|
stm32x="$stm32src/stm32-vserprog.hex"
|
|
stm32dir="$stm32src/boards"
|
|
|
|
# Disable all payloads by default.
|
|
# target.cfg files have to specifically enable [a] payload(s)
|
|
pv="payload_uboot payload_grub_withseabios payload_seabios payload_memtest t"
|
|
pv="$pv payload_seabios_withgrub payload_grub"
|
|
v="romdir cbrom initmode displaymode cbcfg targetdir tree release ubootelf"
|
|
v="$v grub_timeout board grub_scan_disk uboot_config grubtree grubelf tmpmv"
|
|
eval `setvars "n" $pv`
|
|
eval `setvars "" $v boards targets serdir ser`
|
|
|
|
main()
|
|
{
|
|
while [ $# -gt 0 ]; do
|
|
if [ "$1" = "serprog" ]; then
|
|
[ $# -lt 2 ] && $err "serprog type not set"
|
|
[ "$2" != "rp2040" ] && [ "$2" != "stm32" ] && \
|
|
$err "invalid serprog type"
|
|
eval "x_ ./update trees -f \"\${${2}src##*/}\""
|
|
ser="$2" && shift 2 && continue
|
|
fi
|
|
[ "$1$ser" = "list" ] && x_ ls -1 config/coreboot && return
|
|
[ "$1" = "all" ] && shift && continue
|
|
boards="$1 $boards"; shift 1
|
|
done
|
|
|
|
[ -n "$boards" ] || [ -n "$ser" ] || boards="$(ls -1 \
|
|
config/coreboot)" || $err "can't list coreboot boards"
|
|
|
|
[ -n "$ser" ] && \
|
|
eval "serlist \"\$${ser}dir\" > \"\$tmpdir/ser\" || $err \"!ser\""
|
|
[ -n "$ser" ] && [ -z "$boards" ] && boards="$(cat "$tmpdir/ser")"
|
|
|
|
for x in $boards; do
|
|
[ -n "$ser" ] && mkserprogfw "$ser" "$x"
|
|
[ -z "$ser" ] && [ -d "config/coreboot/$x/config" ] && \
|
|
configure_target "$x" && build_payloads && build_board && \
|
|
[ -d "bin/$board" ] && targets="$targets, $x"; continue
|
|
done
|
|
|
|
[ -n "$ser" ] && [ "$xbmk_release" = "y" ] && \
|
|
mkrom_tarball "bin/serprog_$ser" && return 0
|
|
|
|
[ -z "$ser" ] && [ -z "$targets" ] && $err "No images were compiled"
|
|
printf "DO NOT flash images from elf/ - use bin/ instead. ALSO:\n"
|
|
printf "%s\n" "$kbnotice"
|
|
}
|
|
|
|
mkserprogfw()
|
|
{
|
|
x_ mkdir -p "bin/serprog_$1"
|
|
if [ "$1" = "rp2040" ]; then
|
|
x_ cmake -DPICO_BOARD="$2" -DPICO_SDK_PATH="$picosdk" \
|
|
-B "$rp2040src/build" "$rp2040src"
|
|
x_ cmake --build "$rp2040src/build"
|
|
else
|
|
x_ make -C "$stm32src" libopencm3-just-make BOARD=$2
|
|
x_ make -C "$stm32src" BOARD=$2
|
|
fi
|
|
eval "x_ mv \"\$${1}x\" \"bin/serprog_$1/serprog_$2.\${${1}x##*.}\""
|
|
printf "Look in bin/serprog_%s/ for images\n" "$1"
|
|
}
|
|
|
|
serlist()
|
|
{
|
|
basename -a -s .h "$1/"*.h || $err "$1: can't list boards"
|
|
}
|
|
|
|
configure_target()
|
|
{
|
|
eval `setvars "n" $pv`
|
|
eval `setvars "" $v`
|
|
board="$1"
|
|
|
|
targetdir="$cfgsdir/$board"
|
|
|
|
# Override the above defaults using target.cfg
|
|
eval `setcfg "$targetdir/target.cfg"`
|
|
|
|
[ -z "$grub_scan_disk" ] && grub_scan_disk="nvme ahci ata"
|
|
|
|
[ -n "$grubtree" ] || grubtree="default"
|
|
grubelf="elf/grub/$grubtree/payload/grub.elf"
|
|
|
|
[ -z "$tree" ] && $err "$board: tree not defined"
|
|
|
|
[ "$payload_memtest" != "y" ] && payload_memtest="n"
|
|
[ "$(uname -m)" = "x86_64" ] || payload_memtest="n"
|
|
|
|
[ "$payload_grub_withseabios" = "y" ] && eval `setvars "y" \
|
|
payload_grub payload_seabios payload_seabios_withgrub`
|
|
[ "$payload_seabios_withgrub" = "y" ] && payload_seabios="y"
|
|
|
|
# The reverse logic must not be applied. If SeaBIOS-with-GRUB works,
|
|
# that doesn't mean GRUB-with-SeaBIOS will, e.g. VGA ROM execution
|
|
[ "$payload_grub" != "y" ] && [ "$payload_seabios" != "y" ] && \
|
|
[ "$payload_uboot" != "y" ] && $err "'$board' defines no payload"
|
|
|
|
[ "$payload_uboot" = "y" ] || payload_uboot="n"
|
|
[ -n "$uboot_config" ] || uboot_config="default"
|
|
|
|
[ "$xbmk_release" = "y" ] && [ "$release" = "n" ] && return 1
|
|
[ "$board" = "$tree" ] && return 1; return 0
|
|
}
|
|
|
|
build_payloads()
|
|
{
|
|
romdir="bin/$board"
|
|
cbdir="src/coreboot/$board"
|
|
[ "$board" = "$tree" ] || cbdir="src/coreboot/$tree"
|
|
cbfstool="elf/cbfstool/$tree/cbfstool"
|
|
cbrom="$cbdir/build/coreboot.rom"
|
|
|
|
[ -f "$cbfstool" ] || x_ ./update trees -b coreboot utils $tree
|
|
[ "$payload_memtest" = "y" ] && x_ ./update trees -b memtest86plus
|
|
[ "$payload_seabios" = "y" ] && x_ ./update trees -b seabios
|
|
|
|
if [ "$payload_grub" = "y" ] || [ "$payload_seabios_withgrub" = "y" ]
|
|
then
|
|
[ -f "$grubelf" ] || x_ ./update trees -b grub $grubtree
|
|
fi
|
|
|
|
[ "$payload_uboot" = "y" ] || return 0
|
|
x_ ./update trees -b u-boot $board
|
|
ubdir="elf/u-boot/$board/$uboot_config"
|
|
ubootelf="$ubdir/u-boot.elf" && [ ! -f "$ubootelf" ] && \
|
|
ubootelf="$ubdir/u-boot"
|
|
[ -f "$ubootelf" ] || $err "$board: Can't find u-boot"; return 0
|
|
}
|
|
|
|
build_board()
|
|
{
|
|
x_ rm -Rf "$romdir"
|
|
|
|
for it in "normal" "vgarom" "libgfxinit"; do
|
|
initmode="$it"
|
|
hmode="vesafb"
|
|
[ "$initmode" = "vgarom" ] || hmode="corebootfb"
|
|
modes="$hmode txtmode"
|
|
for y in $modes; do
|
|
displaymode="$y"
|
|
[ "$initmode" = "normal" ] && \
|
|
[ "$displaymode" != "txtmode" ] && continue
|
|
cbcfg="$targetdir/config/${initmode}_$displaymode"
|
|
[ "$initmode" = "normal" ] && cbcfg="${cbcfg%_*}"
|
|
e "$cbcfg" f not || build_roms; x_ rm -f "$cbrom"
|
|
done
|
|
done
|
|
}
|
|
|
|
build_roms()
|
|
{
|
|
x_ ./update trees -b coreboot $board
|
|
|
|
_cbrom="$cbelfdir/$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" ] || cbfs "$cbrom" \
|
|
"elf/memtest86plus/memtest.bin" img/memtest
|
|
[ "$payload_seabios" = "y" ] && build_seabios_roms
|
|
[ "$payload_grub" != "y" ] || build_grub_roms "$cbrom" "grub"
|
|
[ "$payload_uboot" = "y" ] && x_ cp "$_cbrom" "$cbrom" && \
|
|
build_uboot_roms; return 0
|
|
}
|
|
|
|
build_seabios_roms()
|
|
{
|
|
if [ "$payload_seabios_withgrub" = "y" ]; then
|
|
t="$(mktemp -t coreboot_rom.XXXXXXXXXX)"
|
|
x_ cp "$cbrom" "$t"
|
|
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"
|
|
cprom cp "$t" "$newrom.rom"
|
|
fi
|
|
x_ rm -f "$t"
|
|
}
|
|
|
|
# Make separate ROM images with GRUB payload
|
|
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
|
|
tmpmv="$(mkSeabiosRom "$tmprom" "seabios.elf")" || \
|
|
$err "build_grub_roms 1 $board: can't build tmprom"
|
|
elif [ "$payload1" != "grub" ] && [ "$payload_seabios_withgrub" = "y" ]
|
|
then
|
|
grub_cbfs="img/grub2"
|
|
tmpmv="$(mkSeabiosRom "$tmprom" fallback/payload)" || \
|
|
$err "build_grub_roms 2 $board: can't build tmprom"
|
|
fi
|
|
[ -n "$tmpmv" ] && [ -f "$tmpmv" ] && x_ mv "$tmpmv" "$tmprom"
|
|
|
|
# we only need insert grub.elf once, for each coreboot config:
|
|
cbfs "$tmprom" "$grubelf" "$grub_cbfs"
|
|
|
|
printf "set grub_scan_disk=\"%s\"\n" "$grub_scan_disk" \
|
|
> "$tmpdir/tmpcfg" || $err "set grub_scan_disk, $grub_scan_disk"
|
|
cbfs "$tmprom" "$tmpdir/tmpcfg" scan.cfg raw
|
|
|
|
newrom="$romdir/${payload1}_${board}_${initmode}_$displaymode.rom"
|
|
[ "$initmode" = "normal" ] && newrom="$romdir/${payload1}_" \
|
|
&& newrom="$newrom${board}_$initmode.rom"
|
|
cprom cp "$tmprom" "$newrom"
|
|
|
|
[ "$payload1" = "grub" ] && return 0
|
|
cbfs "$tmprom" "$grubdata/bootorder" bootorder raw
|
|
cprom cp "$tmprom" "${newrom%.rom}_grubfirst.rom"
|
|
}
|
|
|
|
# make a rom in /tmp/ and then print the path of that ROM
|
|
mkSeabiosRom() {
|
|
tmprom="$(mktemp -t coreboot_rom.XXXXXXXXXX)" # 1=cbrom, 2=cbfs path
|
|
_seabioself="elf/seabios/default/$initmode/bios.bin.elf"
|
|
|
|
x_ cp "$1" "$tmprom"
|
|
cbfs "$tmprom" "$_seabioself" "$2"
|
|
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" ] || cbfs "$tmprom" "$seavgabiosrom" \
|
|
vgaroms/seavgabios.bin raw
|
|
|
|
printf "%s\n" "$tmprom"
|
|
}
|
|
|
|
build_uboot_roms()
|
|
{
|
|
tmprom="$(mktemp -t coreboot_rom.XXXXXXXXXX)"
|
|
newrom="$romdir/uboot_payload_${board}_${initmode}_$displaymode.rom"
|
|
x_ cp "$cbrom" "$tmprom"
|
|
cbfs "$tmprom" "$ubootelf" "fallback/payload"
|
|
cprom mv "$tmprom" "$newrom"
|
|
}
|
|
|
|
cprom()
|
|
{
|
|
printf "Creating target image: %s\n" "$3"
|
|
|
|
x_ mkdir -p "${3%/*}"
|
|
x_ $1 "$2" "$3"
|
|
}
|
|
|
|
main $@
|