Files
lbmk/script/build/boot/roms_helper
T
Leah Rowe 49b266eb42 build/boot/roms: only do 1 custom kbd/payload/mode
-k, -p and -d let you set keymap, payload and displaymode
respectively, but the handling for this is buggy when
passing multiple arguments.

Support only one argument, for simplicity. This is how
people use them anyway, and it makes lbmk less buggy.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2023-09-30 16:14:27 +01:00

505 lines
15 KiB
Bash
Executable File

#!/usr/bin/env sh
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2020,2021,2023 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 Alper Nebi Yasak <alpernebiyasak@gmail.com>
# SPDX-FileCopyrightText: 2023 Riku Viitanen <riku.viitanen@protonmail.com>
[ "x${DEBUG+set}" = 'xset' ] && set -v
set -u -e
. "include/err.sh"
. "include/boot.sh"
read projectname < projectname
cfgsdir="config/coreboot"
blobs_required=""
ubdir=""
kmapdir="config/grub/keymap"
grub_timeout=""
grub_scan_disk="undefined"
tree="undefined"
arch="undefined"
# Disable all payloads by default.
# target.cfg files have to specifically enable [a] payload(s)
payload_grub="n"
payload_grub_withseabios="n" # seabios chainloaded from grub
payload_seabios="n"
payload_seabios_withgrub="n" # i386-coreboot grub from SeaBIOS boot menu
payload_memtest="n"
payload_uboot="n"
uboot_config="undefined"
romdir=""
cbdir=""
cbfstool=""
corebootrom=""
seavgabiosrom="elf/seabios/default/libgfxinit/vgabios.bin"
grub_background="background1280x800.png"
initmode=""
displaymode=""
cbcfg=""
targetdir=""
grubelf="elf/grub/grub.elf"
# main() is in include/boot.sh
handle_targets()
{
board="${boards%% *}"
configure_target
build_dependencies
build_target
}
configure_target()
{
targetdir="${cfgsdir}/${board}"
[ -d "${targetdir}" ] || \
err "Target not defined: ${board}"
[ -f "${targetdir}/target.cfg" ] || \
err "Missing target.cfg for target: ${board}"
# Override the above defaults using target.cfg
. "${targetdir}/target.cfg"
[ "${grub_scan_disk}" = "undefined" ] && \
grub_scan_disk="both"
[ "${grub_scan_disk}" != "both" ] && \
[ "${grub_scan_disk}" != "ata" ] && \
[ "${grub_scan_disk}" != "ahci" ] && \
grub_scan_disk="both"
[ "${tree}" = "undefined" ] && \
err "Target '${board}' defines no tree. Skipping build."
[ "${arch}" = "undefined" ] && \
err "Target '${board}' defines no arch. Skipping build."
[ "${payload_memtest}" != "y" ] && \
payload_memtest="n"
[ "${payload_grub_withseabios}" = "y" ] && \
payload_grub="y"
if [ "${payload_grub_withseabios}" = "y" ]; then
payload_seabios="y"
payload_seabios_withgrub="y"
fi
[ "${payload_seabios_withgrub}" = "y" ] && \
payload_seabios="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
if [ "${payload_grub}" != "y" ] && \
[ "${payload_seabios}" != "y" ] && \
[ "${payload_uboot}" != "y" ]; then
for configfile in "${targetdir}/config/"*; do
[ -e "${configfile}" ] || continue
err "target '${board}' defines no payload"
done
fi
[ "${payload_uboot}" != "n" ] && [ "${payload_uboot}" != "y" ] && \
payload_uboot="n"
[ "${payload_uboot}" = "y" ] && [ "${uboot_config}" = "undefined" ] && \
uboot_config="default"
[ "${blobs_required}" != "n" ] && [ "${blobs_required}" != "y" ] && \
blobs_required="y"
# Override all payload directives with cmdline args
if [ ! -z ${_payload} ]; then
printf "setting payload to: %s\n" "${_payload}"
payload_grub="n"
payload_grub_withseabios="n" # seabios chainloaded from grub
payload_seabios="n"
payload_seabios_withgrub="n" # i386-coreboot grub from SeaBIOS
payload_uboot="n"
payload_memtest="n"
eval "payload_${_payload}=y"
fi
}
build_dependencies()
{
romdir="bin/${board}"
cbdir="coreboot/${board}"
[ "${board}" = "${tree}" ] || \
cbdir="coreboot/${tree}"
cbfstool="cbutils/${tree}/cbfstool"
corebootrom="${cbdir}/build/coreboot.rom"
./build coreboot utils ${tree} || err "cannot build cbutils/${tree}"
build_dependency_seabios
memtest_bin="memtest86plus/build${arch#*_}/memtest.bin"
[ "${payload_memtest}" != "y" ] || [ -f "${memtest_bin}" ] || \
./handle make file -b ${memtest_bin%/*} || \
err "cannot build memtest86+"
rm -f "${romdir}"/* || err "cannot: rm -f \"${romdir}\"/*"
build_dependency_grub
build_dependency_uboot
}
build_dependency_seabios()
{
[ "${payload_seabios}" = "y" ] || return 0
if [ ! -f "${seavgabiosrom}" ] \
|| [ ! -f elf/seabios/default/libgfxinit/bios.bin.elf ] \
|| [ ! -f elf/seabios/default/vgarom/bios.bin.elf ] \
|| [ ! -f elf/seabios/default/normal/bios.bin.elf ]; then
./handle make config -b seabios || \
err "cannot build seabios"
fi
}
build_dependency_grub()
{
[ "${payload_grub}" != "y" ] && \
[ "${payload_seabios_withgrub}" != "y" ] && return 0
rebuild_grub="n"
[ ! -f "${grubelf}" ] && rebuild_grub="y"
for keymapfile in "${kmapdir}"/*.gkb; do
[ "${rebuild_grub}" = "y" ] || break
[ -f "${keymapfile}" ] || continue
keymap="${keymapfile##*/}"
keymap="${keymap%.gkb}"
[ ! -f "elf/grub/keymap_${keymap}.cfg" ] && \
rebuild_grub="y" && break
done
if [ "${rebuild_grub}" = "y" ]; then
./build grub payload || \
err "build_dependency_grub: cannot build grub payload"
fi
}
build_dependency_uboot()
{
[ "${payload_uboot}" = "y" ] || return 0
./handle make config -b u-boot ${board} || \
err "cannot build u-boot target: ${board}"
ubdir="elf/u-boot/${board}/${uboot_config}"
ubootelf="${ubdir}/u-boot.elf"
[ ! -f "${ubootelf}" ] && [ -f "${ubdir}/u-boot.bin" ] && \
ubootelf="${ubdir}/u-boot.bin"
if [ ! -f "${ubootelf}" ]; then
err "Could not find u-boot build for board, ${board}"
fi
}
build_target()
{
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}" "${displaymode}" "${initmode}"
done
done
}
# Main ROM building function. This calls all other functions below
build_roms()
{
cbcfg="${1}"
displaymode="${2}"
initmode="${3}"
[ ! -f "${cbcfg}" ] && \
printf "'%s' does not exist. Skipping build for %s %s %s\n" \
"${cbcfg}" "${board}" "${displaymode}" "${initmode}" \
1>&2 && return 0
./handle make config -b coreboot ${board} || \
err "build_roms: cannot build coreboot for target: ${board}"
_corebootrom="elf/coreboot/${board}/${initmode}_${displaymode}"
[ "${initmode}" = "normal" ] && \
_corebootrom="${_corebootrom%_${displaymode}}"
_corebootrom="${_corebootrom}/coreboot.rom"
corebootrom="$(mktemp -t coreboot_rom.XXXXXXXXXX)"
cp "${_corebootrom}" "${corebootrom}" || \
err "build_roms: cannot copy rom"
[ "${payload_memtest}" != "y" ] || \
"${cbfstool}" "${corebootrom}" add-payload \
-f "${memtest_bin}" -n img/memtest -c lzma || \
err "build_roms: cannot add img/memtest to coreboot rom"
[ "${payload_seabios}" = "y" ] && \
build_seabios_roms
[ "${payload_grub}" != "y" ] || \
build_grub_roms "${corebootrom}" "${initmode}" \
"${displaymode}" "grub" || \
err "build_roms: build_grub_roms failed"
if [ "${payload_uboot}" = "y" ]; then
build_uboot_roms
fi
}
build_seabios_roms()
{
if [ "${payload_seabios_withgrub}" = "y" ]; then
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
cp "${corebootrom}" "${tmprom}" || \
err "build_seabios_roms: cannot copy to tmprom"
build_grub_roms "${tmprom}" "${initmode}" \
"${displaymode}" "seabios_withgrub" || \
err "build_roms: cannot build grub roms, seabios w/grub"
rm -f "${tmprom}" || err "build_roms: can't remove tmprom"
else
x=${corebootrom}
y=${initmode}
t=$(mkSeabiosRom "$x" "fallback/payload" "$y") || \
err "build_seabios_roms: cannot build tmprom"
if [ "${initmode}" = "normal" ]; then
newrompath="${romdir}/seabios_${board}_"
newrompath="${newrompath}${initmode}.rom"
else
newrompath="${romdir}/seabios_${board}_"
newrompath="${newrompath}${initmode}_"
newrompath="${newrompath}${displaymode}.rom"
fi
moverom "${t}" "${newrompath}" || \
err "build_roms: cannot copy rom"
rm -f "${t}" || err "cannot rm ${t}"
fi
}
# Make separate ROM images with GRUB payload, for each supported keymap
build_grub_roms() {
tmprompath="${1}"
initmode="${2}"
displaymode="${3}"
firstpayloadname="${4}" # allow values: grub, seabios, seabios_withgrub
grubelf_cbfs="fallback/payload"
x=${tmprompath}
y=${initmode}
if [ "${payload_grub_withseabios}" = "y" ] && \
[ "${firstpayloadname}" = "grub" ]; then
mv "$(mkSeabiosRom "${x}" "seabios.elf" "${y}")" \
"${tmprompath}" || \
err "build_grub_roms: cannot move tmp rom (seabios.elf)"
elif [ "${payload_seabios_withgrub}" = "y" ] && \
[ "${firstpayloadname}" != "grub" ]; then
mv "$(mkSeabiosRom "${x}" "fallback/payload" "$y")" \
"${tmprompath}" || \
err "build_grub_roms: cannot move SeaBIOS ROM to tmprom"
grubelf_cbfs="img/grub2"
fi
# we only need insert grub.elf once, for each coreboot config:
"${cbfstool}" "${tmprompath}" add-payload -f "${grubelf}" \
-n ${grubelf_cbfs} -c lzma || \
err "build_grub_roms: cannot add grub payload to tmprom"
# we only need insert background.png once, for each coreboot config:
if [ "${displaymode}" = "vesafb" ] || \
[ "${displaymode}" = "corebootfb" ]; then
backgroundfile="config/grub/background/${grub_background}"
"${cbfstool}" "${tmprompath}" add -f ${backgroundfile} \
-n background.png -t raw || \
err "build_grub_roms: cannot add background.png to tmprom"
fi
tmpcfg=$(mktemp -t coreboot_rom.XXXXXXXXXX) ||
err "mkGrubRom: cannot create temporary scan.cfg"
printf "set grub_scan_disk=\"%s\"\n" "${grub_scan_disk}" > \
"${tmpcfg}" || \
err "mkGrubRom: cannot insert into temporary scan.cfg"
[ "${grub_scan_disk}" = "both" ] || \
"${cbfstool}" "${tmprompath}" add -f "${tmpcfg}" -n scan.cfg \
-t raw || err "mkGrubROM: cannot insert scan.cfg into CBFS"
printf "set timeout=%s\n" "${grub_timeout}" > "${tmpcfg}" || \
err "mkGrubRom: cannot insert into temporary timeout.cfg"
[ -z "${grub_timeout}" ] || \
"${cbfstool}" "${tmprompath}" add -f "${tmpcfg}" -n timeout.cfg \
-t raw || err "mkGrubROM: cannot insert timeout.cfg into CBFS"
rm -f "${tmpcfg}" || err "cannot delete tmpcfg"
keymaps=""
for kmapfile in "${kmapdir}"/*; do
keymaps="${keymaps} ${kmapfile}"
done
[ -z ${_keyboard_layout} ] || \
keymaps="${kmapdir}/${_keyboard_layout}.gkb"
for keymapfile in ${keymaps}; do
printf "keymaps is %s, keymapfile is %s\n" \
"${keymaps}" "${keymapfile}"
[ -f "${keymapfile}" ] || continue
keymap="${keymapfile##*/}"
keymap="${keymap%.gkb}"
tmpgrubrom="$(mkGrubRom "${keymap}" "${tmprompath}")"
if [ "${initmode}" = "normal" ]; then
newrompath="${romdir}/${firstpayloadname}_${board}_"
newrompath="${newrompath}${initmode}_${keymap}.rom"
else
newrompath="${romdir}/${firstpayloadname}_${board}_"
newrompath="${newrompath}${initmode}_${displaymode}_"
newrompath="${newrompath}${keymap}.rom"
fi
moverom "${tmpgrubrom}" "${newrompath}" || \
err "build_grub_roms, moverom"
rm -f "${tmpgrubrom}" || err "rm tmpgrubrom, build_grub_roms"
done
}
# make a rom in /tmp/ and then print the path of that ROM
mkGrubRom() {
target_keymap="${1}"
target_cbrom="${2}"
keymapcfg="elf/grub/keymap_${target_keymap}.cfg"
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX) || \
err "mkGrubRom: cannot create tmprom"
cp "${target_cbrom}" "${tmprom}" || \
err "mkGrubRom: cannot copy to tmprom"
"${cbfstool}" "${tmprom}" add -f "${keymapcfg}" -n keymap.cfg -t raw \
|| err "mkGrubRom: cannot add keymap.cfg to tmprom"
printf "%s\n" "${tmprom}"
}
# make a rom in /tmp/ and then print the path of that ROM
mkSeabiosRom() {
target_cbrom="${1}" # rom to insert seabios in. will not be touched
# (a tmpfile will be made instead)
target_seabios_cbfs_path="${2}" # e.g. fallback/payload
target_initmode="${3}" # e.g. libgfxinit
target_seabioself="elf/seabios/default/${target_initmode}/bios.bin.elf"
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
cp "${target_cbrom}" "${tmprom}" || \
err "mkSeabiosRom: cannot copy to tmprom"
"${cbfstool}" "${tmprom}" add-payload -f "${target_seabioself}" \
-n ${target_seabios_cbfs_path} -c lzma || \
err "mkSeabiosRom: can't add payload, ${target_seabioself}, to rom"
"${cbfstool}" "${tmprom}" add-int -i 3000 -n etc/ps2-keyboard-spinup \
|| err "mkSeabiosRom: cbfs add-int etc/ps2-keyboard-spinup 3000"
if [ "${target_initmode}" = "normal" ] || \
[ "${target_initmode}" = "libgfxinit" ]; then
"${cbfstool}" "${tmprom}" add-int -i 2 \
-n etc/pci-optionrom-exec || \
err "mkSeabiosRom: cbfs add-int etc/pci-optionrom-exec 2"
elif [ "${target_initmode}" = "vgarom" ]; then # coreboot executes it
"${cbfstool}" "${tmprom}" add-int -i 0 \
-n etc/pci-optionrom-exec || \
err "mkSeabiosRom: cbfs add-int etc/pci-optionrom-exec 0"
fi # for undefined modes, don't add this integer. use SeaBIOS defaults
"${cbfstool}" "${tmprom}" add-int -i 0 -n etc/optionroms-checksum || \
err "mkSeabiosRom: cbfs add-int etc/optionroms-checksum 0"
[ "${target_initmode}" != "libgfxinit" ] || \
"${cbfstool}" "${tmprom}" add -f "${seavgabiosrom}" \
-n vgaroms/seavgabios.bin -t raw || \
err "mkSeabiosRom: cbfs add-raw vgaroms/seavgabios.bin"
printf "%s\n" "${tmprom}"
}
build_uboot_roms()
{
x=${corebootrom}
y=${uboot_config}
z=${cbfstool}
tmprom="$(mkUbootRom "$x" "fallback/payload" "$y" "$z")"
newrompath="${romdir}/uboot_payload_${board}_${initmode}_${displaymode}.rom"
[ "${initmode}" = "normal" ] && \
newrompath="${romdir}/uboot_payload_${board}_${initmode}.rom"
moverom "${tmprom}" "${newrompath}" || \
err "build_roms: moverom fail (u-boot)"
rm -f "${tmprom}" || \
err "build_roms: cannot rm u-boot rom"
}
# make a rom in /tmp/ and then print the path of that ROM
mkUbootRom() {
target_cbrom="${1}" # rom to insert u-boot in. it won't be touched
# (a tmpfile will be made instead)
target_uboot_cbfs_path="${2}" # e.g. fallback/payload
target_uboot_config="${3}"
cbfstool_path="${4}"
target_ubdir="elf/u-boot/${board}/${target_uboot_config}"
target_ubootelf="${target_ubdir}/u-boot.elf"
[ -f "${target_ubootelf}" ] || \
target_ubootelf="${target_ubdir}/u-boot.bin"
[ -f "${target_ubootelf}" ] || \
err "mkUbootRom: ${board}: cant find u-boot build"
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
cp "${target_cbrom}" "${tmprom}" || \
err "mkUbootRom: cannot copy to tmprom"
"${cbfstool}" "${tmprom}" add-payload -f "${target_ubootelf}" \
-n ${target_uboot_cbfs_path} -c lzma || \
err "mkUbootRom: cannot add u-boot to tmprom"
printf "%s\n" "${tmprom}"
}
# it is assumed that no other work will be done on the ROM
# after calling this function. therefore this function is "final"
moverom() {
rompath="${1}"
newrompath="${2}"
printf "\nCreating new ROM image: %s\n" "${newrompath}"
[ -d "${newrompath%/*}" ] || mkdir -p "${newrompath%/*}/" || \
err "moverom: cannot create rom directory: \"${newrompath%/*}\""
[ "${blobs_required}" = "n" ] && \
newrompath="${newrompath%.rom}_noblobs.rom"
cp "${rompath}" "${newrompath}" || err "moverom: can't copy rom"
}
main $@