summaryrefslogtreecommitdiff
path: root/resources/grub/config/grub.cfg
blob: 7bc0adf4564e253ca7888d6e6b638a904287a8cb (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
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
terminat_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: "
	unset ddev
	if [ (${1}?) != "(${1}?)" ]; then
		ddev=(${1}*) # Both raw and partitioned devices
	fi
	for i in ${ddev}; do
		echo -n "${i} "
		try_user_config "${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 {
	unset ddev
	if [ (${1}?) != "(${1}?)" ]; then
		ddev=(${1}*) # Both raw and partitioned devices.
		echo -n "Attempting to parse isolinux menu from: "
	fi
	for i in ${ddev}; do
		echo -n "${i} "
		try_isolinux_config "${i}"
	done
	echo # Insert newline
}
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
	unset lvmvol
	for vol in bootvol rootvol; do
		if [ (lvm\/?atrix-${vol}) != "(lvm/?atrix-${vol})" ]; then # Sketchy check, hardcoded string to be dropped in future
			lvmvol="${lvmvol} (lvm/matrix-${vol})"
		fi
	done
	unset raidvol
	if [ (md/?) != "(md/?)" ] ; then
		raidvol=(md/?)
	fi
	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!
#TODO: Unset variables before use!
#TODO: Pick better variable name scheme than ${ddev}, or find way to make it local
	unset ahcidev
	unset atadev
	if [ (ahci?) != "(ahci?)" ]; then
		ahcilist=(ahci*)
		for part in ${ahcilist}; do
				ahcidev="$part $ahcidev"
		done
	fi
	if [ (ata?) != "(ata?)" ]; then
		atalist=(ata*)
		for part in ${atalist}; do
				atadev="$part $atadev"
		done
	fi
	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

# Rescan lvm volumes, should probably use test at this point
	unset lvmvol
	for vol in bootvol rootvol; do
		if [ (lvm\/?atrix-${vol}) != "(lvm/?atrix-${vol})" ]; then # Sketchy check, hardcoded string to be dropped in future
			lvmvol="${lvmvol} (lvm/matrix-${vol})"
		fi
	done

#	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