mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-28 15:09:04 +02:00
it didn't work in the past, but it does work nowadays; specifically, it only worked with libgfxinit in the past, but not on VGA ROMs. now it does work on VGA ROMs, tested on e6400 and t1650 so it was enabled there. in this setup, a special image is provided where SeaBIOS is the main payload, but it only loads GRUB; nothing else, every. this is called SeaGRUB. this setup is useful in cases where the user only has a GPU that lacks libgfxinit support. Signed-off-by: Leah Rowe <leah@libreboot.org>
475 lines
14 KiB
Bash
Executable File
475 lines
14 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# SPDX-FileCopyrightText: 2014-2016,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-2023 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/option.sh"
|
|
|
|
seavgabiosrom="elf/seabios/default/libgfxinit/vgabios.bin"
|
|
grub_background="background1280x800.png"
|
|
grubelf="elf/grub/grub.elf"
|
|
cfgsdir="config/coreboot"
|
|
kmapdir="config/grub/keymap"
|
|
|
|
# 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"
|
|
pv="${pv} payload_seabios_withgrub payload_seabios_grubonly payload_uboot memtest_bin"
|
|
v="romdir cbrom initmode displaymode cbcfg targetdir tree arch"
|
|
v="${v} grub_timeout ubdir vendorfiles board grub_scan_disk uboot_config"
|
|
eval "$(setvars "n" ${pv})"
|
|
eval "$(setvars "" ${v} boards _displaymode _payload _keyboard all targets)"
|
|
|
|
main()
|
|
{
|
|
while [ $# -gt 0 ]; do
|
|
case ${1} in
|
|
help) usage && exit 0 ;;
|
|
list) items config/coreboot && exit 0 ;;
|
|
-d) _displaymode="${2}" ;;
|
|
-p) _payload="${2}" ;;
|
|
-k) _keyboard="${2}" ;;
|
|
*)
|
|
[ "${1}" = "all" ] && all="y"
|
|
boards="${1} ${boards}"
|
|
shift && continue ;;
|
|
esac
|
|
shift 2
|
|
done
|
|
|
|
[ "${all}" != "y" ] || boards=$(items config/coreboot) || \
|
|
err "Cannot generate list of boards for building"
|
|
|
|
for x in ${boards}; do
|
|
eval "$(setvars "n" ${pv})"
|
|
eval "$(setvars "" ${v})"
|
|
grub_background="background1280x800.png"
|
|
board="${x}"
|
|
check_target
|
|
prepare_target
|
|
[ -d "bin/${board}" ] || continue
|
|
targets="* bin/${board}\n${targets}"
|
|
done
|
|
|
|
[ -z "${targets}" ] && err "No ROM images were compiled"
|
|
printf "\nROM images available in these directories:\n"
|
|
printf "${targets}^^ ROM images available in these directories.\n\n"
|
|
|
|
printf "DO NOT flash ROM images from elf/ - please use bin/ instead.\n"
|
|
}
|
|
|
|
check_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 "Target '${board}' defines no tree. Skipping build."
|
|
[ -z "${arch}" ] && \
|
|
err "Target '${board}' defines no arch. Skipping build."
|
|
|
|
[ "${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"
|
|
if [ "${payload_seabios_grubonly}" = "y" ]; then
|
|
payload_seabios="y"
|
|
payload_seabios_withgrub="y"
|
|
fi
|
|
|
|
# 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"
|
|
[ "${vendorfiles}" != "n" ] && [ "${vendorfiles}" != "y" ] && \
|
|
vendorfiles="y"
|
|
|
|
# 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"
|
|
}
|
|
|
|
prepare_target()
|
|
{
|
|
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}
|
|
|
|
build_dependency_seabios
|
|
|
|
memtest_bin="memtest86plus/build64/memtest.bin"
|
|
[ "${payload_memtest}" != "y" ] || [ -f "src/${memtest_bin}" ] || \
|
|
x_ ./update trees -b memtest86plus
|
|
|
|
rm -f "${romdir}/"* || err "!prepare, rm files, ${romdir}"
|
|
|
|
build_dependency_grub
|
|
build_dependency_uboot
|
|
build_target
|
|
}
|
|
|
|
build_dependency_seabios()
|
|
{
|
|
[ "${payload_seabios}" = "y" ] || return 0
|
|
[ -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 ] && return 0
|
|
|
|
x_ ./update trees -b seabios
|
|
}
|
|
|
|
build_dependency_grub()
|
|
{
|
|
[ "${payload_grub}" != "y" ] && \
|
|
[ "${payload_seabios_withgrub}" != "y" ] && \
|
|
[ "${payload_seabios_grubonly}" != "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
|
|
[ "${rebuild_grub}" = "y" ] || return 0
|
|
x_ ./build grub
|
|
}
|
|
|
|
build_dependency_uboot()
|
|
{
|
|
[ "${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}" ] && [ -f "${ubdir}/u-boot" ] && \
|
|
ubootelf="${ubdir}/u-boot"
|
|
[ -f "${ubootelf}" ] && return 0
|
|
err "Could not find u-boot build for board, ${board}"
|
|
}
|
|
|
|
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}"
|
|
done
|
|
done
|
|
}
|
|
|
|
# Main ROM building function. This calls all other functions below
|
|
build_roms()
|
|
{
|
|
cbcfg="${1}"
|
|
[ ! -f "${cbcfg}" ] && \
|
|
printf "'%s' does not exist. Skipping build for %s %s %s\n" \
|
|
"${cbcfg}" "${board}" "${displaymode}" "${initmode}" \
|
|
1>&2 && return 0
|
|
|
|
x_ ./update trees -b coreboot ${board}
|
|
|
|
_cbrom="elf/coreboot_nopayload_DO_NOT_FLASH/${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
|
|
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
|
|
x_ cp "${cbrom}" "${tmprom}"
|
|
x_ build_grub_roms "${tmprom}" "seabios_withgrub"
|
|
x_ rm -f "${tmprom}"
|
|
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"
|
|
x_ rm -f "${t}"
|
|
fi
|
|
}
|
|
|
|
# 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"
|
|
[ "${payload1}" = "grub" ] && [ "${payload_grub_withseabios}" = "y" ] \
|
|
&& x_ mv "$(mkSeabiosRom "${tmprom}" "seabios.elf")" "${tmprom}"
|
|
[ "${payload1}" != "grub" ] && [ "${payload_seabios_withgrub}" = "y" ] \
|
|
&& grub_cbfs="img/grub2" && \
|
|
x_ mv "$(mkSeabiosRom "${tmprom}" fallback/payload)" "${tmprom}"
|
|
|
|
# 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}"
|
|
|
|
keymaps=""
|
|
for kmapfile in "${kmapdir}"/*; do
|
|
keymaps="${keymaps} ${kmapfile}"
|
|
done
|
|
[ -z "${_keyboard}" ] || keymaps="${kmapdir}/${_keyboard}.gkb"
|
|
|
|
for keymapfile in ${keymaps}; do
|
|
[ -f "${keymapfile}" ] || continue
|
|
keymap="${keymapfile##*/}"
|
|
keymap="${keymap%.gkb}"
|
|
tmpgrubrom="$(mkGrubRom "${keymap}" "${tmprom}")"
|
|
|
|
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}"
|
|
[ "${payload_seabios_grubonly}" = "y" ] && \
|
|
mkSeabiosGrubonlyRom "${tmpgrubrom}" "${newrom}"
|
|
x_ rm -f "${tmpgrubrom}"
|
|
done
|
|
}
|
|
|
|
# make a rom in /tmp/ and then print the path of that ROM
|
|
mkGrubRom() {
|
|
_keymap="${1}"
|
|
_cbrom="${2}"
|
|
|
|
keymapcfg="elf/grub/keymap_${_keymap}.cfg"
|
|
|
|
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
|
|
x_ cp "${_cbrom}" "${tmprom}"
|
|
x_ "${cbfstool}" "${tmprom}" add -f "${keymapcfg}" -n keymap.cfg -t raw
|
|
|
|
printf "%s\n" "${tmprom}"
|
|
}
|
|
|
|
# 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}"
|
|
}
|
|
|
|
# SeaGRUB configuration
|
|
mkSeabiosGrubonlyRom()
|
|
{
|
|
_grubrom="${1}"
|
|
_newrom="${2}"
|
|
|
|
tmpbootorder=$(mktemp -t coreboot_rom.XXXXXXXXXX)
|
|
|
|
# only load grub, by inserting a custom bootorder file
|
|
printf "/rom@img/grub2\n" > "${tmpbootorder}" || err "printf bootorder"
|
|
x_ "${cbfstool}" "${_grubrom}" \
|
|
add -f "${tmpbootorder}" -n bootorder -t raw
|
|
x_ rm -f "${tmpbootorder}"
|
|
|
|
x_ "${cbfstool}" "${_grubrom}" add-int -i 0 -n etc/show-boot-menu
|
|
|
|
x_ moverom "${_grubrom}" "${_newrom%.rom}_grubonly.rom"
|
|
}
|
|
|
|
build_uboot_roms()
|
|
{
|
|
tmprom="$(mkUbootRom "${cbrom}" "fallback/payload")"
|
|
newrom="${romdir}/uboot_payload_${board}_${initmode}_${displaymode}.rom"
|
|
[ "${initmode}" = "normal" ] && \
|
|
newrom="${romdir}/uboot_payload_${board}_${initmode}.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}"
|
|
}
|
|
|
|
# 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}"
|
|
newrom="${2}"
|
|
|
|
[ "${vendorfiles}" = "n" ] && newrom="${newrom%.rom}_noblobs.rom"
|
|
printf "Creating target image: %s\n" "${newrom}"
|
|
|
|
[ -d "${newrom%/*}" ] || x_ mkdir -p "${newrom%/*}/"
|
|
|
|
x_ modify_coreboot_rom
|
|
x_ cp "${rompath}" "${newrom}"
|
|
}
|
|
|
|
modify_coreboot_rom()
|
|
{
|
|
tmpmvrom="$(mktemp -t rom.XXXXXXXXXX)"
|
|
x_ rm -f "${tmpmvrom}"
|
|
|
|
if [ "${romtype}" = "d8d16sas" ]; then
|
|
# pike2008 roms hang seabios. an empty rom will override
|
|
# the built-in one, thus disabling all execution of it
|
|
x_ touch "${tmpmvrom}"
|
|
for deviceID in "0072" "3050"; do
|
|
x_ "${cbfstool}" "${rompath}" add -f "${tmpmvrom}" \
|
|
-n "pci1000,${deviceID}.rom" -t raw
|
|
done
|
|
elif [ "${romtype}" = "i945 laptop" ]; then
|
|
# for bucts-based installation method from factory bios
|
|
dd if="${rompath}" of="${tmpmvrom}" bs=1 \
|
|
skip=$(($(stat -c %s "${rompath}") - 0x10000)) \
|
|
count=64k || err "modrom 1, copy bootblock"
|
|
dd if="${tmpmvrom}" of="${rompath}" bs=1 \
|
|
seek=$(($(stat -c %s "${rompath}") - 0x20000)) count=64k \
|
|
conv=notrunc || err "modrom 2, insert new bootblock"
|
|
x_ rm -f "${tmpmvrom}"
|
|
fi
|
|
x_ rm -f "${tmpmvrom}"
|
|
}
|
|
|
|
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
|
|
|
|
possible values for 'target':
|
|
$(items "config/coreboot")
|
|
|
|
Refer to the ${projectname} documentation for more information.
|
|
EOF
|
|
}
|
|
|
|
main $@
|