| #!/bin/bash |
| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| #### CATEGORY=Run, inspect and debug |
| ### start fuchsia in an emulator |
| |
| ## usage: fx emu [-a <mode>] [-c <text>] [-N [-I <ifname>]] [-u <path>] [-v <build_variant>] [-g <port> [-r <fps>] [-t <cmd>]] [-x <port> [-X <directory>]] [-e <directory>] [-w <size>] [-s <cpus>] [-m <mb>] [-k <authorized_keys_file>] [-K <kernel_image>] [-z <zbi_image>] [-f <fvm_image>] [-p mouse|touch] [-H|--headless] [--audio] [--hidpi-scaling] [--software-gpu] [--debugger] |
| ## -a <mode> acceleration mode (auto, off, kvm, hvf, hax), default is auto |
| ## -c <text> append item to kernel command line |
| ## -ds <size> extends the fvm image size to <size> bytes. Default is twice the original size |
| ## -N run with emulated nic via tun/tap |
| ## -I <ifname> uses the tun/tap interface named ifname |
| ## -u <path> execute emu if-up script, default: linux: no script, macos: tap ifup script. |
| ## -v <build_variant> uses the build system variant to modify the total memory. |
| ## -e <directory> location of emulator, defaults to looking in prebuilt/third_party/android/aemu/release/PLATFORM |
| ## -g <port> enable gRPC service on port to control the emulator, default is 5556 when WebRTC service is enabled |
| ## -r <fps> webrtc frame rate when using gRPC service, default is 30 |
| ## -t <cmd> execute the given command to obtain turn configuration |
| ## -x <port> enable WebRTC HTTP service on port |
| ## -X <directory> location of grpcwebproxy, defaults to looking in prebuilt/third_party/grpcwebproxy |
| ## -w <size> window size, default is 1280x800 |
| ## -s <cpus> number of cpus, 1 for uniprocessor |
| ## -m <mb> total memory, in MB |
| ## -k <authorized_keys_file> SSH authorized keys file, otherwise defaults to ~/.ssh/fuchsia_authorized_keys |
| ## -K <kernel_image> path to image to use as kernel, defaults to kernel generated by the current build. |
| ## -z <zbi_image> path to image to use as ZBI, defaults to zircon-a generated by the current build. |
| ## -Z <zbi tool> path to a version of the `zbi` tool to use; defaults to the one in the current build directory. |
| ## -f <fvm_image> path to full FVM image, defaults to image generated by the current build. |
| ## -F <fvm tool> path to a version of the `fvm` tool to use; defaults to the one in the current build directory. |
| ## -A <arch> architecture of images (x64, arm64), default is the current build. |
| ## -p mouse|touch set pointing device used on emulator: mouse or multitouch screen; defaults to mouse. |
| ## -H|--headless run in headless mode |
| ## --audio run with audio hardware added to the virtual machine |
| ## --hidpi-scaling enable pixel scaling on HiDPI devices |
| ## --host-gpu run with host GPU acceleration |
| ## --software-gpu run without host GPU acceleration |
| ## --debugger pause on launch and wait for a debugger process to attach before resuming |
| ## --no-build do not attempt to build the fvm and zbi tools and the zbi image |
| |
| set -e |
| |
| DEVSHELL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" |
| source "${DEVSHELL_DIR}"/lib/image_build_vars.sh || exit $? |
| source "${DEVSHELL_DIR}"/lib/fvm.sh || exit $? |
| |
| echo |
| fx-info "The Fuchsia emulator is improving and will soon be launched in ffx. Want to be an early adopter?" |
| fx-info "Please use 'ffx emu' and send us feedback!" |
| echo |
| sleep 0.3 |
| |
| # Note these match the defaults in `fx qemu` (//zircon/scripts/run-zircon) and the ram value in |
| # `fx vdl` (//src/developer/ffx/plugins/emulator/src/vdl_files.rs). This can be overriden by the |
| # emulator configs in the infra/recipe repo |
| # (https://fuchsia.googlesource.com/infra/recipes/+/refs/heads/main/recipe_modules/emu/api.py). |
| readonly MEMSIZE_DEFAULT=8192 |
| readonly SMP_DEFAULT=4 |
| |
| ACCEL="auto" |
| BUILD_VARIANT= |
| NET=0 |
| DEBUGGER=0 |
| IFNAME="" |
| AUDIO=0 |
| HEADLESS=0 |
| HIDPI_SCALING=0 |
| AEMU="emulator" |
| AEMU_DIR="" |
| UPSCRIPT= |
| DOWNSCRIPT=no |
| WINDOW_SIZE="1280x800" |
| GRPC= |
| RTCFPS="30" |
| TURNCFG="" |
| GPU="auto" |
| VULKAN=1 |
| HTTP=0 |
| GRPCWEBPROXY_DIR="" |
| CMDLINE="" |
| OPT_CMDLINE="" |
| SMP=$SMP_DEFAULT |
| MEMSIZE=$MEMSIZE_DEFAULT |
| IMAGE_SIZE= |
| EXPERIMENT_ARM64=false |
| ARCH="${FUCHSIA_ARCH}" |
| KERNEL_IMAGE="" |
| FVM_IMAGE="" |
| ZBI_IMAGE="" |
| ZBI_TOOL="" |
| FVM_TOOL="" |
| POINTING_DEVICE="mouse" |
| BUILD=1 |
| EMU_ARGS=() |
| HAS_MEMSIZE=false |
| |
| # Propagate our TERM environment variable as a kernel command line |
| # argument. This is first so that an explicit -c TERM=foo argument |
| # goes into CMDLINE later and overrides this. |
| if [[ -n $TERM ]]; then |
| CMDLINE+="TERM=$TERM " |
| fi |
| |
| while [[ $# -ge 1 ]]; do |
| case "$1" in |
| -h|--help) |
| fx-command-help |
| exit 0 |
| ;; |
| -a) |
| shift |
| ACCEL="$1" |
| ;; |
| -c) |
| shift |
| OPT_CMDLINE+="$1 " |
| ;; |
| -ds) |
| shift |
| IMAGE_SIZE="$1" |
| ;; |
| -N) |
| NET=1 |
| ;; |
| -I) |
| shift |
| IFNAME="$1" |
| ;; |
| -u) |
| shift |
| UPSCRIPT="$1" |
| ;; |
| -v) |
| shift |
| BUILD_VARIANT="$1" |
| ;; |
| -e) |
| shift |
| AEMU_DIR="$1" |
| ;; |
| -x) |
| shift |
| HTTP="$1" |
| ;; |
| -X) |
| shift |
| GRPCWEBPROXY_DIR="$1" |
| ;; |
| -g) |
| shift |
| GRPC="$1" |
| ;; |
| -r) |
| shift |
| RTCFPS="$1" |
| ;; |
| -t) |
| shift |
| TURNCFG="$1" |
| ;; |
| -w) |
| shift |
| WINDOW_SIZE="$1" |
| ;; |
| -s) |
| shift |
| SMP="$1" |
| ;; |
| -m) |
| shift |
| MEMSIZE="$1" |
| HAS_MEMSIZE=true |
| ;; |
| -k) |
| shift |
| AUTHORIZED_KEYS="$1" |
| ;; |
| -K) |
| shift |
| KERNEL_IMAGE="$1" |
| ;; |
| -z) |
| shift |
| ZBI_IMAGE="$1" |
| ;; |
| -Z) |
| shift |
| ZBI_TOOL="$1" |
| ;; |
| -f) |
| shift |
| FVM_IMAGE="$1" |
| ;; |
| -F) |
| shift |
| FVM_TOOL="$1" |
| ;; |
| -A) |
| shift |
| ARCH="$1" |
| ;; |
| -p) |
| shift |
| POINTING_DEVICE="$1" |
| ;; |
| -H|--headless) |
| HEADLESS=1 |
| ;; |
| --audio) |
| AUDIO=1 |
| ;; |
| --debugger) |
| DEBUGGER=1 |
| ;; |
| --hidpi-scaling) |
| HIDPI_SCALING=1 |
| ;; |
| --host-gpu) |
| GPU="host" |
| ;; |
| --software-gpu) |
| GPU="swiftshader_indirect" |
| ;; |
| --no-build) |
| BUILD=0 |
| ;; |
| --experiment-arm64) |
| EXPERIMENT_ARM64=true |
| ;; |
| *) |
| EMU_ARGS+=("$1") |
| ;; |
| esac |
| shift |
| done |
| |
| build_targets=() |
| if [[ -z "${KERNEL_IMAGE}" ]] ; then |
| KERNEL_IMAGE="$(fx-command-run list-build-artifacts --type kernel --name qemu-kernel images)" |
| build_targets+=( "${KERNEL_IMAGE}" ) |
| KERNEL_IMAGE="${FUCHSIA_BUILD_DIR}/${KERNEL_IMAGE}" |
| fi |
| |
| if [[ -z "${ZBI_IMAGE}" ]] ; then |
| ZBI_IMAGE="$(fx-command-run list-build-artifacts --type zbi --name zircon-a images)" |
| build_targets+=( "${ZBI_IMAGE}" ) |
| ZBI_IMAGE="${FUCHSIA_BUILD_DIR}/${ZBI_IMAGE}" |
| fi |
| |
| if [[ -z "${FVM_IMAGE}" ]] ; then |
| # Not all builds use an FVM so failing to find a source FVM is OK. |
| FVM_IMAGE="$(fx-fvm-find-raw-source)" |
| if [[ -n "${FVM_IMAGE}" ]]; then |
| build_targets+=( "${FVM_IMAGE}" ) |
| FVM_IMAGE="${FUCHSIA_BUILD_DIR}/${FVM_IMAGE}" |
| fi |
| fi |
| |
| if (( BUILD )) && [[ ${#build_targets[@]} -gt 0 ]]; then |
| _targets="$(printf ", %s" "${build_targets[@]}")" |
| fx-info "Building ${_targets:2}" |
| fx-command-run build "${build_targets[@]}" |
| fi |
| |
| if [[ -z "${ZBI_TOOL}" ]] ; then |
| (( BUILD )) && build_flag="" || build_flag="--no-build" |
| ZBI_TOOL="$(fx-command-run host-tool ${build_flag} --print zbi)" |
| fi |
| |
| if [[ -z "${FVM_TOOL}" ]] ; then |
| (( BUILD )) && build_flag="" || build_flag="--no-build" |
| FVM_TOOL="$(fx-command-run host-tool ${build_flag} --print fvm)" |
| fi |
| |
| # TODO(fxbug.dev/62631): femu.sh relies on "-a auto", which makes use of |
| # HOST_CPU, which is an fx internal variable. In that case, fall back to |
| # defining it so that things work as expected. |
| if [[ -z "${HOST_CPU}" ]]; then |
| case "$(uname -m)" in |
| x86_64) |
| readonly HOST_CPU="x64" |
| ;; |
| aarch64) |
| readonly HOST_CPU="arm64" |
| ;; |
| *) |
| echo >&2 "Unknown architecture: $(uname -m)." |
| exit 1 |
| ;; |
| esac |
| fi |
| |
| if [[ "$ARCH" != "$HOST_CPU" ]]; then |
| ACCEL=off |
| fi |
| |
| if [[ -z "$AEMU_DIR" && -d "$PREBUILT_AEMU_DIR" ]]; then |
| AEMU_DIR="$PREBUILT_AEMU_DIR" |
| fi |
| |
| if [[ -z "$GRPCWEBPROXY_DIR" && -d "$PREBUILT_GRPCWEBPROXY_DIR" ]]; then |
| GRPCWEBPROXY_DIR="$PREBUILT_GRPCWEBPROXY_DIR" |
| fi |
| |
| if [[ -z "$AUTHORIZED_KEYS" ]]; then |
| AUTHORIZED_KEYS="$(get-ssh-authkeys)" |
| fi |
| |
| # if memory size is not specified, assign memory size based on build_variant. |
| if [[ ! ("$HAS_MEMSIZE" && -z "$BUILD_VARIANT") ]]; then |
| variants=("asan" "asan-ubsan" "coverage" "coverage-rust" "profile") |
| if [[ ! ${variants[*]} =~ "$BUILD_VARIANT " ]]; then |
| MEMSIZE=4096 |
| fi |
| fi |
| |
| # construct the args for aemu |
| ARGS=() |
| ARGS+=("-m" "$MEMSIZE") |
| ARGS+=("-serial" "stdio") |
| ARGS+=("-vga" "none") |
| ARGS+=("-device" "virtio-keyboard-pci") |
| |
| if [[ $SMP != 1 ]]; then |
| ARGS+=("-smp" "${SMP}") |
| fi |
| |
| # TODO(raggi): do we want to use hda on arm64? |
| if (( AUDIO )); then |
| ARGS+=("-soundhw" "hda") |
| fi |
| |
| FEATURES="VirtioInput,GLDirectMem,HostComposition" |
| |
| if [[ "$POINTING_DEVICE" == "mouse" ]]; then |
| ARGS+=("-device" "virtio-mouse-pci") |
| FEATURES+=",VirtioMouse" |
| elif [[ "$POINTING_DEVICE" == "touch" ]]; then |
| ARGS+=("-device" "virtio_input_multi_touch_pci_1") |
| else |
| fx-error "Unsupported pointing device: $POINTING_DEVICE" |
| exit 1 |
| fi |
| |
| if [[ "$ACCEL" == "auto" ]]; then |
| if [[ "$(uname -s)" == "Darwin" ]]; then |
| ACCEL="hvf" |
| else |
| ACCEL="kvm" |
| fi |
| fi |
| |
| case "$ARCH" in |
| x64) |
| ARGS+=("-machine" "q35") |
| ARGS+=("-device" "isa-debug-exit,iobase=0xf4,iosize=0x04") |
| |
| # Override the SeaBIOS serial port to keep it from outputting |
| # a terminal reset on start. |
| ARGS+=("-fw_cfg" "name=etc/sercon-port,string=0") |
| ;; |
| arm64) |
| ARGS+=("-machine" "virt") |
| ;; |
| *) |
| fx-error "Unsupported architecture: $(uname -m)" |
| exit 1 |
| esac |
| |
| if [[ "$ACCEL" == "kvm" ]]; then |
| if [[ ! -w "/dev/kvm" ]]; then |
| echo "Error: No write permission on /dev/kvm." |
| echo "To use KVM acceleration, adjust permissions to /dev/kvm using:" |
| echo |
| echo "sudo usermod -a -G kvm $USER" |
| echo |
| echo "Exit the current ssh session. From the remote host:" |
| echo |
| echo "exit" |
| echo |
| echo "On the local host:" |
| echo |
| echo "ssh <remote_host_name> -O exit" |
| echo |
| echo "Log back in to remote host and run the emulator again." |
| exit 1 |
| fi |
| # TODO(fxbug.dev/33174): Work around KVM bug on AMD Zen machines where SMAP |
| # and CPL=3 MMIO accesses trigger a loop in the Linux kernel. |
| # TODO(fxbug.dev/63110): Work around KVM bug on AMD Zen machines where XSAVES |
| # is enumerated but the IA32_XSS MSR is not available. The bug fix is in |
| # 864e2ab2b46db1ac266c46a7c in upstream Linux but has not percolated to |
| # popular distributions yet. |
| if [[ "$(lsmod | grep kvm_amd)" != "" ]]; then |
| # Add topoext to properly report hyperthreading on AMD CPUs |
| ARGS+=("-enable-kvm" "-cpu" "host,migratable=no,+invtsc,-smap,-xsaves,+topoext") |
| else |
| ARGS+=("-enable-kvm" "-cpu" "host,migratable=no,+invtsc") |
| fi |
| FEATURES+=",KVM" |
| elif [[ "$ACCEL" == "hvf" ]]; then |
| ARGS+=("-enable-hvf" "-cpu" "Haswell") |
| FEATURES+=",HVF" |
| elif [[ "$ACCEL" == "hax" ]]; then |
| ARGS+=("-enable-hax" "-cpu" "Haswell") |
| FEATURES+=",HAXM" |
| elif [[ "$ACCEL" == "off" ]]; then |
| case "$ARCH" in |
| x64) |
| ARGS+=("-cpu" "Haswell,+smap,-check,-fsgsbase") |
| ;; |
| arm64) |
| ARGS+=("-cpu" "cortex-a53") |
| ;; |
| esac |
| else |
| fx-error Unsupported acceleration mode |
| exit 1 |
| fi |
| |
| if (( VULKAN )); then |
| FEATURES+=",Vulkan" |
| else |
| FEATURES+=",-Vulkan" |
| fi |
| |
| OPTIONS=() |
| OPTIONS+=("-feature" "$FEATURES") |
| OPTIONS+=("-window-size" "$WINDOW_SIZE") |
| OPTIONS+=("-gpu" "$GPU") |
| OPTIONS+=("-no-location-ui") |
| if (( DEBUGGER )); then |
| OPTIONS+=("-wait-for-debugger") |
| fi |
| |
| if (( HEADLESS )); then |
| OPTIONS+=("-no-window") |
| fi |
| |
| if (( ! HIDPI_SCALING )); then |
| OPTIONS+=("-no-hidpi-scaling") |
| fi |
| |
| if [[ "$ARCH" == "arm64" ]]; then |
| if ! "$EXPERIMENT_ARM64"; then |
| fx-error "arm64 support is still experimental, requires --experiment-arm64" |
| exit 1 |
| fi |
| OPTIONS+=("-avd-arch" "arm64") |
| fi |
| |
| # use port 5556 by default |
| if (( HTTP )); then |
| GRPC="${GRPC:-5556}" |
| fi |
| |
| if (( GRPC )); then |
| if [[ "$(uname -s)" == "Darwin" ]]; then |
| echo "WebRTC feature is not supported on macOS" |
| exit 1 |
| fi |
| OPTIONS+=("-grpc" "$GRPC") |
| OPTIONS+=("-rtcfps" "$RTCFPS") |
| if [[ -n "$TURNCFG" ]]; then |
| OPTIONS+=("-turncfg" "$TURNCFG") |
| fi |
| fi |
| |
| if (( NET )); then |
| if [[ "$(uname -s)" == "Darwin" ]]; then |
| if [[ -z "$IFNAME" ]]; then |
| IFNAME="tap0" |
| fi |
| if [[ "$IFNAME" != "fakenetwork" && ! -c "/dev/$IFNAME" ]]; then |
| echo "To use emu with networking on macOS, install the tun/tap driver:" |
| echo "http://tuntaposx.sourceforge.net/download.xhtml" |
| exit 1 |
| fi |
| if [[ "$IFNAME" != "fakenetwork" && ! -w "/dev/$IFNAME" ]]; then |
| echo "For networking /dev/$IFNAME must be owned by $USER. Please run:" |
| echo " sudo chown $USER /dev/$IFNAME" |
| exit 1 |
| fi |
| if [[ -z "${UPSCRIPT}" ]]; then |
| echo "sudo follows to configure the tap interface:" |
| UPSCRIPT="${DEVSHELL_DIR}"/lib/emu-ifup-macos.sh |
| fi |
| else |
| if [[ -z "$IFNAME" ]]; then |
| IFNAME="qemu" |
| fi |
| TAP_IFS=$(ip tuntap show 2>/dev/null) |
| if [[ "$IFNAME" != "fakenetwork" && ! "$TAP_IFS" =~ ${IFNAME}: ]]; then |
| echo "To use emu with networking on Linux, configure tun/tap:" |
| echo |
| echo "sudo ip tuntap add dev $IFNAME mode tap user $USER && \\" |
| echo "sudo ip link set $IFNAME up" |
| exit 1 |
| fi |
| # Try to detect if a firewall is active. There are only few ways to do that |
| # without being root. Unfortunately, using systemd or systemctl does not work |
| # (at least on Debian), so use the following hack instead: |
| if (command -v ufw && grep -q "^ENABLED=yes" /etc/ufw/ufw.conf) >/dev/null 2>&1; then |
| fx-warn "Active firewall detected: If this emulator is unreachable, run: fx setup-ufw" |
| fi |
| if [[ -z "${UPSCRIPT}" ]]; then |
| UPSCRIPT=no |
| fi |
| fi |
| if [[ -n "${UPSCRIPT}" && "${UPSCRIPT}" != "no" && ! -x "${UPSCRIPT}" ]]; then |
| echo "The upscript ${UPSCRIPT} is not a valid executable" |
| exit 1 |
| fi |
| if [[ -n "${DOWNSCRIPT}" && "${DOWNSCRIPT}" != "no" && ! -x "${DOWNSCRIPT}" ]]; then |
| echo "The downscript ${DOWNSCRIPT} is not a valid executable" |
| exit 1 |
| fi |
| ARGS+=("-netdev" "type=tap,ifname=$IFNAME,id=net0${UPSCRIPT:+,script=${UPSCRIPT}}${DOWNSCRIPT:+,downscript=${DOWNSCRIPT}}") |
| HASH=$(echo $IFNAME | shasum) |
| SUFFIX=$(for i in {0..2}; do echo -n ":${HASH:$(( 2 * i )):2}"; done) |
| MAC=",mac=52:54:00$SUFFIX" |
| ARGS+=("-device" "virtio-net-pci,vectors=8,netdev=net0${MAC}") |
| else |
| ARGS+=("-net" "none") |
| fi |
| |
| # Check for X11 on Linux |
| if [[ "$(uname -s)" == "Linux" ]] && (( ! HEADLESS )); then |
| if [[ -z "$DISPLAY" ]]; then |
| echo "To use emulator on Linux, start X, or use a virtual framebuffer:" |
| echo |
| echo "xvfb-run fx emu" |
| exit 1 |
| else |
| if [[ "$DISPLAY" != "fakedisplay" ]] && ! xset q >/dev/null 2>&1; then |
| echo "clients must be allowed to connect to DISPLAY. Please run:" |
| echo |
| echo "DISPLAY=$DISPLAY XAUTHORITY=/run/user/`getent passwd | grep /var/lib/gdm | cut -d: -f3`/gdm/Xauthority sudo xhost +" |
| echo |
| echo "or if using lightdm:" |
| echo |
| echo "DISPLAY=$DISPLAY XAUTHORITY=/var/run/lightdm/root/$DISPLAY sudo xhost +" |
| exit 1 |
| fi |
| fi |
| fi |
| |
| # Construction of a qcow image prevents aemu from writing back to the |
| # build-produced image file, which could cause timestamp issues with that file. |
| # Construction of the new ZBI adds ~/.ssh/fuchsia_authorized_keys for SSH access. |
| img_dir="$(mktemp -d)" |
| if [[ ! -d "${img_dir}" ]]; then |
| fx-error "Failed to create temporary directory" |
| exit 1 |
| fi |
| |
| # Restore the terminal only if the standard input (fd 0) is associated with a |
| # terminal device. We check this using test operator "-t". |
| trap 'rm -Rf "${img_dir}"; [[ "${GRPCWEBPROXY_PID}" ]] && kill "${GRPCWEBPROXY_PID}"; [[ -t 0 ]] && stty sane' EXIT |
| |
| KERNEL_ZBI="${img_dir}/fuchsia-ssh.zbi" |
| "${ZBI_TOOL}" -o "${KERNEL_ZBI}" "${ZBI_IMAGE}" \ |
| --entry "data/ssh/authorized_keys=${AUTHORIZED_KEYS}" \ |
| --type=entropy:64 /dev/urandom |
| |
| if [[ -n "${FVM_IMAGE}" ]]; then |
| fvm_raw="${img_dir}/fvm_raw.blk" |
| fx-fvm-extend-image "${FVM_TOOL}" "${FVM_IMAGE}" "${fvm_raw}" "${IMAGE_SIZE}" |
| ARGS+=("-drive" "file=${fvm_raw},format=raw,if=none,id=vdisk") |
| ARGS+=("-device" "virtio-blk-pci,drive=vdisk") |
| fi |
| |
| # Start gRPC web proxy if HTTP port is set |
| if (( HTTP )); then |
| "${GRPCWEBPROXY_DIR}/grpcwebproxy" \ |
| --backend_addr localhost:"$GRPC" --server_http_debug_port "$HTTP" \ |
| --backend_tls=false --run_tls_server=false --allow_all_origins & |
| GRPCWEBPROXY_PID=$! |
| fi |
| |
| # construct the kernel cmd line for aemu |
| CMDLINE+="kernel.serial=legacy " |
| |
| # Add entropy to the kernel |
| CMDLINE+="kernel.entropy-mixin=$(head -c 32 /dev/urandom | shasum -a 256 | awk '{ print $1 }') " |
| |
| # Don't 'reboot' the emulator if the kernel crashes |
| CMDLINE+="kernel.halt-on-panic=true " |
| |
| # TODO(fxbug.dev/74233): FEMU using HVF accelerator may encounter a race |
| # condition between VCPU threads which could cause emulator to crash if page |
| # table eviction is enabled; As a workaround, we disable page table eviction if |
| # we are using HVF. |
| if [[ "$ACCEL" == "hvf" ]]; then |
| CMDLINE+="kernel.page-scanner.page-table-eviction-policy=never " |
| fi |
| |
| # Finally, append any values received via option. We save them for last so that |
| # they can override others since "last value wins". |
| CMDLINE+=$OPT_CMDLINE |
| |
| # run aemu |
| set -x |
| "${AEMU_DIR}/${AEMU}" "${OPTIONS[@]}" -fuchsia \ |
| -kernel "${KERNEL_IMAGE}" \ |
| -initrd "$KERNEL_ZBI" "${ARGS[@]}" -append "$CMDLINE" "${EMU_ARGS[@]}" |