-
Notifications
You must be signed in to change notification settings - Fork 4
/
isodetect.cfg
416 lines (365 loc) · 15.2 KB
/
isodetect.cfg
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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
## grub2
# REQUIRES GRUB2 >= 1.99 TO RUN!!!
#
# grub-script port of isodetect.lua from Super Grub2 Disk[1]
# by Ximin Luo; I release this into the public domain.
#
# isodetect.lua (Jordan Uggla) is based on listisos.lua, bootiso.lua (JustRon[2])
# All of these are released into the public domain.
#
# [1] http://www.supergrubdisk.org/
# [2] http://ubuntuforums.org/showthread.php?t=1288604
#
# This file can be used in the following ways.
#
# - as a child screen (easier to use)
# - call `configfile $this_file` with IB_AUTOSCAN=true inside a menuentry.
# When it is activated, detected isos will be listed in a child screen.
# The user may press ESC to return to the parent screen.
# - as library functionality (more flexible)
# - call `configfile $this_file` with IB_AUTOSCAN=false, which will return
# immediately without creating any menu entries in the child screen.
# - call `ib_init` immediately, before using anything else from this file
# - do any customisations such as overriding variables
# - call `iso_scanall` to perform the autoscan in the parent
# Detected isos will be listed in the parent, and will appear after other
# entries that already exist in the parent.
function ib_env_defaults
{
# If this is not set, IB_* variables will be reset to their default values.
# For example, if you override any varibles in the GRUB environment block, you
# should also set this variable in it too, or else the overrides will be reset.
IB_VAR_OVERRIDE=set
# Directory containing ISO images
IB_IMG_DIR=img
# Directory containing linux overrides for an image.
# The override for x.iso should be named x.(something), e.g. x.vmlinuz
IB_OVERRIDE_DIR_LINUX=linux
# Directory containing initrd overrides for an image.
# The override for x.iso should be named x.(something), e.g. x.initrd.gz
IB_OVERRIDE_DIR_INITRD=initrd
# Whether to detect non-standard boot layouts (slower). If not, only detects
# the loopback.cfg standard http://www.supergrubdisk.org/wiki/loopback.cfg
IB_DETECT_NONSTANDARD=yes
# Kernel boot options.
# This is currently an implementation detail and subject to change; see source
# code below for how these are used. Sorry!
IB_KERN_LANG=us
IB_LINUX_SPLASH=""
IB_LINUX_INSTALLER_DEB="keyb=$IB_KERN_LANG debian-installer/language=$IB_KERN_LANG console-setup/layoutcode?=$IB_KERN_LANG"
IB_LINUX_INSTALLER="noeject noprompt nopersistent"
}
###############################################################################
# GRUB script is not that sophistiated; we adopt a few conventions to work
# around the lack of local variables or the ability to capture command output.
#
# lower_underscore = public variable
# set by a function as its result, intended to be consumed by the caller.
# _UPPER_UNDERSCORE = private constant
# data private to a function, not meant to be accessed inappropriately.
# _lower_underscore = private variable
# emulates a local variable for a non-reentrant function by making the name
# obscure enough that it's unlikely to be clobbered by child functions.
insmod regexp # enable wildcard expansion
# note: loopdev variables are devices *without* the enclosing brackets
# this is because the "loopback" command requires it
function pause # ()
{
echo "Press any key to return to the main menu..."
read
}
# find a file by regexp
# output: ib_result_find
function find_file_regexp # (abspath, regexp)
{
ib_result_find=""
for f in "$1"/*; do
if ! [ -f "$f" ]; then continue; fi
if ! regexp "$2" "$f"; then continue; fi
ib_result_find="$f"; return 0
done
return 1
}
# find a file by wildcard glob
# output: ib_result_find
function find_file_glob # (abspath, glob)
{
ib_result_find=""
for f in "$1"/$2; do
if ! [ -f "$f" ]; then continue; fi
ib_result_find="$f"; return 0
done
return 1
}
function ib_init #
{
#_IB_ALLOWED_PATTERN='^[a-zA-Z0-9_\-\.]*$' # bug: doesn't work in grub 1.99
_IB_ALLOWED_PATTERN='^[a-zA-Z0-9_.-]+$'
_IB_RGX_MAINNAME='^(.+)\.[^.]*$|^([^.]*)$'
_IB_RGX_BASENAME='^\([^)]+\)/([^/]+/+)+([^/]+)/*$'
_IB_RGX_PATHNAME='^(\([^)]+\))(.*)$'
if [ -z "$IB_VAR_OVERRIDE" ]; then
ib_env_defaults
save_env IB_VAR_OVERRIDE
save_env IB_IMG_DIR IB_OVERRIDE_DIR_INITRD IB_OVERRIDE_DIR_LINUX
save_env IB_DETECT_NONSTANDARD
save_env IB_KERN_LANG IB_LINUX_SPLASH IB_LINUX_INSTALLER IB_LINUX_INSTALLER_DEB
fi
}
load_env
ib_init
# output: ib_result_path
function mainname { regexp -s 1:_1 -s 2:_2 "$_IB_RGX_MAINNAME" "$1"; ib_result_path="$_1$_2"; unset _1; unset _2; }
# output: ib_result_path
function basename { regexp -s 2:ib_result_path "$_IB_RGX_BASENAME" "$1"; }
# output: ib_result_path
function pathname { regexp -s 2:ib_result_path "$_IB_RGX_PATHNAME" "$1"; }
# output: ib_result_path
function devname { regexp -s 1:ib_result_path "$_IB_RGX_PATHNAME" "$1"; }
# Check that filename contains only allowed characters
function allowed_name { regexp "$_IB_ALLOWED_PATTERN" "$1"; }
# Show an error
function error_entry # (abspath, loopdev, message)
{
menuentry "Unsupported: $1" "$1" "$2" "$3" { shift # needed in grub 1.99
echo "Error: $3"
echo ""
echo -n "The iso file $1 is not supported "
echo -n "by Super GRUB2 disk. The most likely reason is that the iso is not loop "
echo -n "bootable. An iso must be specifically designed to read its root "
echo -n "filesystem from an iso file rather than looking for it in your CDROM "
echo -n "drive. It is impossible to boot an iso file not specifically designed "
echo -n "this way with GRUB or any other bootloader."
echo ""
echo ""
echo -n "If you believe that this iso file is loop-bootable it is mounted as "
echo -n "($2) so you can view its contents in the "
echo -n "grub shell and try to boot it yourself. If there are any distributions "
echo -n "that you know are loop bootable but are not currently supported by this "
echo -n "script please check that you are using the latest version of Super GRUB2 "
echo -n "Disk then send the commands required to boot the iso to "
echo -n "[email protected] so support can be added. Or even " ..
echo -n "better, convince them to ship a loopback.cfg on their isos:"
echo ""
echo ""
echo "http://www.supergrubdisk.org/wiki/loopback.cfg for more info"
echo ""
pause
}
}
# Add a menu entry for a GNU/Linux live system
function linux_entry # (abspath, loopdev, title, linux, initrd, loopkey, params)
{
# $linux, $initrd should be paths relative to $loopdev
# we also check for user overrides for the linux and initrd images
# $ib_cur_scandir is set by iso_scandir
_linux_entry__linux=""
if find_file_glob "$ib_cur_scandir$IB_OVERRIDE_DIR_LINUX" "$2"'.*'; then
_linux_entry__linux="$ib_result_find"
elif find_file_glob "($2)" "$4"; then
_linux_entry__linux="$ib_result_find"
fi
_linux_entry__initrd=""
if find_file_glob "$ib_cur_scandir$IB_OVERRIDE_DIR_INITRD" "$2"'.*'; then
_linux_entry__initrd="$ib_result_find"
elif find_file_glob "($2)" "$5"; then
_linux_entry__initrd="$ib_result_find"
fi
if [ -z "$_linux_entry__linux" ]; then
error_entry "$1" "$2" "cannot find linux image ($2)/$4 or $ib_cur_scandir$IB_OVERRIDE_DIR_LINUX/$2.*"
return 1
fi
if [ -z "$_linux_entry__initrd" ]; then
error_entry "$1" "$2" "cannot find initrd image ($2)/$5 or $ib_cur_scandir$IB_OVERRIDE_DIR_INITRD/$2.*"
return 1
fi
pathname "$1"
menuentry "$3" "$ib_result_path" "$_linux_entry__linux" "$_linux_entry__initrd" "$6" "$7" { shift # needed in grub 1.99
# isoloop=.iso needs to be the last entry, or some stuff (e.g. sysrcd) won't boot
linux "$2" $5 "$4=$1"
initrd "$3"
}
return 0
}
# Mount the iso file as a loopback device
function mount_iso # (abspath, loopdev)
{
if ! allowed_name "$2"; then
menuentry "Error: $1 has unallowed characters" "$2" { shift # needed in grub 1.99
echo -n "Only alphanumeric characters, periods, underscores, and dashes "
echo -n "are allowed as part of the filename, for compatibility reasons. "
echo ""
echo "The exact regex pattern is: $_IB_ALLOWED_PATTERN"
echo "The failing string is: $1"
echo ""
pause
}
elif [ -z "$1" ]; then
error_entry "$1" "$2" "\$abspath is undefined"
elif ! [ -f "$1" ]; then
error_entry "$1" "$2" "Cannot find image file $1"
else
if loopback "$2" "$1"; then return 0; fi
# TODO once it's possible to capture command output, use that instead
# of generic error message
error_entry "$1" "$2" "Cannot load ISO: loopback init error"
fi
return 1
}
# Detect the live system type and boots it
# Must not be called recursively # TODO (put in a guard for this)
function iso_detect # (abspath)
{
# Pick a device name that's the same name as the iso
basename "$1"; mainname "$ib_result_path"; _iso_detect__loopdev="$ib_result_path"
# Linux shouldn't be passed the grub device name, just the relative path
pathname "$1"; _iso_detect__relpath="$ib_result_path"
devname "$1"; _iso_detect__devname="$ib_result_path"
if ! mount_iso "$1" "$_iso_detect__loopdev"; then return 1; fi
# Any distro providing a loopback.cfg
_iso_detect__loopcfg=""
for path in "/boot/grub/loopback.cfg" "/grub/loopback.cfg"; do
if [ -f "($_iso_detect__loopdev)$path" ]; then
_iso_detect__loopcfg="$path"
break
fi
done
iso_detect_inner "$1" "$_iso_detect__loopdev" "$_iso_detect__relpath" "$_iso_detect__loopcfg" "$_iso_detect__devname"
}
function iso_detect_inner # (abspath, loopdev, relpath, loopcfg, devname)
{
if [ -n "$4" ]; then
menuentry "Load: $1" "$2" "$3" "$4" { shift # needed in grub 1.99
set root="($1)"
set iso_path="$2"
export iso_path
configfile "$3"
}
return 0
elif [ "$IB_DETECT_NONSTANDARD" == "no" ]; then
error_entry "$1" "$2" "Unsupported ISO type"
return 1
# auto-detect section. entries marked #? have not yet been tested
elif [ -d "($2)/casper" ]; then
# casper distros, e.g. ubuntu, backtrack
linux_entry "$1" "$2" "Boot casper: $1" 'casper/vmlinuz' 'casper/initrd*.*z' "iso-scan/filename" "boot=casper $IB_LINUX_INSTALLER $IB_LINUX_SPLASH $IB_LINUX_INSTALLER_DEB"
return 0
elif [ -d "($2)/live" ]; then
# debian-live distros, e.g. TAILS, kali. we want to do this before debian-install because some ISOs have both
_kern_opts="$IB_LINUX_INSTALLER"
if [ -f "($2)/live/Tails.module" ]; then
_kern_opts="config noswap live-media=removable nopersistent noprompt timezone=Etc/UTC block.events_dfl_poll_msecs=1000 nox11autologin"
elif [ -d "($2)/dists/kali" ]; then
_kern_opts="username=root noconfig=sudo hostname=kali"
fi
linux_entry "$1" "$2" "Boot live-boot: $1" 'live/vmlinuz' 'live/initrd.*' "findiso" "boot=live $_kern_opts $IB_LINUX_SPLASH $IB_LINUX_INSTALLER_DEB"
return 0
elif [ -d "($2)/dists" -a -d "($2)/pool" ]; then
# debian install discs
# as of this writing, you need to download the "hd-media" initrd override as well as whatever .iso image you're using
# go to https://www.debian.org/devel/debian-installer/ then "other images" then "hd-media" then "initrd.gz"
# e.g. (no https) http://ftp.nl.debian.org/debian/dists/testing/main/installer-amd64/current/images/hd-media/initrd.gz
# e.g. https://mirrors.kernel.org/debian/dists/testing/main/installer-amd64/20170407/images/hd-media/initrd.gz
# put this in $IB_OVERRIDE_DIR_INITRD/$ISO_NAME.initrd.gz then the below should work automatically
linux_entry "$1" "$2" "Boot debian: $1" 'install*/vmlinuz*' 'install*/initrd.*' "findiso" "$IB_LINUX_INSTALLER $IB_LINUX_SPLASH $IB_LINUX_INSTALLER_DEB"
return 0
elif [ -f "($2)/boot/grub/grubsrcd.cfg" ]; then
# system rescue cd, version 8+
probe --set img_dev --fs-uuid "$5"
set img_dev=/dev/disk/by-uuid/$img_dev
linux_entry "$1" "$2" "Boot sysrcd: $1" 'sysresccd/boot/x86_64/vmlinuz' 'sysresccd/boot/x86_64/sysresccd.img' "img_loop" "img_dev=$img_dev archisobasedir=sysresccd copytoram"
return 0
elif [ -f "($2)/sysrcd.dat" ]; then
# system rescue cd, older versions
linux_entry "$1" "$2" "Boot sysrcd: $1" 'isolinux/rescue*' 'isolinux/initram.igz' "isoloop" "root=/dev/ram"
return 0
elif [ -d "($2)/KNOPPIX" ]; then
# KNOPPIX
linux_entry "$1" "$2" "Boot KNOPPIX: $1" 'boot/isolinux/linux' 'boot/isolinux/minirt.gz' "bootfrom" "BOOT_IMAGE=knoppix"
return 0
elif [ -d "($2)/aptosid" ]; then
# aptosid (was sidux)
linux_entry "$1" "$2" "Boot aptosid: $1" 'boot/vmlinuz*.*' 'boot/initrd*.*' "fromiso" "boot=fll"
return 0
elif [ -d "($2)/slax/boot" ]; then
# slax 7.0+
linux_entry "$1" "$2" "Boot slax: $1" 'slax/boot/vmlinuz' 'slax/boot/initrfs.img' "from" "load_ramdisk=1 prompt_ramdisk=0 rw printk.time=0 slax.flags=perch,xmode"
return 0
elif [ -d "($2)/slax" ]; then
# slax
linux_entry "$1" "$2" "Boot slax: $1" 'boot/vmlinuz' 'boot/initrd.gz' "from" "ramdisk_size=6666 root=/dev/ram0 rw"
return 0
elif [ -d "($2)/pmagic" ]; then
#? pmagic
linux_entry "$1" "$2" "Boot pmagic: $1" 'pmagic/bzImage' 'pmagic/initramfs' "iso_filename" "edd=off noapic load_ramdisk=1 prompt_ramdisk=0 rw sleep=10 loglevel=0 keymap=$IB_KERN_LANG"
return 0
elif [ -f "($2)/boot/tinycore.gz" ]; then
#? tinycore. isoloop isn't actually used but we need that param to be non-empty
linux_entry "$1" "$2" "Boot tinycore: $1" 'boot/bzImage' 'boot/tinycore.gz' "isoloop" ""
return 0
elif [ -f "($2)/boot/gnumach" ]; then
#? arch hurd, don't think I ever tested this
menuentry "Boot Arch Hurd: $1" "$2" { shift # needed in grub 1.99
set root="($1)"
multiboot /boot/gnumach root=device:"$1"
module /hurd/iso9660fs.static --multiboot-command-line='${kernel-command-line}' --host-priv-port='${host-port}' --device-master-port='${device-port}' --exec-server-task='${exec-task}' -T typed '${root}' '$(task-create)' '$(task-resume)'
module /lib/ld-2.11.90.so /hurd/exec '$(exec-task=task-create)'
}
return 0
elif [ -f "($2)/boot/grub/grub.cfg" ]; then
if ! find_file_glob "($2)/boot/grub" '*supergrub*'; then continue; fi
# super grub2 disk
menuentry "Load SG2D: $1" "$2" { shift # needed in grub 1.99
set root="($1)"
configfile "/boot/grub/grub.cfg"
}
return 0
fi
error_entry "$1" "$2" "Unsupported ISO type"
return 1
}
function verify_checksum # (iso_dir, sum_file, sum_cmd)
{
if ! [ -f "$1/$2" ]; then return; fi
menuentry --class="checksum" "Verify $2 in $1" "$1" "$2" "$3" { shift # needed in grub 1.99
cat "$1/$2"
echo "Verifying $1/$2..."
$3 -k -c "$1/$2" -p "$1"
pause
}
}
# output ib_cur_scandir, ib_scan_found_iso
function iso_scandir # (boot_dir/)
{
ib_cur_scandir="$1"
for _iso_scandir__iso in "$1$IB_IMG_DIR"/*.iso; do
if ! [ -e "$_iso_scandir__iso" ]; then continue; fi
if ! iso_detect "$_iso_scandir__iso"; then continue; fi
ib_scan_found_iso=true
done
verify_checksum "$1$IB_IMG_DIR" MD5SUMS md5sum
verify_checksum "$1$IB_IMG_DIR" SHA1SUMS sha1sum
verify_checksum "$1$IB_IMG_DIR" SHA256SUMS sha256sum
verify_checksum "$1$IB_IMG_DIR" SHA512SUMS sha512sum
}
# Scan all devices
function iso_scanall
{
echo "Scanning for bootable ISOs in all devices. This may take a while..."
ib_scan_found_iso=false
for _iso_scanall__device in (*); do
for _iso_scanall__path in "$_iso_scanall__device/" "$_iso_scanall__device/boot/"; do
if ! [ -d "$_iso_scanall__path$IB_IMG_DIR" ]; then continue; fi
iso_scandir "$_iso_scanall__path"
done
done
if $ib_scan_found_iso; then return 0; fi
echo -n "Error: No iso files were found in the /$IB_IMG_DIR or /boot/$IB_IMG_DIR directories of "
echo -n "any device. To search inside different directories, set IB_IMG_DIR. "
echo ""
pause
return 1
}
if [ "$IB_AUTOSCAN" = "true" ]; then
iso_scanall
fi