Files
lbmk/config/grub/config/grub.cfg
T
Leah Rowe 37817e6bcb GRUB: insert only 1 keymap per board, in cbfs
There is no need to add multiple keymap files, because
GRUB can load keymaps from CBFS. The current build logic
is designed to avoid building multiple GRUB binaries,
which are expensive computationally because each one
would then have to be compressed for each board.

This patch provides the best of both worlds: less space
used in flash like in the old lbmk design (1 keymap per
board), but retaining the current build speeds and therefore
not re-introducing the slowness of lbmk's previous GRUB
build logic.

The grub.cfg file has been modified, accordingly. It now
only loads a keymap.gkb file from CBFS, by default. It does
this, only if that file exists; if not, GRUB already defaults
to US Qwerty layout anyway.

ALSO: compress all keymap gkb files with xz -6

GRUB automatically decompresses files when accessed.
This results in about 2KB of flash space saved in CBFS.

Here is real-world data, showing the increased flash space:

< fallback/payload               0x3eb80    simple elf     548821 none
< keymap.cfg                     0xc4bc0    raw                16 none
< (empty)                        0xc4c00    null         11633316 none
---
> fallback/payload               0x3eb80    simple elf     546787 none
> keymap.gkb                     0xc43c0    raw               344 none
> (empty)                        0xc4540    null         11635044 none

This was taken by diffing the cbfstool "print" output,
both before and after. The *after* result is with this change.
11633316. In this example, 1728 bytes have been saved. Therefore,
with compression taken into account, this patch saves about 1.7KB
of space in CBFS.

This change means that lbmk can now scale to support hundreds
of keymaps, without increasing the amount of flash space used,
in each given image. Since the keymap files are compressed in
lbmk.git, in advance, we spend no additional time on compression
at build time. The resulting change in build speed in negligible.

Adding your own keymap.gkb file was already possible, for changing
the keymap in libreboot images, if you didn't want to change the
memdisk (and thus re-compile grub.elf). Now, this is the default
behaviour, and the only way to do it. It's much more efficient.

The original keymap files can be restored, by running unxz.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2024-01-18 00:27:33 +00:00

201 lines
5.1 KiB
INI

set prefix=(memdisk)/boot/grub
insmod at_keyboard
insmod usb_keyboard
insmod nativedisk
insmod ehci
insmod ohci
insmod uhci
insmod usb
insmod usbms
insmod regexp
terminal_input --append at_keyboard
terminal_input --append usb_keyboard
terminal_output --append cbmemc
gfxpayload=keep
terminal_output --append gfxterm
if [ -f (cbfsdisk)/background.png ]; then
insmod png
background_image (cbfsdisk)/background.png
elif [ -f (cbfsdisk)/background.jpg ]; then
insmod jpeg
background_image (cbfsdisk)/background.jpg
fi
set default="0"
if [ -f (cbfsdisk)/timeout.cfg ]; then
source (cbfsdisk)/timeout.cfg
else
set timeout=5
fi
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
fi
function try_user_config {
set root="${1}"
# The @/... entries are for cases where the BTRFS filesystem is being used
for dir in boot grub grub2 boot/grub boot/grub2 @/boot @/grub @/grub2 @/boot/grub @/boot/grub2; do
for name in '' osboot_ autoboot_ libreboot_ coreboot_; do
if [ -f /"${dir}"/"${name}"grub.cfg ]; then
unset superusers
configfile /"${dir}"/"${name}"grub.cfg
fi
done
done
}
function search_grub {
echo -n "Attempting to load grub.cfg from '${1}' devices"
for i in 0 1 2 3 4 5 6 7 8 9 10 11; do
for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
try_user_config "(${1}${i},${part})"
done
# raw devices e.g. (ahci0) instead of (ahci0,1)
try_user_config "(${1}${i})"
done
echo # Insert newline
}
function try_isolinux_config {
set root="${1}"
for dir in '' /boot /EFI /boot/EFI /@ /@/boot /@/boot/EFI /@/EFI; do
if [ -f "${dir}"/isolinux/isolinux.cfg ]; then
syslinux_configfile -i "${dir}"/isolinux/isolinux.cfg
elif [ -f "${dir}"/syslinux/syslinux.cfg ]; then
syslinux_configfile -s "${dir}"/syslinux/syslinux.cfg
elif [ -f "${dir}"/syslinux/extlinux.conf ]; then
syslinux_configfile -s "${dir}"/syslinux/extlinux.conf
elif [ -f "${dir}"/extlinux/extlinux.conf ]; then
syslinux_configfile -s "${dir}"/extlinux/extlinux.conf
fi
done
}
function search_isolinux {
echo "\nAttempting to parse iso/sys/extlinux config from '${1}' devices"
for i in 0 1 2 3 4 5 6 7 8 9 10 11; do
for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
try_isolinux_config "(${1}${i},${part})"
done
# raw devices e.g. (usb0) instead of (usb0,1)
try_isolinux_config "(${1}${i})"
done
echo # Insert newline
}
function try_bootcfg {
try_user_config "${1}"
try_isolinux_config "${1}"
}
function search_bootcfg {
search_grub "${1}"
search_isolinux "${1}"
}
menuentry 'Load Operating System (incl. fully encrypted disks) [o]' --hotkey='o' {
if [ "${grub_scan_disk}" != "ata" ]; then
search_bootcfg ahci
fi
if [ "${grub_scan_disk}" != "ahci" ]; then
search_bootcfg ata
fi
# grub device enumeration is very slow, so checks are hardcoded
# TODO: add more strings, based on what distros set up when
# the user select auto-partitioning on those installers
lvmvol="lvm/grubcrypt-bootvol lvm/grubcrypt-rootvol"
raidvol="md/0 md/1 md/2 md/3 md/4 md/5 md/6 md/7 md/8 md/9"
# in practise, doing multiple redundant checks is perfectly fast and
# TODO: optimize grub itself, and use */? here for everything
for vol in ${lvmvol} ${raidvol} ; do
try_bootcfg "${vol}"
done
unset ahcidev
unset atadev
for i in 11 10 9 8 7 6 5 4 3 2 1 0; do
for part in 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1; do
if [ "${grub_scan_disk}" != "ata" ]; then
ahcidev="(ahci${i},${part}) ${ahcidev}"
fi
if [ "${grub_scan_disk}" != "ahci" ]; then
atadev="(ata${i},${part}) ${atadev}"
fi
done
done
set pager=0
echo -n "Attempting to unlock encrypted volumes"
for dev in ${ahcidev} ${atadev} ${lvmvol} ${raidvol}; do
if cryptomount "${dev}" ; then break ; fi
done
set pager=1
echo
# after cryptomount, lvm volumes might be available
for vol in ${lvmvol}; do
try_bootcfg "${vol}"
done
search_bootcfg crypto
for vol in lvm/* ; do
try_bootcfg "${vol}"
done
true # Prevent pager requiring to accept each line instead of whole screen
}
menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on USB [s]' --hotkey='s' {
search_bootcfg usb
}
menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on AHCI [a]' --hotkey='a' {
search_bootcfg ahci
}
menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on ATA/IDE [d]' --hotkey='d' {
search_bootcfg ahci
}
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
if [ -f (cbfsdisk)/seabios.elf ]; then
menuentry 'Load SeaBIOS (payload) [b]' --hotkey='b' {
set root='cbfsdisk'
chainloader /seabios.elf
}
fi
if [ -f (cbfsdisk)/img/grub2 ]; then
menuentry 'Return to SeaBIOS [b]' --hotkey='b' {
set root='cbfsdisk'
chainloader /fallback/payload
}
fi
menuentry 'Poweroff [p]' --hotkey='p' {
halt
}
menuentry 'Reboot [r]' --hotkey='r' {
reboot
}
if [ -f (cbfsdisk)/img/memtest ]; then
menuentry 'Load MemTest86+ [m]' --hotkey='m' {
set root='cbfsdisk'
chainloader /img/memtest
}
fi