| #!/usr/bin/env bash |
| |
| # Copyright 2020 The Android KVM Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| source "$(dirname "${BASH_SOURCE[0]}")/../common.inc" |
| |
| default_var QEMU "${PREBUILTS_QEMU_BIN}" |
| default_var ROM_DIR "${PREBUILTS_QEMU_ROM_DIR}" |
| default_var KERNEL "${LINUX_OUT_IMAGE}" |
| default_var ROOTFS "${PREBUILTS_KUT_ROOTFS}" |
| default_var CPU "max" |
| default_var SMP 2 |
| default_var RAM 512 |
| default_var GIC 3 |
| default_var GDB 0 |
| default_var VERBOSE 0 |
| default_var TIMEOUT "" |
| |
| function usage() { |
| cat <<EOF |
| |
| Usage: $0 [-h] [-v] |
| [-e QEMU] [-L ROM_DIR] [-k KERNEL] [-r ROOTFS] [-R DRIVE] |
| [-c CPU] [-s NUM_CPUS] [-m MEM] [-g GIC] [-G] |
| [-t TIMEOUT] |
| |
| -h output this help text |
| -v print invoked command |
| -e QEMU emulator binary |
| -L directory where QEMU should look for BIOS image |
| -k kernel image |
| -r root filesystem image |
| -R additional drive image(s) to mount as read-only |
| -c CPU model (defaults to "${DEFAULT_CPU}") |
| -s number of CPU cores (defaults to ${DEFAULT_SMP}) |
| -m amount of memory in MB (defaults to ${DEFAULT_RAM}) |
| -g version of GIC (defaults to ${DEFAULT_GIC}) |
| -G enable debugging of emulated system with GDB |
| -t kill QEMU after given number of seconds |
| EOF |
| } |
| |
| CMD=() |
| APPEND=() |
| EXTRA_ARGS=() |
| EXTRA_RO_MOUNTS=() |
| |
| while getopts ":e:L:k:r:R:c:s:m:g:t:vGh" OPT; do |
| case "${OPT}" in |
| e) QEMU="${OPTARG}" ;; |
| L) ROM_DIR="${OPTARG}" ;; |
| k) KERNEL="${OPTARG}" ;; |
| r) ROOTFS="${OPTARG}" ;; |
| R) EXTRA_RO_MOUNTS+=("${OPTARG}") ;; |
| c) CPU="${OPTARG}" ;; |
| s) SMP="${OPTARG}" ;; |
| m) RAM="${OPTARG}" ;; |
| g) GIC="${OPTARG}" ;; |
| t) TIMEOUT="${OPTARG}" ;; |
| v) VERBOSE=1 ;; |
| G) GDB=1 ;; |
| h) |
| usage |
| exit 0 |
| ;; |
| \?) |
| echo "Invalid option: ${!OPTIND}" 1>&2 |
| usage 1>&2 |
| exit 1 |
| ;; |
| :) |
| echo "Invalid option: -${OPTARG} requires an argument" 1>&2 |
| usage 1>&2 |
| exit 1 |
| ;; |
| esac |
| done |
| shift $((OPTIND -1)) |
| if [ $# -ne 0 ]; then |
| echo "Unrecognized options: $@" 1>&2 |
| usage 1>&2 |
| exit 1 |
| fi |
| |
| if [ "${TIMEOUT}" != "" ]; then |
| CMD+=(timeout -k 1s --foreground "${TIMEOUT}") |
| fi |
| CMD+=("${QEMU}") |
| APPEND+=(rootwait root=/dev/vda) |
| |
| # Note: Due to a bug in older versions of Bash, use '${array[@]+"${array[@]}"}' |
| # to expand potentially empty arrays. '${array[@]}' is treated as undefined. |
| for MOUNT in ${EXTRA_RO_MOUNTS[@]+"${EXTRA_RO_MOUNTS[@]}"}; do |
| EXTRA_ARGS+=(-drive "file=${MOUNT},readonly,if=virtio,format=raw") |
| done |
| |
| if [ "${GDB}" -eq 1 ]; then |
| EXTRA_ARGS+=(-S -s) |
| APPEND+=(nokaslr) |
| fi |
| |
| if [ "${VERBOSE}" -eq 1 ]; then |
| set -x |
| fi |
| |
| # Note: Due to a bug in older versions of Bash, use '${array[@]+"${array[@]}"}' |
| # to expand potentially empty arrays. '${array[@]}' is treated as undefined. |
| exec "${CMD[@]}" \ |
| -M virt \ |
| -machine virtualization=true -machine virt,gic-version=${GIC} \ |
| -cpu "${CPU}" -smp "${SMP}" -m "${RAM}" \ |
| -L "${ROM_DIR}" -kernel "${KERNEL}" \ |
| -drive file="${ROOTFS}",readonly,if=virtio,format=raw \ |
| -object rng-random,filename=/dev/urandom,id=rng0 \ |
| -device virtio-rng-pci,rng=rng0 \ |
| -nographic -nodefaults -serial stdio \ |
| -append "${APPEND[*]}" \ |
| ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"} |