]> code.delx.au - monosys/blob - multiboot-setup
multiboot: commands do better checking of state and arguments
[monosys] / multiboot-setup
1 #!/bin/bash
2
3 set -eu
4
5 ISO_MNT="/mnt/iso"
6 PARTITION_LABEL="multiboot"
7 MULTIBOOT_MNT="/mnt/multiboot"
8 GRUB_CFG="${MULTIBOOT_MNT}/grub/grub.cfg"
9 SYSLINUX_VERSION="6.03"
10 SYSLINUX_URL="https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-${SYSLINUX_VERSION}.tar.gz"
11
12 function cmd_format {
13 if [ ! -b "${1:-}" ]; then
14 echo "Usage: $0 format /dev/sdX"
15 exit 1
16 fi
17 set -x
18
19 sudo -k
20 DISK_DEVICE="$1"
21 PARTITION_DEVICE="${DISK_DEVICE}1"
22 echo -ne 'label: dos\ntype=c, bootable\n' | sudo sfdisk "$DISK_DEVICE"
23 sudo mkfs.vfat -n "$PARTITION_LABEL" "$PARTITION_DEVICE"
24 }
25
26 function cmd_bootloader {
27 DISK_DEVICE="$(mount|grep /mnt/multiboot|cut -d' ' -f1|sed 's/[0-9]*$//')"
28 if [ ! -b "$DISK_DEVICE" ]; then
29 echo "ERROR! Could not find disk to install bootloader. Try using mount."
30 exit 1
31 fi
32 set -x
33
34 sudo -k
35 install_grub_bios
36 install_grub_efi
37 install_grub_cfg
38 }
39
40 function install_grub_bios {
41 sudo grub-install \
42 --target=i386-pc \
43 --boot-directory="$MULTIBOOT_MNT" \
44 "$DISK_DEVICE"
45 }
46
47 function install_grub_efi {
48 sudo grub-install \
49 --target=x86_64-efi \
50 --no-nvram \
51 --removable \
52 --efi-directory="$MULTIBOOT_MNT" \
53 --boot-directory="$MULTIBOOT_MNT" \
54 "$DISK_DEVICE"
55 }
56
57 function install_grub_cfg {
58 mkdir -p "$(dirname "$GRUB_CFG")"
59 cat <<EOT >> "$GRUB_CFG"
60 insmod all_video
61 insmod part_msdos
62 insmod progress
63 search --set=root --label $PARTITION_LABEL
64
65 EOT
66 }
67
68 function cmd_mount {
69 set -x
70
71 PARTITION_DEVICE="$(readlink -f /dev/disk/by-label/multiboot)"
72 sudo mkdir -p "$MULTIBOOT_MNT"
73 while sudo umount "$PARTITION_DEVICE" &> /dev/null; do true; done
74 sudo mount "$PARTITION_DEVICE" "$MULTIBOOT_MNT" -o "uid=$(whoami)"
75 }
76
77 function cmd_umount {
78 set -x
79
80 sudo umount "$MULTIBOOT_MNT"
81 sudo rmdir "$MULTIBOOT_MNT"
82 }
83
84 function cmd_add_iso {
85 if [ ! -f "${1:-}" ]; then
86 echo "Usage: $0 add_iso /path/to/ubuntu.iso"
87 exit 1
88 fi
89 set -x
90
91 ISO_FILENAME="$1"
92 ISO_BASENAME="$(basename "$ISO_FILENAME")"
93 local f="$(basename "$ISO_FILENAME")"
94
95 if [[ "$ISO_BASENAME" == ubuntu-*-desktop-*.iso ]]; then
96 setup_ubuntu
97 elif [[ "$ISO_BASENAME" == debian-live-*.iso ]]; then
98 setup_debian
99 elif [[ "$ISO_BASENAME" == Fedora-Workstation-Live-*.iso ]]; then
100 setup_fedora
101 elif [[ "$ISO_BASENAME" == archlinux-*.iso ]]; then
102 setup_archlinux
103 elif [[ "$ISO_BASENAME" == FD12*.zip ]]; then
104 setup_freedos
105 else
106 echo "Unsupported ISO! $ISO_BASENAME"
107 fi
108 }
109
110 function setup_ubuntu {
111 copy_iso_data
112
113 cat <<EOT >> "$GRUB_CFG"
114 menuentry '$ISO_BASENAME' {
115 loopback loop /$ISO_BASENAME
116 linux (loop)/casper/vmlinuz.efi boot=casper quiet iso-scan/filename=/$ISO_BASENAME
117 initrd (loop)/casper/initrd.lz
118 }
119
120 EOT
121 }
122
123 function setup_debian {
124 copy_iso_data
125
126 cat <<EOT >> "$GRUB_CFG"
127 menuentry '$ISO_BASENAME' {
128 loopback loop /$ISO_BASENAME
129 linux (loop)/live/vmlinuz boot=live components findiso=/$ISO_BASENAME
130 initrd (loop)/live/initrd.img
131 }
132
133 EOT
134 }
135
136 function setup_fedora {
137 copy_iso_data
138
139 cat <<EOT >> "$GRUB_CFG"
140 menuentry '$ISO_BASENAME' {
141 loopback loop /$ISO_BASENAME
142 linux (loop)/isolinux/vmlinuz root=live:CDLABEL=$(blkid -s LABEL -o value "$ISO_FILENAME") rd.live.image quiet iso-scan/filename=/$ISO_BASENAME
143 initrd (loop)/isolinux/initrd.img
144 }
145
146 EOT
147 }
148
149 function setup_archlinux {
150 copy_iso_data
151
152 cat <<EOT >> "$GRUB_CFG"
153 menuentry '$ISO_BASENAME' {
154 loopback loop /$ISO_BASENAME
155 linux (loop)/arch/boot/x86_64/vmlinuz img_label=${PARTITION_LABEL} img_loop=$ISO_BASENAME archisobasedir=arch earlymodules=loop
156 initrd (loop)/arch/boot/x86_64/archiso.img
157 }
158
159 EOT
160 }
161
162 function setup_freedos {
163 install_memdisk
164 copy_iso_data
165
166 cat <<EOT >> "$GRUB_CFG"
167 menuentry '$ISO_BASENAME' {
168 if [ \${grub_platform} = pc ]; then
169 linux16 /memdisk raw
170 initrd16 /$ISO_BASENAME
171 else
172 echo "FreeDOS only works with BIOS boot."
173 sleep 3
174 fi
175 }
176
177 EOT
178 }
179
180 function copy_iso_data {
181 rsync --size-only --progress "$ISO_FILENAME" "${MULTIBOOT_MNT}/"
182 }
183
184 function install_memdisk {
185 local dest="${MULTIBOOT_MNT}/memdisk"
186
187 if [ -f "$dest" ]; then
188 return
189 fi
190
191 for maybe in /usr/lib/syslinux/bios/memdisk /usr/lib/syslinux/memdisk; do
192 if [ -f "$maybe" ]; then
193 cp "$maybe" "$dest"
194 return
195 fi
196 done
197
198 curl --fail "$SYSLINUX_URL" | \
199 tar xz --strip-components=3 -C "$MULTIBOOT_MNT" \
200 "syslinux-${SYSLINUX_VERSION}/bios/memdisk/memdisk"
201 }
202
203 CMD="cmd_${1:-}"
204 shift || true
205
206 if [ "$(type -t -- "$CMD")" = "function" ]; then
207 "${CMD}" "$@"
208 else
209 echo "Usage: $0 [format|mount|bootloader|add_iso|umount]"
210 exit 1
211 fi