1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
menuentry 'Load Operating System (incl. fully encrypted disks) [o]' --hotkey='o' {
# GRUB handles (almost) every possible disk setup, but only the location of /boot is actually important,
# since GRUB only loads the user's config. As soon as the kernel takes over, libreboot's done.
# 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 GRUB as payload and probably desired/used
# by most users, libreboot GRUB config tries to load the operating system (kernel) in the following way:
# 1. Try to decrypt raw devices first. This <your disk setup> inside a LUKS container is pretty common
# a) Try LVM and RAID first, they might be used (accross multiple (raw) devices)
# b) Always try LVM before RAID (LVM on (raw) RAID)
# c) Try MBR/GPT partitions at last, one might still conviniently uses a single partition
for d in (lvm/*) md/0 (md/0,*) ahci0 ahci1 (ahci0,*) (ahci1,*); do
# prompt user for passphrase if LUKS header is found
cryptomount ${d}
done
# (This way, we only need to scan for encrypted data once while covering every possible disk setup,
# be it LVM/BTRFS/ZFS/ext4/etc. (on LUKS) (on RAID) on/across raw devices/MBR/GPT
# 2. Look for user config. If the above routine successfully decrypted a LUKS container, its content
# will be searched before everything else for obvious reasons. Regardless of this, the devices'
# hirachy stays the same.
for d in crypto0 (crypt0,*) (lvm/*) md/0 (md0/,*) ahci0 ahci1 (ahci0,*) (ahci1,*); do
set root=${d}
# a) Check possible file locations...
for p in boot/grub/libreboot_ grub/libreboot_ boot/grub/ grub/ boot/grub2 grub2/; do
if [ -f "/${p}grub.cfg" ]; then
# b) And eventually try to load the config. Using ESC one can still exit and revert back to
# libreboot's menu.
configfile /${p}grub.cfg
fi
done
done
# prompt user for passphrase if LUKS header is found but try using external keyfiles first
search -n -f /keyfile --set=kf --hint usb0, --hint usb1,
if [ $? = 0 ]; then
kf="-k (${kf})/keyfile ${d}"
fi
# (This way, we only need to scan for encrypted data once while covering every possible disk setup,
# be it LVM/BTRFS/ZFS/ext4/etc. (on LUKS) (on RAID) on/across raw devices/MBR/GPT
for d in ${devs}; do
cryptomount ${kf} ${d}
done
# 3. Do the same routine again, but for possibly decrypted data this time. There might be an LVM
# inside the LUKS container, but check crypto0 first since lvm/* also covers already existing (and
# therefore already scanned volumes as well)
for d in crypto0 (crypt0,*) (lvm/*); do
set root=${d}
for p in boot/grub/libreboot_ grub/libreboot_ boot/grub/ grub/ boot/grub2 grub2/; do
if [ -f "/${p}grub.cfg" ]; then
configfile /${p}grub.cfg
fi
done
done
# 3. Last resort, if none of the above succeeds, all you have is GRUB's shell
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
}
menuentry 'Parse ISOLINUX menu (AHCI) [a]' --hotkey='a' {
for i in 0 1; do
# Check for filesystem on raw device without partition table (MBR/GPT), e.g. BTRFS or ZFS
set root=ahci${i}
for p in /isolinux /syslinux; do
if [ -f "${p}${p}.cfg" ]; then
syslinux_configfile -i ${p}${p}.cfg
elif [ -f "/boot${p}${p}.cfg" ]; then
syslinux_configfile -i /boot${p}${p}.cfg
fi
done
# Look for partitions
# GPT allows more than 4 partitions, /boot on /dev/sda7 is quite unlikely but still possible
for j in 0 1 2 3 4 5 6 7 8 9; do
set root="ahci${i},${j}"
for p in /isolinux /syslinux; do
if [ -f "${p}${p}.cfg" ]; then
syslinux_configfile -i ${p}${p}.cfg
elif [ -f "/boot${p}${p}.cfg" ]; then
syslinux_configfile -i /boot${p}${p}.cfg
fi
done
done
done
}
menuentry 'Parse ISOLINUX menu (USB) [u]' --hotkey='u' {
for i in 0 1; do
# Check for filesystem on raw device without partition table (MBR/GPT), e.g. BTRFS or ZFS
set root=usb${i}
for p in /isolinux /syslinux; do
if [ -f "${p}${p}.cfg" ]; then
syslinux_configfile -i ${p}${p}.cfg
elif [ -f "/boot${p}${p}.cfg" ]; then
syslinux_configfile -i /boot${p}${p}.cfg
fi
done
# Look for partitions
# GPT allows more than 4 partitions, /boot on /dev/sda7 is quite unlikely but still possible
for j in 0 1 2 3 4 5 6 7 8 9; do
set root=usb${i},${j}
for p in "/isolinux" "/syslinux"; do
if [ -f "${p}${p}.cfg" ]; then
syslinux_configfile -i ${p}${p}.cfg
elif [ -f "/boot${p}${p}.cfg" ]; then
syslinux_configfile -i /boot${p}${p}.cfg
fi
done
done
done
}
menuentry 'Parse ISOLINUX menu (CD/DVD) [d]' --hotkey='d' {
insmod ata
for x in ata0 ahci1; do
set root=${x}
for p in "/isolinux" "/syslinux"; do
if [ -f "${p}${p}.cfg" ]; then
syslinux_configfile -i ${p}${p}.cfg
elif [ -f "/boot${p}${p}.cfg" ]; then
syslinux_configfile -i /boot${p}${p}.cfg
fi
done
done
}
menuentry 'Switch to grubtest.cfg [t]' --hotkey='t' {
set root=cbfsdisk
configfile /grubtest.cfg
}
menuentry 'Search for GRUB configuration (grub.cfg) outside of CBFS [s]' --hotkey='s' {
for i in usb0 usb1 ahci0 ahci1; do
for j in 1 2 3 4 5 6 7 8 9; do
x=${i},${j}
for p in "grub" "boot/grub" "grub2" "boot/grub2"; do
if [ -f "${x}/${p}/grub.cfg" ]; then
submenu "Load Config from ${x}" ${x} {
root=$2
source /${p}/grub.cfg
unset superusers
}
fi
done
done
done
}
menuentry 'Poweroff [p]' --hotkey='p' {
halt
}
menuentry 'Reboot [r]' --hotkey='r' {
reboot
}
|