summaryrefslogtreecommitdiff
path: root/resources/grub/config/grub.cfg
blob: b03a1741c984e145144467a38a75b78f26328162 (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
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"
set timeout=30
set pager=1
set grub_scan_disk="both"

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 '${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
}
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/matrix-bootvol lvm/matrix-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

	if [ "${grub_scan_disk}" != "ata" ]; then
		# 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
	fi

	if [ "${grub_scan_disk}" != "ahci" ]; then
		# 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
	fi

	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 (ATA/IDE)  [d]' --hotkey='d' {
	search_isolinux ata
}
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