]> code.delx.au - monosys/blob - hacks/multiboot-setup
multiboot: Add a menu item to attempt booting images from ram.
[monosys] / hacks / multiboot-setup
1 #!/bin/bash
2
3 set -eu
4
5 PARTITION_LABEL="multiboot"
6 MULTIBOOT_MNT="${MULTIBOOT_MNT:-/mnt/multiboot}"
7
8 function cmd_format {
9 if [ ! -b "${1:-}" ]; then
10 echo "Usage: $0 format /dev/sdX"
11 exit 1
12 fi
13 set -x
14
15 sudo -k
16 DISK_DEVICE="$1"
17 PARTITION_DEVICE="${DISK_DEVICE}1"
18 echo -ne 'label: dos\ntype=c, bootable\n' | sudo sfdisk "$DISK_DEVICE"
19 sudo mkfs.vfat -n "$PARTITION_LABEL" "$PARTITION_DEVICE"
20 }
21
22 function cmd_grub {
23 DISK_DEVICE="$(findmnt -n -o source "$MULTIBOOT_MNT" | sed 's/[0-9]*$//')"
24 if [ ! -b "$DISK_DEVICE" ]; then
25 echo "ERROR! Could not find disk to install bootloader. Try using mount."
26 exit 1
27 fi
28 set -x
29
30 sudo -k
31 install_grub_bios
32 install_grub_efi
33 install_grub_cfg
34 }
35
36 function cmd_grubcfg {
37 set -x
38 install_grub_cfg
39 }
40
41 function install_grub_bios {
42 sudo grub-install \
43 --target=i386-pc \
44 --boot-directory="$MULTIBOOT_MNT" \
45 "$DISK_DEVICE"
46 }
47
48 function install_grub_efi {
49 for arch in i386-efi x86_64-efi; do
50 sudo grub-install \
51 --target="$arch" \
52 --no-nvram \
53 --removable \
54 --efi-directory="$MULTIBOOT_MNT" \
55 --boot-directory="$MULTIBOOT_MNT" \
56 "$DISK_DEVICE"
57 done
58 }
59
60 function install_grub_cfg {
61 if [[ -w "${MULTIBOOT_MNT}/grub/" ]]; then
62 # We already have write access, no need to use sudo
63 print_grub_cfg > "${MULTIBOOT_MNT}/grub/grub.cfg"
64 else
65 print_grub_cfg | sudo tee "${MULTIBOOT_MNT}/grub/grub.cfg" > /dev/null
66 fi
67 }
68
69 function cmd_mount {
70 set -x
71
72 PARTITION_DEVICE="$(readlink -f "/dev/disk/by-label/${PARTITION_LABEL}")"
73 sudo mkdir -p "$MULTIBOOT_MNT"
74 while sudo umount "$PARTITION_DEVICE" &> /dev/null; do true; done
75 sudo mount "$PARTITION_DEVICE" "$MULTIBOOT_MNT" -o "uid=$(whoami)"
76 }
77
78 function cmd_umount {
79 set -x
80
81 sudo umount "$MULTIBOOT_MNT"
82 sudo rmdir "$MULTIBOOT_MNT"
83 }
84
85 function cmd_freedos {
86 set -x
87
88 local SYSLINUX_VERSION="6.03"
89 local SYSLINUX_URL="https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz"
90 local FREEDOS_URL="http://www.freedos.org/download/download/FD12LITE.zip"
91
92 curl -fL "$SYSLINUX_URL" | \
93 tar xz --no-same-owner --strip-components=3 -C "$MULTIBOOT_MNT" \
94 "syslinux-${SYSLINUX_VERSION}/bios/memdisk/memdisk"
95
96 curl -fL "$FREEDOS_URL" > "${MULTIBOOT_MNT}/FD12LITE.zip"
97 }
98
99 function cmd_memtest {
100 curl -fL "https://www.memtest.org/download/5.01/memtest86+-5.01.bin.gz" | \
101 zcat - > "${MULTIBOOT_MNT}/memtest.bin"
102 }
103
104 function print_grub_cfg {
105 cat <<EOT
106 insmod all_video
107 insmod part_msdos
108 insmod progress
109 insmod regexp
110 search --set=root --label $PARTITION_LABEL
111 set maybe_to_ram=''
112
113 menuentry "Copy ISO image to ram before booting" {
114 # copytoram is used by arch
115 # toram is used by casper based images (tails, Ubuntu, etc)
116 set maybe_to_ram="copytoram toram"
117 }
118
119 function setup_arch {
120 menuentry "\$1" {
121 loopback loop \$1
122 echo "Loading kernel..."
123 linux (loop)/arch/boot/x86_64/vmlinuz-* img_label=${PARTITION_LABEL} img_loop=\$1 archisobasedir=arch earlymodules=loop \$maybe_to_ram
124 echo "Loading initrd (and microcode if they exist)..."
125 initrd (loop)/arch/boot/*.img (loop)/arch/boot/x86_64/initramfs-*.img
126 }
127 }
128 for iso in /archlinux-*.iso /isos/archlinux-*.iso; do
129 if [ -f "\$iso" ]; then
130 setup_arch \$iso
131 fi
132 done
133
134 function setup_debian {
135 menuentry "\$1" {
136 linux \$1/vmlinuz
137 initrd \$1/initrd.gz
138 }
139 }
140 for d in /debian-*-hd-media; do
141 if [ -d "\$d" ]; then
142 setup_debian \$d
143 fi
144 done
145
146 if [ -f /memdisk -a -f /FD12LITE.zip ]; then
147 menuentry /FD12LITE.zip {
148 if [ \${grub_platform} = pc ]; then
149 linux16 /memdisk raw
150 initrd16 /FD12LITE.zip
151 else
152 echo "FreeDOS only works with BIOS boot."
153 sleep 3
154 fi
155 }
156 fi
157
158 if [ -f /memtest.bin ]; then
159 menuentry "/memtest" {
160 linux16 /memtest.bin
161 }
162 fi
163
164 function setup_fedora {
165 menuentry "\$1" {
166 loopback loop \$1
167 probe -s iso_label -l (loop)
168 echo "Loading kernel..."
169 linux (loop)/isolinux/vmlinuz root=live:CDLABEL=\$iso_label rd.live.image quiet iso-scan/filename=\$1
170 echo "Loading initrd..."
171 initrd (loop)/isolinux/initrd.img
172 }
173 }
174 for iso in /Fedora-Workstation-Live-*.iso /isos/Fedora-Workstation-Live-*.iso; do
175 if [ -f "\$iso" ]; then
176 setup_fedora \$iso
177 fi
178 done
179
180 function setup_ubuntu {
181 menuentry "\$1" {
182 loopback loop \$1
183 echo "Loading kernel..."
184 linux (loop)/casper/vmlinuz* boot=casper quiet iso-scan/filename=\$1 \$maybe_to_ram
185 echo "Loading initrd..."
186 initrd (loop)/casper/initrd*
187 }
188 }
189 for iso in /ubuntu-*-desktop-*.iso /isos/ubuntu-*-desktop-*.iso; do
190 if [ -f "\$iso" ]; then
191 setup_ubuntu \$iso
192 fi
193 done
194
195 function setup_tails {
196 menuentry "\$1" {
197 loopback loop \$1
198 echo "Loading kernel..."
199 linux (loop)/live/vmlinuz* initrd=/live/initrd.img boot=live config iso-scan/filename=\$1 findiso=\$1 nopersistence noprompt timezone=Etc/UTC noautologin module=Tails slab_nomerge slub_debug=FZP mce=0 vsyscall=none page_poison=1 init_on_free=1 mds=full,nosmt splash quiet \$maybe_to_ram
200 echo "Loading initrd..."
201 initrd (loop)/live/initrd*
202 }
203 }
204 for iso in /tails-*.iso /isos/tails-*.iso; do
205 if [ -f "\$iso" ]; then
206 setup_tails \$iso
207 fi
208 done
209
210 EOT
211 }
212
213 CMD="cmd_${1:-}"
214 shift || true
215
216 if [ "$(type -t -- "$CMD")" = "function" ]; then
217 "${CMD}" "$@"
218 else
219 echo "Usage: $0 [format|mount|grub|grubcfg|freedos|memtest|umount]"
220 exit 1
221 fi