run_archiso.sh 4.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env bash
#
# Copyright (C) 2020 David Runge <dvzrv@archlinux.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# A simple script to run an archiso image using qemu. The image can be booted
# using BIOS or UEFI.
#
# Requirements:
# - qemu
# - edk2-ovmf (when UEFI booting)


set -eu

print_help() {
18
19
    local usagetext
    IFS='' read -r -d '' usagetext <<EOF || true
20
21
22
23
Usage:
    run_archiso [options]

Options:
24
    -a              set accessibility support using brltty
25
    -b              set boot type to 'BIOS' (default)
26
    -d              set image type to hard disk instead of optical disc
27
28
    -h              print help
    -i [image]      image to boot into
29
30
    -s              use Secure Boot (only relevant when using UEFI)
    -u              set boot type to 'UEFI'
31
    -v              use VNC display (instead of default SDL)
32
    -c [image]      attach an additional optical disc image (e.g. for cloud-init)
33
34
35
36
37

Example:
    Run an image using UEFI:
    $ run_archiso -u -i archiso-2020.05.23-x86_64.iso
EOF
38
    printf '%s' "${usagetext}"
39
40
41
}

cleanup_working_dir() {
42
43
    if [[ -d "${working_dir}" ]]; then
        rm -rf -- "${working_dir}"
44
45
46
47
    fi
}

copy_ovmf_vars() {
48
49
    if [[ ! -f '/usr/share/edk2-ovmf/x64/OVMF_VARS.fd' ]]; then
        printf 'ERROR: %s\n' "OVMF_VARS.fd not found. Install edk2-ovmf."
50
51
        exit 1
    fi
52
    cp -av -- '/usr/share/edk2-ovmf/x64/OVMF_VARS.fd' "${working_dir}/"
53
54
55
}

check_image() {
56
57
    if [[ -z "$image" ]]; then
        printf 'ERROR: %s\n' "Image name can not be empty."
58
59
        exit 1
    fi
60
61
    if [[ ! -f "$image" ]]; then
        printf 'ERROR: %s\n' "Image file (${image}) does not exist."
62
63
64
65
66
        exit 1
    fi
}

run_image() {
67
68
69
70
71
72
73
74
75
    if [[ "$boot_type" == 'uefi' ]]; then
        copy_ovmf_vars
        if [[ "${secure_boot}" == 'on' ]]; then
            printf '%s\n' 'Using Secure Boot'
            local ovmf_code='/usr/share/edk2-ovmf/x64/OVMF_CODE.secboot.fd'
        else
            local ovmf_code='/usr/share/edk2-ovmf/x64/OVMF_CODE.fd'
        fi
        qemu_options+=(
David Runge's avatar
David Runge committed
76
            '-drive' "if=pflash,format=raw,unit=0,file=${ovmf_code},read-only=on"
77
78
79
80
            '-drive' "if=pflash,format=raw,unit=1,file=${working_dir}/OVMF_VARS.fd"
            '-global' "driver=cfi.pflash01,property=secure,value=${secure_boot}"
        )
    fi
81

82
83
84
85
86
87
88
    if [[ "${accessibility}" == 'on' ]]; then
        qemu_options+=(
            '-chardev' 'braille,id=brltty'
            '-device' 'usb-braille,id=usbbrl,chardev=brltty'
        )
    fi

89
90
91
    if [[ -n "${oddimage}" ]]; then
        qemu_options+=(
            '-device' 'scsi-cd,bus=scsi0.0,drive=cdrom1'
David Runge's avatar
David Runge committed
92
            '-drive' "id=cdrom1,if=none,format=raw,media=cdrom,read-only=on,file=${oddimage}"
93
94
95
        )
    fi

96
97
    qemu-system-x86_64 \
        -boot order=d,menu=on,reboot-timeout=5000 \
98
        -m "size=3072,slots=0,maxmem=$((3072*1024*1024))" \
99
        -k en-us \
100
        -name archiso,process=archiso_0 \
101
102
        -device virtio-scsi-pci,id=scsi0 \
        -device "scsi-${mediatype%rom},bus=scsi0.0,drive=${mediatype}0" \
David Runge's avatar
David Runge committed
103
        -drive "id=${mediatype}0,if=none,format=raw,media=${mediatype/hd/disk},read-only=on,file=${image}" \
104
        -display "${display}" \
105
        -vga virtio \
106
107
108
        -audiodev pa,id=snd0 \
        -device ich9-intel-hda \
        -device hda-output,audiodev=snd0 \
109
        -device virtio-net-pci,romfile=,netdev=net0 -netdev user,id=net0,hostfwd=tcp::60022-:22 \
110
        -machine type=q35,smm=on,accel=kvm,usb=on,pcspk-audiodev=snd0 \
111
112
        -global ICH9-LPC.disable_s3=1 \
        -enable-kvm \
113
        "${qemu_options[@]}" \
114
115
        -serial stdio \
        -no-reboot
116
117
}

118
image=''
119
oddimage=''
120
accessibility=''
121
boot_type='bios'
122
mediatype='cdrom'
123
secure_boot='off'
124
display='sdl'
125
126
qemu_options=()
working_dir="$(mktemp -dt run_archiso.XXXXXXXXXX)"
127
128
trap cleanup_working_dir EXIT

129
if (( ${#@} > 0 )); then
130
    while getopts 'abc:dhi:suv' flag; do
131
        case "$flag" in
132
133
134
            a)
                accessibility='on'
                ;;
135
            b)
136
                boot_type='bios'
137
                ;;
138
139
140
            c)
                oddimage="$OPTARG"
                ;;
141
142
143
            d)
                mediatype='hd'
                ;;
144
145
146
147
148
149
150
151
            h)
                print_help
                exit 0
                ;;
            i)
                image="$OPTARG"
                ;;
            u)
152
                boot_type='uefi'
153
154
                ;;
            s)
155
                secure_boot='on'
156
                ;;
157
158
159
160
            v)
                display='none'
                qemu_options+=(-vnc 'vnc=0.0.0.0:0,vnc=[::]:0')
                ;;
161
            *)
162
                printf '%s\n' "Error: Wrong option. Try 'run_archiso -h'."
163
164
165
166
167
168
169
170
171
172
173
                exit 1
                ;;
        esac
    done
else
    print_help
    exit 1
fi

check_image
run_image