summaryrefslogtreecommitdiff
path: root/config/grub/config/grub.cfg
blob: 1511d524258c83b7db090b738c14fd0b04cb2dab (plain)
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
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
elif [ -f (cbfsdisk)/keymap.cfg ]; then
	source (cbfsdisk)/keymap.cfg
else
	keymap usqwerty
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; 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 {
	echo "\nAttempting to parse isolinux/syslinux 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_without_config {

}

menuentry 'Load Operating System (incl. fully encrypted disks)  [o]' --hotkey='o' {

	if [ "${grub_scan_disk}" != "ata" ]; then
		search_grub ahci
	fi
	if [ "${grub_scan_disk}" != "ahci" ]; then
		search_grub 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_user_config "${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_user_config "${vol}"
	done

	search_grub crypto

	for vol in lvm/* ; do
		try_user_config "${vol}"
	done

	# bruteforce as a last result. figure out how to boot
	# linux without a grub configuration file. (crypto and lvm unsupported)
	set vmlinuz=""
	set initrd=""
	set devtype=""
	set devnum=""
	set devletter=""
	set partnum=""
	for t in ata ahci; do
		set vmlinuz=""
		set initrd=""
		if [ "${t}" = "ata" ] && [ "${grub_scan_disk}" = "ahci" ]; then
			continue
		elif [ "${t}" = "ahci" ] && [ "${grub_scan_disk}" = "ata" ]; then
			continue
		fi
		for dev in 0 1 2 3 4 5 6 7 8; do
			for part in 1 2 3 4 5 6 7 8 9; do
				set root="${t}${devnum},${partnum}"
				set devnum="${dev}"
				set partnum="${part}"
				for k in /vmlinuz* @/vmlinuz*; do
					if [ ! -f "${k}" ] || [ ! -d /boot ]; then
						continue
					fi
					set vmlinuz="${k}"
					# do not break. if furthe rentries are
					# available, due to alphabetic sorting,
					# the next entry is likely a newer
					# kernel version
				done
				for k in /boot/vmlinuz* @/boot/vmlinuz*; do
					if [ "${vmlinuz}" != "" ]; then
						break
					fi
					set vmlinuz="${k}"
				done
				if [ "${vmlinuz}" = "" ]; then
					continue
				fi
				for i in /initrd* /initramfs* @/initrd* @/initramfs*; do
					if [ ! -f "${i}" ] || [ ! -d "/boot" ]; then
						continue
					done
					set initrd="${i}"
					# ditto. do not break yet
				done
				for i in /boot/initrd* /boot/initramfs* @/boot/initrd* @/boot/initramfs*; do
					if [ "${initrd}" != "" ]; then
						break
					fi
					set initrd="${i}"
				done
				if [ "${vmlinuz}" != "" ] && [ "${initrd}" != "" ]; then
					set devtype="${t}"
					break
				fi
				set vmlinuz=""
				set initrd=""
			done
			if [ "${vmlinuz}" != "" ] && [ "${initrd}" != "" ]; then
				break
			fi
		done
		if [ "${vmlinuz}" != "" ] && [ "${initrd}" != "" ]; then
			break
		fi
	done

	if [ "${vmlinuz}" = "" ] || [ "${initrd}" = "" ]; then
		return
	fi
	if [ "${devnum}" = "0" ]; then
		set devletter="a"
	elif [ "${devnum}" = "1" ]; then
		set devletter="b"
	elif [ "${devnum}" = "2" ]; then
		set devletter="c"
	elif [ "${devnum}" = "3" ]; then
		set devletter="d"
	elif [ "${devnum}" = "4" ]; then
		set devletter="e"
	elif [ "${devnum}" = "5" ]; then
		set devletter="f"
	elif [ "${devnum}" = "6" ]; then
		set devletter="g"
	elif [ "${devnum}" = "7" ]; then
		set devletter="h"
	elif [ "${devnum}" = "8" ]; then
		set devletter="i"
	fi
	set btrfsvol=""
	if [ "${vmlinuz#@}" != "${vmlinuz}" ]; then
		set btrfsvol="rootflags=subvol=@"
	fi
	set root="${devtype}${devnum},${partnum}"
	linux ${vmlinuz} root=/dev/sd${devletter}${partnum} ${btrfsvol} rw
	initrd ${initrd}

	true # Prevent pager requiring to accept each line instead of whole screen
}

menuentry 'Find and load GRUB config from USB drive  [s]' --hotkey='s' {
	search_grub usb
}
menuentry 'Find and load ISOLINUX/EXTLINUX from USB drive  [u]' --hotkey='u' {
	search_isolinux usb
}
menuentry 'Find and load ISOLINUX/EXTLINUX menu via AHCI  [a]' --hotkey='a' {
	search_isolinux ahci
}
menuentry 'Find and load ISOLINUX/EXTLINUX menu via 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
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