run_parabolaiso.sh 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #!/usr/bin/env bash
  2. #
  3. # Copyright (C) 2020 David Runge <dvzrv@archlinux.org>
  4. #
  5. # SPDX-License-Identifier: GPL-3.0-or-later
  6. #
  7. # A simple script to run a parabolaiso image using qemu. The image can be booted
  8. # using BIOS or UEFI.
  9. #
  10. # Requirements:
  11. # - qemu
  12. # - edk2-ovmf (when UEFI booting)
  13. set -eu
  14. print_help() {
  15. local usagetext
  16. IFS='' read -r -d '' usagetext <<EOF || true
  17. Usage:
  18. run_parabolaiso [options]
  19. Options:
  20. -a set accessibility support using brltty
  21. -b set boot type to 'BIOS' (default)
  22. -d set image type to hard disk instead of optical disc
  23. -h print help
  24. -i [image] image to boot into
  25. -s use Secure Boot (only relevant when using UEFI)
  26. -u set boot type to 'UEFI'
  27. -v use VNC display (instead of default SDL)
  28. -c [image] attach an additional optical disc image (e.g. for cloud-init)
  29. Example:
  30. Run an image using UEFI:
  31. $ run_parabolaiso -u -i parabolaiso-2020.05.23-x86_64.iso
  32. EOF
  33. printf '%s' "${usagetext}"
  34. }
  35. cleanup_working_dir() {
  36. if [[ -d "${working_dir}" ]]; then
  37. rm -rf -- "${working_dir}"
  38. fi
  39. }
  40. copy_ovmf_vars() {
  41. if [[ ! -f '/usr/share/edk2-ovmf/x64/OVMF_VARS.fd' ]]; then
  42. printf 'ERROR: %s\n' "OVMF_VARS.fd not found. Install edk2-ovmf."
  43. exit 1
  44. fi
  45. cp -av -- '/usr/share/edk2-ovmf/x64/OVMF_VARS.fd' "${working_dir}/"
  46. }
  47. check_image() {
  48. if [[ -z "$image" ]]; then
  49. printf 'ERROR: %s\n' "Image name can not be empty."
  50. exit 1
  51. fi
  52. if [[ ! -f "$image" ]]; then
  53. printf 'ERROR: %s\n' "Image file (${image}) does not exist."
  54. exit 1
  55. fi
  56. }
  57. run_image() {
  58. if [[ "$boot_type" == 'uefi' ]]; then
  59. copy_ovmf_vars
  60. if [[ "${secure_boot}" == 'on' ]]; then
  61. printf '%s\n' 'Using Secure Boot'
  62. local ovmf_code='/usr/share/edk2-ovmf/x64/OVMF_CODE.secboot.fd'
  63. else
  64. local ovmf_code='/usr/share/edk2-ovmf/x64/OVMF_CODE.fd'
  65. fi
  66. qemu_options+=(
  67. '-drive' "if=pflash,format=raw,unit=0,file=${ovmf_code},read-only=on"
  68. '-drive' "if=pflash,format=raw,unit=1,file=${working_dir}/OVMF_VARS.fd"
  69. '-global' "driver=cfi.pflash01,property=secure,value=${secure_boot}"
  70. )
  71. fi
  72. if [[ "${accessibility}" == 'on' ]]; then
  73. qemu_options+=(
  74. '-chardev' 'braille,id=brltty'
  75. '-device' 'usb-braille,id=usbbrl,chardev=brltty'
  76. )
  77. fi
  78. if [[ -n "${oddimage}" ]]; then
  79. qemu_options+=(
  80. '-device' 'scsi-cd,bus=scsi0.0,drive=cdrom1'
  81. '-drive' "id=cdrom1,if=none,format=raw,media=cdrom,read-only=on,file=${oddimage}"
  82. )
  83. fi
  84. qemu-system-x86_64 \
  85. -boot order=d,menu=on,reboot-timeout=5000 \
  86. -m "size=3072,slots=0,maxmem=$((3072*1024*1024))" \
  87. -k en-us \
  88. -name parabolaiso,process=parabolaiso_0 \
  89. -device virtio-scsi-pci,id=scsi0 \
  90. -device "scsi-${mediatype%rom},bus=scsi0.0,drive=${mediatype}0" \
  91. -drive "id=${mediatype}0,if=none,format=raw,media=${mediatype/hd/disk},read-only=on,file=${image}" \
  92. -display "${display}" \
  93. -vga virtio \
  94. -audiodev pa,id=snd0 \
  95. -device ich9-intel-hda \
  96. -device hda-output,audiodev=snd0 \
  97. -device virtio-net-pci,romfile=,netdev=net0 -netdev user,id=net0,hostfwd=tcp::60022-:22 \
  98. -machine type=q35,smm=on,accel=kvm,usb=on,pcspk-audiodev=snd0 \
  99. -global ICH9-LPC.disable_s3=1 \
  100. -enable-kvm \
  101. "${qemu_options[@]}" \
  102. -serial stdio \
  103. -no-reboot
  104. }
  105. image=''
  106. oddimage=''
  107. accessibility=''
  108. boot_type='bios'
  109. mediatype='cdrom'
  110. secure_boot='off'
  111. display='sdl'
  112. qemu_options=()
  113. working_dir="$(mktemp -dt run_parabolaiso.XXXXXXXXXX)"
  114. trap cleanup_working_dir EXIT
  115. if (( ${#@} > 0 )); then
  116. while getopts 'abc:dhi:suv' flag; do
  117. case "$flag" in
  118. a)
  119. accessibility='on'
  120. ;;
  121. b)
  122. boot_type='bios'
  123. ;;
  124. c)
  125. oddimage="$OPTARG"
  126. ;;
  127. d)
  128. mediatype='hd'
  129. ;;
  130. h)
  131. print_help
  132. exit 0
  133. ;;
  134. i)
  135. image="$OPTARG"
  136. ;;
  137. u)
  138. boot_type='uefi'
  139. ;;
  140. s)
  141. secure_boot='on'
  142. ;;
  143. v)
  144. display='none'
  145. qemu_options+=(-vnc 'vnc=0.0.0.0:0,vnc=[::]:0')
  146. ;;
  147. *)
  148. printf '%s\n' "Error: Wrong option. Try 'run_parabolaiso -h'."
  149. exit 1
  150. ;;
  151. esac
  152. done
  153. else
  154. print_help
  155. exit 1
  156. fi
  157. check_image
  158. run_image