From eb54e427e6f0d447a120c55165e797e73d123396 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Mon, 28 Aug 2023 18:10:35 +0100 Subject: [PATCH] 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 --- resources/grub/config/grub.cfg | 14 ++- resources/grub/config/grub_memdisk.cfg | 7 +- script/build/boot/roms_helper | 134 ++++++++++--------------- script/build/grub/payload | 79 ++++++--------- 4 files changed, 100 insertions(+), 134 deletions(-) diff --git a/resources/grub/config/grub.cfg b/resources/grub/config/grub.cfg index b03a1741..586eb145 100644 --- a/resources/grub/config/grub.cfg +++ b/resources/grub/config/grub.cfg @@ -29,8 +29,18 @@ set default="0" set timeout=30 set pager=1 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 { set root="${1}" 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' { search_isolinux ata } +if [ -f (cbfsdisk)/grubtest.cfg ]; then menuentry 'Load test configuration (grubtest.cfg) inside of CBFS [t]' --hotkey='t' { set root='(cbfsdisk)' if [ -f /grubtest.cfg ]; then configfile /grubtest.cfg fi } +fi menuentry 'Search for GRUB2 configuration on external media [s]' --hotkey='s' { search_grub usb } diff --git a/resources/grub/config/grub_memdisk.cfg b/resources/grub/config/grub_memdisk.cfg index c9f22ff1..0763801b 100644 --- a/resources/grub/config/grub_memdisk.cfg +++ b/resources/grub/config/grub_memdisk.cfg @@ -1,4 +1,7 @@ set prefix=(memdisk)/boot/grub -set root='cbfsdisk' -source (cbfsdisk)/grub.cfg +if [ -f (cbfsdisk)/grub.cfg ]; then + source (cbfsdisk)/grub.cfg +else + source (memdisk)/boot/grub/grub_default.cfg +fi diff --git a/script/build/boot/roms_helper b/script/build/boot/roms_helper index 5dea7fc0..64de5843 100755 --- a/script/build/boot/roms_helper +++ b/script/build/boot/roms_helper @@ -68,6 +68,8 @@ displaymode="" cbcfg="" targetdir="" +grubelf="elf/grub/grub.elf" + main() { while [ $# -gt 0 ]; do @@ -215,34 +217,21 @@ build_dependency_grub() [ "${payload_grub}" != "y" ] && \ [ "${payload_seabios_withgrub}" != "y" ] && return 0 - if [ -f "elf/grub/grub_usqwerty.cfg" ]; then - sha1sumcmd="sha1sum resources/grub/config/grub.cfg" - grubrefchecksum="$(${sha1sumcmd} | awk '{print $1}')" - - 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 + 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}" - - grubelf="elf/grub/grub_${keymap}.elf" - 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 + [ ! -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() @@ -324,7 +313,8 @@ build_seabios_roms() { if [ "${payload_seabios_withgrub}" = "y" ]; then 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}" \ "${displaymode}" "seabios_withgrub" || \ err "build_roms: cannot build grub roms, seabios w/grub" @@ -356,18 +346,50 @@ build_grub_roms() { 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}" - elif [ "${payload_seabios_withgrub}" ] && \ + 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="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="" if [ -z ${keyboard_layouts} ]; then for kmapfile in "${kmapdir}"/*; do @@ -386,16 +408,7 @@ build_grub_roms() { keymap="${keymapfile##*/}" keymap="${keymap%.gkb}" - grub_path_in_cbfs="fallback/payload" - [ "${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}")" + tmpgrubrom="$(mkGrubRom "${keymap}" "${tmprompath}")" if [ "${initmode}" = "normal" ]; then newrompath="${romdir}/${firstpayloadname}_${board}_" @@ -415,61 +428,16 @@ build_grub_roms() { mkGrubRom() { target_keymap="${1}" target_cbrom="${2}" - target_grubelf_cbfs_path="${3}" # e.g. fallback/payload - grubelf="elf/grub/grub_${target_keymap}.elf" - grubcfg="elf/grub/grub_${target_keymap}.cfg" - grubtestcfg="elf/grub/grub_${target_keymap}_test.cfg" + 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-payload -f "${grubelf}" \ - -n ${target_grubelf_cbfs_path} -c lzma || \ - 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" + "${cbfstool}" "${tmprom}" add -f "${keymapcfg}" -n keymap.cfg -t raw \ + || err "mkGrubRom: cannot add keymap.cfg to tmprom" printf "%s\n" "${tmprom}" } diff --git a/script/build/grub/payload b/script/build/grub/payload index 63849bac..f8a49b64 100755 --- a/script/build/grub/payload +++ b/script/build/grub/payload @@ -24,7 +24,6 @@ set -u -e . "include/err.sh" grubcfgsdir="resources/grub" -keymap="" . "${grubcfgsdir}/modules.list" @@ -34,13 +33,40 @@ main() 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 - 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 - 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() @@ -58,47 +84,4 @@ handle_dependencies() 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 $@