grub: all one grub.elf containing keymaps and cfg

new behaviour:
* grub.cfg and grubtest.cfg no longer inserted to cbfs
* grub.cfg in memdisk instead
* grub.cfg in memdisk defers to cbfs/grub.cfg if added
  (not added by default, anymore)
* does not defer to grubtest.cfg even if available
* only shows link to grubtest.cfg if available,
  as a menuentry item

keymaps:
if /keymap.gkb exists in cbfs, it uses that by default,
but by default this isn't added. instead, it looks for
a file named keymap.cfg and sources that, which then
sets the keymap to one that is located under memdisk.
this file is inserted for each rom, per layout.
if keymap.gkb and keymap.cfg both absent, grub.cfg in
memdisk shall defer to usqwerty as the default keymap

grub_scan_disk: grub.cfg looks for cbfs file "scan.cfg"
and sources that if found, which will be inserted with
the string: set grub_scandisk=setting_goes_here (based
on target.cfg, generated by build/boot/roms automatically).
If no scan.cfg is found, it defaults to "both"

The "background.png" file remains unchanged, and present in
CBFS, used by grub.cfg if present (and it is, by default)

This change actually *saves* space in CBFS, due to compression,
and means that the grub.cfg is now compressed heavily. This
is also safer, because now the user overrides grub.cfg by
adding it, and they can still add grubtest.cfg for testing
first. If they accidentally delete both configs from cbfs,
Libreboot will fall back to the one in memdisk which would
presumably not be deleted.

This also means that lbmk can now more easily be used by
other build systems, that just want the GRUB part to re-use
in their own project. For example, people who want to build
custom coreboot images without using Libreboot's build system.

This change also *speeds* up the build process considerably,
on the parts where ROM images are copied. It's less than half
a second now, whereas previously it took about 30-45 seconds
for ROM images to copy, because of grub.elf being re-added in
each ROM via cbfstool, where compression is used; I believe
the compression part is what caused slowness.

Much, much faster, more versatile builds.

Signed-off-by: Leah Rowe <leah@libreboot.org>
btrfsvols
Leah Rowe 2023-08-28 18:10:35 +01:00
parent c6fd4d2ad3
commit eb54e427e6
4 changed files with 100 additions and 134 deletions

View File

@ -29,8 +29,18 @@ set default="0"
set timeout=30 set timeout=30
set pager=1 set pager=1
set grub_scan_disk="both" set grub_scan_disk="both"
if [ -f (cbfsdisk)/scan.cfg ]; then
source (cbfsdisk)/scan.cfg
fi
if [ -f (cbfsdisk)/keymap.gkb ]; then
keymap (cbfsdisk)/keymap.gkb
elif [ -f (cbfsdisk)/keymap.cfg ]; then
source (cbfsdisk)/keymap.cfg
else
keymap usqwerty
fi
keymap usqwerty
function try_user_config { function try_user_config {
set root="${1}" set root="${1}"
for dir in boot grub grub2 boot/grub boot/grub2; do for dir in boot grub grub2 boot/grub boot/grub2; do
@ -165,12 +175,14 @@ menuentry 'Search ISOLINUX menu (USB) [u]' --hotkey='u' {
menuentry 'Search ISOLINUX menu (ATA/IDE) [d]' --hotkey='d' { menuentry 'Search ISOLINUX menu (ATA/IDE) [d]' --hotkey='d' {
search_isolinux ata search_isolinux ata
} }
if [ -f (cbfsdisk)/grubtest.cfg ]; then
menuentry 'Load test configuration (grubtest.cfg) inside of CBFS [t]' --hotkey='t' { menuentry 'Load test configuration (grubtest.cfg) inside of CBFS [t]' --hotkey='t' {
set root='(cbfsdisk)' set root='(cbfsdisk)'
if [ -f /grubtest.cfg ]; then if [ -f /grubtest.cfg ]; then
configfile /grubtest.cfg configfile /grubtest.cfg
fi fi
} }
fi
menuentry 'Search for GRUB2 configuration on external media [s]' --hotkey='s' { menuentry 'Search for GRUB2 configuration on external media [s]' --hotkey='s' {
search_grub usb search_grub usb
} }

View File

@ -1,4 +1,7 @@
set prefix=(memdisk)/boot/grub set prefix=(memdisk)/boot/grub
set root='cbfsdisk' if [ -f (cbfsdisk)/grub.cfg ]; then
source (cbfsdisk)/grub.cfg source (cbfsdisk)/grub.cfg
else
source (memdisk)/boot/grub/grub_default.cfg
fi

View File

@ -68,6 +68,8 @@ displaymode=""
cbcfg="" cbcfg=""
targetdir="" targetdir=""
grubelf="elf/grub/grub.elf"
main() main()
{ {
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
@ -215,34 +217,21 @@ build_dependency_grub()
[ "${payload_grub}" != "y" ] && \ [ "${payload_grub}" != "y" ] && \
[ "${payload_seabios_withgrub}" != "y" ] && return 0 [ "${payload_seabios_withgrub}" != "y" ] && return 0
if [ -f "elf/grub/grub_usqwerty.cfg" ]; then rebuild_grub="n"
sha1sumcmd="sha1sum resources/grub/config/grub.cfg" [ ! -f "${grubelf}" ] && rebuild_grub="y"
grubrefchecksum="$(${sha1sumcmd} | awk '{print $1}')" for keymapfile in "${kmapdir}"/*.gkb; do
[ "${rebuild_grub}" = "y" ] || break
sha1sumcmd="sha1sum elf/grub/grub_usqwerty.cfg"
grubbuildchecksum="$(${sha1sumcmd} | awk '{print $1}')"
[ "${grubrefchecksum}" != "${grubbuildchecksum}" ] && \
printf "GRUB change detected. Re-building.\n" 1>&2
else
printf "GRUB not built yet. Building now.\n" 1>&2
fi
for keymapfile in "${kmapdir}"/*; do
[ -f "${keymapfile}" ] || continue [ -f "${keymapfile}" ] || continue
keymap="${keymapfile##*/}" keymap="${keymapfile##*/}"
keymap="${keymap%.gkb}" keymap="${keymap%.gkb}"
[ ! -f "elf/grub/keymap_${keymap}.cfg" ] && \
grubelf="elf/grub/grub_${keymap}.elf" rebuild_grub="y" && break
grubcfg="elf/grub/grub_${keymap}.cfg"
grubtestcfg="elf/grub/grub_${keymap}_test.cfg"
if [ ! -f "${grubelf}" ] || [ ! -f "${grubcfg}" ] || \
[ ! -f "${grubtestcfg}" ]; then
./build grub payload || \
err "cannot build grub payload"
fi
done done
if [ "${rebuild_grub}" = "y" ]; then
./build grub payload || \
err "build_dependency_grub: cannot build grub payload"
fi
} }
build_dependency_uboot() build_dependency_uboot()
@ -324,7 +313,8 @@ build_seabios_roms()
{ {
if [ "${payload_seabios_withgrub}" = "y" ]; then if [ "${payload_seabios_withgrub}" = "y" ]; then
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX) tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX)
cp "${corebootrom}" "${tmprom}" cp "${corebootrom}" "${tmprom}" || \
err "build_seabios_roms: cannot copy to tmprom"
build_grub_roms "${tmprom}" "${initmode}" \ build_grub_roms "${tmprom}" "${initmode}" \
"${displaymode}" "seabios_withgrub" || \ "${displaymode}" "seabios_withgrub" || \
err "build_roms: cannot build grub roms, seabios w/grub" err "build_roms: cannot build grub roms, seabios w/grub"
@ -356,18 +346,50 @@ build_grub_roms() {
displaymode="${3}" displaymode="${3}"
firstpayloadname="${4}" # allow values: grub, seabios, seabios_withgrub firstpayloadname="${4}" # allow values: grub, seabios, seabios_withgrub
grubelf_cbfs="fallback/payload"
x=${tmprompath} x=${tmprompath}
y=${initmode} y=${initmode}
if [ "${payload_grub_withseabios}" = "y" ] && \ if [ "${payload_grub_withseabios}" = "y" ] && \
[ "${firstpayloadname}" = "grub" ]; then [ "${firstpayloadname}" = "grub" ]; then
mv "$(mkSeabiosRom "${x}" "seabios.elf" "${y}")" "${tmprompath}" mv "$(mkSeabiosRom "${x}" "seabios.elf" "${y}")" "${tmprompath}"
elif [ "${payload_seabios_withgrub}" ] && \ elif [ "${payload_seabios_withgrub}" = "y" ] && \
[ "${firstpayloadname}" != "grub" ]; then [ "${firstpayloadname}" != "grub" ]; then
mv "$(mkSeabiosRom "${x}" "fallback/payload" "$y")" \ mv "$(mkSeabiosRom "${x}" "fallback/payload" "$y")" \
"${tmprompath}" || \ "${tmprompath}" || \
err "build_grub_roms: cannot move SeaBIOS ROM to tmprom" err "build_grub_roms: cannot move SeaBIOS ROM to tmprom"
grubelf_cbfs="img/grub2"
fi 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="background1280x800.png"
if [ "${board}" = "x60" ] \
|| [ "${board}" = "t60_intelgpu" ]; then
# TODO: don't hardcode this. do it in target.cfg
backgroundfile="background1024x768.png"
fi
backgroundfile="resources/grub/background/${backgroundfile}"
"${cbfstool}" "${tmprompath}" add -f ${backgroundfile} \
-n background.png -t raw || \
err "build_grub_roms: cannot add background.png to tmprom"
fi
tmpscancfg=$(mktemp -t coreboot_rom.XXXXXXXXXX) ||
err "mkGrubRom: cannot create temporary scan.cfg"
printf "set grub_scan_disk=\"%s\"\n" "${grub_scan_disk}" > \
"${tmpscancfg}" || \
err "mkGrubRom: cannot insert into temporary scan.cfg"
"${cbfstool}" "${tmprompath}" add -f "${tmpscancfg}" -n scan.cfg \
-t raw || err "mkGrubROM: cannot insert scan.cfg into CBFS"
keymaps="" keymaps=""
if [ -z ${keyboard_layouts} ]; then if [ -z ${keyboard_layouts} ]; then
for kmapfile in "${kmapdir}"/*; do for kmapfile in "${kmapdir}"/*; do
@ -386,16 +408,7 @@ build_grub_roms() {
keymap="${keymapfile##*/}" keymap="${keymapfile##*/}"
keymap="${keymap%.gkb}" keymap="${keymap%.gkb}"
grub_path_in_cbfs="fallback/payload" tmpgrubrom="$(mkGrubRom "${keymap}" "${tmprompath}")"
[ "${firstpayloadname}" = "grub" ] || \
grub_path_in_cbfs="img/grub2"
# evil bofh rfc 2646 compliance hack
x=${keymap}
y=${tmprompath}
z=${grub_path_in_cbfs}
tmpgrubrom="$(mkGrubRom "${x}" "${y}" "${z}")"
if [ "${initmode}" = "normal" ]; then if [ "${initmode}" = "normal" ]; then
newrompath="${romdir}/${firstpayloadname}_${board}_" newrompath="${romdir}/${firstpayloadname}_${board}_"
@ -415,61 +428,16 @@ build_grub_roms() {
mkGrubRom() { mkGrubRom() {
target_keymap="${1}" target_keymap="${1}"
target_cbrom="${2}" target_cbrom="${2}"
target_grubelf_cbfs_path="${3}" # e.g. fallback/payload
grubelf="elf/grub/grub_${target_keymap}.elf" keymapcfg="elf/grub/keymap_${target_keymap}.cfg"
grubcfg="elf/grub/grub_${target_keymap}.cfg"
grubtestcfg="elf/grub/grub_${target_keymap}_test.cfg"
tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX) || \ tmprom=$(mktemp -t coreboot_rom.XXXXXXXXXX) || \
err "mkGrubRom: cannot create tmprom" err "mkGrubRom: cannot create tmprom"
cp "${target_cbrom}" "${tmprom}" || \ cp "${target_cbrom}" "${tmprom}" || \
err "mkGrubRom: cannot copy to tmprom" err "mkGrubRom: cannot copy to tmprom"
"${cbfstool}" "${tmprom}" add-payload -f "${grubelf}" \ "${cbfstool}" "${tmprom}" add -f "${keymapcfg}" -n keymap.cfg -t raw \
-n ${target_grubelf_cbfs_path} -c lzma || \ || err "mkGrubRom: cannot add keymap.cfg to tmprom"
err "mkGrubRom: cannot add grub payload to tmprom"
tmpgrubcfg=$(mktemp -t grub.cfg.XXXXXXXXXX)
tmpgrubtestcfg=$(mktemp -t grubtest.cfg.XXXXXXXXXX)
if [ "${grub_scan_disk}" = "ahci" ]; then
sed \
's/set\ grub_scan_disk=\"both\"/set\ grub_scan_disk=\"ahci\"/' \
"${grubcfg}" > "${tmpgrubcfg}" || err "mkGrubRom: sed1"
sed \
's/set\ grub_scan_disk=\"both\"/set\ grub_scan_disk=\"ahci\"/' \
"${grubtestcfg}" > "${tmpgrubtestcfg}" || \
err "mkGrubRom: sed2"
elif [ "${grub_scan_disk}" = "ata" ]; then
sed \
's/set\ grub_scan_disk=\"both\"/set\ grub_scan_disk=\"ata\"/' \
"${grubcfg}" > "${tmpgrubcfg}" || err "mkGrubRom: sed3"
sed \
's/set\ grub_scan_disk=\"both\"/set\ grub_scan_disk=\"ata\"/' \
"${grubtestcfg}" > "${tmpgrubtestcfg}" || \
err "mkGrubRom: sed4"
else
cp "${grubcfg}" "${tmpgrubcfg}" || err "mkGrubRom: grub.cfg cp"
cp "${grubtestcfg}" "${tmpgrubtestcfg}" || \
err "mkGrubRom: grubtest.cfg cp"
fi
"${cbfstool}" "${tmprom}" add -f "${tmpgrubcfg}" -n grub.cfg -t raw || \
err "mkGrubRom: cannot add grub.cfg to tmprom"
"${cbfstool}" "${tmprom}" add -f "${tmpgrubtestcfg}" -n grubtest.cfg \
-t raw || err "mkGrubRom: cannot add grubtest.cfg to tmprom"
rm -f "${tmpgrubcfg}" "${tmpgrubtestcfg}" || \
err "mkGrubRom: cannot remove tmp grub.cfg / grubtest.cfg"
backgroundfile="background1280x800.png"
if [ "${board}" = "x60" ] || [ "${board}" = "t60_intelgpu" ]; then
# TODO: don't hardcode this. do it in target.cfg per board
backgroundfile="background1024x768.png"
fi
backgroundfile="resources/grub/background/${backgroundfile}"
"${cbfstool}" "${tmprom}" add -f ${backgroundfile} -n background.png \
-t raw || err "mkGrubRom: cannot add background.png to tmprom"
printf "%s\n" "${tmprom}" printf "%s\n" "${tmprom}"
} }

View File

@ -24,7 +24,6 @@ set -u -e
. "include/err.sh" . "include/err.sh"
grubcfgsdir="resources/grub" grubcfgsdir="resources/grub"
keymap=""
. "${grubcfgsdir}/modules.list" . "${grubcfgsdir}/modules.list"
@ -34,13 +33,40 @@ main()
handle_dependencies handle_dependencies
# Separate GRUB payload per keymap to save space in ROM. for keylayoutfile in "${grubcfgsdir}/keymap/"*.gkb; do
for keylayoutfile in ${grubcfgsdir}/keymap/*.gkb; do
[ -f "${keylayoutfile}" ] || continue [ -f "${keylayoutfile}" ] || continue
build_grub_payloads "${keylayoutfile}" keymap="${keylayoutfile##${grubcfgsdir}/keymap/}"
keymap="${keymap%.gkb}"
printf "keymap %s\n" "${keymap}" > \
"elf/grub/keymap_${keymap}.cfg" || \
err "make_keymapcfgs: cannot create elf/grub/keymap_${keymap}.cfg"
done done
printf "Done! Check elf/grub/ to see the files.\n\n" grub/grub-mkstandalone \
--grub-mkimage="grub/grub-mkimage" \
-O i386-coreboot \
-o "elf/grub/grub.elf" \
-d grub/grub-core/ \
--fonts= --themes= --locales= \
--modules="${grub_modules}" \
--install-modules="${grub_install_modules}" \
"/boot/grub/layouts/colemak.gkb=${grubcfgsdir}/keymap/colemak.gkb" \
"/boot/grub/layouts/deqwertz.gkb=${grubcfgsdir}/keymap/deqwertz.gkb" \
"/boot/grub/layouts/esqwerty.gkb=${grubcfgsdir}/keymap/esqwerty.gkb" \
"/boot/grub/layouts/frazerty.gkb=${grubcfgsdir}/keymap/frazerty.gkb" \
"/boot/grub/layouts/frdvbepo.gkb=${grubcfgsdir}/keymap/frdvbepo.gkb" \
"/boot/grub/layouts/itqwerty.gkb=${grubcfgsdir}/keymap/itqwerty.gkb" \
"/boot/grub/layouts/svenska.gkb=${grubcfgsdir}/keymap/svenska.gkb" \
"/boot/grub/layouts/trqwerty.gkb=${grubcfgsdir}/keymap/trqwerty.gkb" \
"/boot/grub/layouts/ukdvorak.gkb=${grubcfgsdir}/keymap/ukdvorak.gkb" \
"/boot/grub/layouts/ukqwerty.gkb=${grubcfgsdir}/keymap/ukqwerty.gkb" \
"/boot/grub/layouts/usdvorak.gkb=${grubcfgsdir}/keymap/usdvorak.gkb" \
"/boot/grub/layouts/usqwerty.gkb=${grubcfgsdir}/keymap/usqwerty.gkb" \
"/boot/grub/grub.cfg=${grubcfgsdir}/config/grub_memdisk.cfg" \
"/boot/grub/grub_default.cfg=${grubcfgsdir}/config/grub.cfg" \
err "build_grub_elf: cannot build grub payload (grub-mkstandalone)"
printf "\nDone! Check elf/grub/\n\n"
} }
handle_dependencies() handle_dependencies()
@ -58,47 +84,4 @@ handle_dependencies()
err "handle_dependencies: cannot rm inside: elf/grub/" err "handle_dependencies: cannot rm inside: elf/grub/"
} }
build_grub_payloads()
{
keylayoutfile=${1}
[ -f "${keylayoutfile}" ] || continue
keymap="${keylayoutfile##${grubcfgsdir}/keymap/}"
keymap="${keymap%.gkb}"
build_grub_elf "${keylayoutfile}"
create_grub_config
printf "Created 'elf/grub/grub_%s.elf' and configs.'\n" "${keymap}"
}
build_grub_elf()
{
keylayoutfile=${1}
gcfg="/boot/grub/grub.cfg=${grubcfgsdir}"
gcfg="${gcfg}/config/grub_memdisk.cfg"
grubk="/boot/grub/layouts/${keymap}.gkb=${keylayoutfile}"
grub/grub-mkstandalone \
--grub-mkimage="grub/grub-mkimage" \
-O i386-coreboot \
-o "elf/grub/grub_${keymap}.elf" \
-d grub/grub-core/ \
--fonts= --themes= --locales= \
--modules="${grub_modules}" \
--install-modules="${grub_install_modules}" \
"${gcfg}" "${grubk}" || \
err "build_grub_elf: cannot build grub payload (grub-mkstandalone)"
}
create_grub_config()
{
sed "s/usqwerty/${keymap}/" < "${grubcfgsdir}/config/grub.cfg" \
> "elf/grub/grub_${keymap}.cfg" || \
err "create_grub_config: sed failed: grub.cfg"
sed "s/grubtest.cfg/grub.cfg/" < "elf/grub/grub_${keymap}.cfg" \
> "elf/grub/grub_${keymap}_test.cfg" || \
err "create_grub_config: sed failed: grubtest.cfg"
}
main $@ main $@