mirror of
https://git.savannah.gnu.org/git/gnuboot.git
synced 2025-01-05 15:57:40 +01:00
c98308c499
hardcode everything. in practise, the new logic will work just the same in almost all cases, for most people, but it works around performance issues in grub. cleanup of grub.cfg will be done in the next commit
249 lines
7.2 KiB
INI
249 lines
7.2 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
|
|
|
|
# Serial and keyboard configuration, very important.
|
|
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
|
|
|
|
# Default to first option, automatically boot after 1 second
|
|
set default="0"
|
|
set timeout=10
|
|
|
|
# This is useful when using 'cat' on long files on GRUB terminal
|
|
set pager=1
|
|
|
|
keymap usqwerty
|
|
function try_user_config {
|
|
set root="${1}"
|
|
for dir in 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: "
|
|
# TODO : Find a better way to detect how many disks
|
|
# : are on the computer instead of hardcoding.
|
|
# FIXME: Does this work on all boards?
|
|
for i in 0 1 2 3 4 5 6 7 8 9 10 11; do
|
|
# TODO : Find a better way to detect how many partitions
|
|
# : are on the disk instead of hardcoding.
|
|
echo "\nTrying disk ${1}${i}"
|
|
for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
|
|
# MBR/GPT partitions
|
|
echo "\nTrying partiton ${part}"
|
|
try_user_config "(${1}${i},${part})"
|
|
done
|
|
# raw devices
|
|
echo "\nTrying to boot to a raw disk ..."
|
|
try_user_config "(${1}${i})"
|
|
echo # Insert newline
|
|
done
|
|
}
|
|
|
|
function try_isolinux_config {
|
|
set root="${1}"
|
|
for dir in '' /boot; 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
|
|
fi
|
|
done
|
|
}
|
|
function search_isolinux {
|
|
for i in 0 1 2 3 4 5 6 7 8 9 10 11; do
|
|
# TODO : Find a better way to detect how many partitions
|
|
# : are on the disk instead of hardcoding.
|
|
echo "\nAttempting to parse isolinux menu from ${1}${i}"
|
|
for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
|
|
# MBR/GPT partitions
|
|
echo "\nTrying partiton ${part}"
|
|
try_isolinux_config "(${1}${i},${part})"
|
|
done
|
|
# raw devices
|
|
echo "\nTrying raw usb device ..."
|
|
try_isolinux_config "(${1}${i})"
|
|
echo # Insert newline
|
|
done
|
|
|
|
}
|
|
menuentry 'Load Operating System (incl. fully encrypted disks) [o]' --hotkey='o' {
|
|
# GRUB2 handles (almost) every possible disk setup, but only the location of
|
|
# /boot is actually important since GRUB2 only loads the user's config.
|
|
|
|
# LVM, RAID, filesystems and encryption on both raw devices and partitions in
|
|
# all various combinations need to be supported. Since full disk encryption is
|
|
# possible with GRUB2 as payload and probably even used by most users, this
|
|
# configuration tries to load the operating system in the following way:
|
|
|
|
# 1. Look for user configuration on unencrypted devices first to avoid
|
|
# unnecessary decryption routines in the following order:
|
|
|
|
# 1) raw devices and MBR/GPT partitions
|
|
search_grub ahci
|
|
search_grub ata
|
|
# 2) LVM and RAID which might be used accross multiple devices
|
|
lvmvol="lvm/matrix-bootvol lvm/matrix-rootvol"
|
|
# TODO: add more entries to this string in the future, with common
|
|
# volume group names per common distro configs. look at what all the
|
|
# popular distros are doing when the user select automatic partitioning
|
|
# in their distro's installer. this still won't cover all use cases,
|
|
# but grub's enumeration of anything partition-related is very slow,
|
|
# so for now we hardcode everything in grub.cfg
|
|
|
|
# again, hardcoded. grub's enumeration is always very slow.
|
|
# until that is optimized, we must hardcode everything in grub.cfg
|
|
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
|
|
# ok, even if less technically correct
|
|
# TODO: optimize grub itself, and use */? here for everything
|
|
|
|
for vol in ${lvmvol} ${raidvol} ; do
|
|
try_user_config "${vol}"
|
|
done
|
|
# 2. In case no configuration could be found, try decrypting devices. Look
|
|
# on raw crypto devices as well as inside LVM volumes this time.
|
|
|
|
# The user will be prompted for a passphrase if a LUKS header was found.
|
|
# Encrypted disks and partitions
|
|
#TODO: This needs to be adjusted on each device to exclude ODD
|
|
#TODO: Usually ATA is for odd if both exist!
|
|
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
|
|
ahcidev="(ahci${i},${part}) ${ahcidev}"
|
|
atadev="(ata${i},${part}) ${atadev}"
|
|
done
|
|
done
|
|
|
|
set pager=0
|
|
echo -n "Attempting to cryptomount: "
|
|
for dev in ${ahcidev} ${atadev} ${lvmvol} ${raidvol}; do
|
|
echo -n "${dev} "
|
|
if cryptomount "${dev}" ; then break ; fi
|
|
done
|
|
set pager=1
|
|
echo # Insert newline
|
|
|
|
# Retry lvm volumes, because after cryptomount, they might now be exposed
|
|
|
|
# 3) LVM inside LUKS containers
|
|
for vol in ${lvmvol}; do
|
|
try_user_config "${vol}"
|
|
done
|
|
|
|
# 4) encrypted devices/partitions
|
|
search_grub crypto
|
|
|
|
# TODO: generalize last resorts
|
|
# Use first connected device? not just sata port 1
|
|
|
|
# Last resort, if all else fails
|
|
set root=ahci0,1
|
|
for p in / /boot/; do
|
|
if [ -f "${p}vmlinuz" ]; then
|
|
linux ${p}vmlinuz root=/dev/sda1 rw
|
|
if [ -f "${p}initrd.img" ]; then
|
|
initrd ${p}initrd.img
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Last resort (for setups that use IDE instead of SATA)
|
|
set root=ata0,1
|
|
for p in / /boot/; do
|
|
if [ -f "${p}vmlinuz" ]; then
|
|
linux ${p}vmlinuz root=/dev/sda1 rw
|
|
if [ -f "${p}initrd.img" ]; then
|
|
initrd ${p}initrd.img
|
|
fi
|
|
fi
|
|
done
|
|
|
|
true # Prevent pager requiring to accept each line instead of whole screen
|
|
}
|
|
|
|
menuentry 'Search ISOLINUX menu (AHCI) [a]' --hotkey='a' {
|
|
search_isolinux ahci
|
|
}
|
|
menuentry 'Search ISOLINUX menu (USB) [u]' --hotkey='u' {
|
|
search_isolinux usb
|
|
}
|
|
menuentry 'Search ISOLINUX menu (CD/DVD) [d]' --hotkey='d' {
|
|
insmod ata
|
|
unset ahcidev
|
|
unset atadev
|
|
if [ (ata?) != "(ata?)" ]; then
|
|
atadev=(ata?) # Only full drives not partitions
|
|
fi
|
|
if [ (ahci?) != "(ahci?)" ]; then
|
|
ahcidev=(ahci1) # TODO: hardcoded!!!
|
|
fi
|
|
echo -n "Attempting to parse isolinux menu from: "
|
|
for dev in ${atadev} ${ahcidev}; do
|
|
echo -n "${dev} "
|
|
try_isolinux_config "${dev}"
|
|
done
|
|
echo # Insert newline
|
|
}
|
|
menuentry 'Load test configuration (grubtest.cfg) inside of CBFS [t]' --hotkey='t' {
|
|
set root='(cbfsdisk)'
|
|
if [ -f /grubtest.cfg ]; then
|
|
configfile /grubtest.cfg
|
|
fi
|
|
}
|
|
menuentry 'Search for GRUB2 configuration on external media [s]' --hotkey='s' {
|
|
search_grub usb
|
|
}
|
|
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
|