blob: 1ca0988554951a82b7e28ece9a2b2817ec63ce54 [file] [log] [blame]
#!/bin/bash
# Copyright 2017 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 qemu with a FVM disk
## start fuchsia in qemu with a FVM disk
##
## usage: fx qemu [--no-build] [-z <zbi_image>] [--archive <tgt>]
##
## -z <zbi_image> use <zbi_image> instead of the default.
## --no-build do not attempt to build the fvm and the default zbi images.
## A custom zbi image passed by a '-z' flag is never built.
## --archive <tgt> Don't actually run QEMU. Instead, create a compressed tarball archive
## named "<tgt>.tgz" which contains all of the images needed to run QEMU.
##
## When generating an archive, either two or three files are typically included in the
## archive. They are:
##
## 1) qemu-boot-shim.bin
## This file is the image to be loaded into RAM and jumped to. When using QEMU,
## pass this file to the VM instance using the -kernel option.
## 2) fuchsia-ssh.zbi
## This file is the image to used as the initial ramdisk for the VM. When using QEMU,
## pass this file to the VM instance using the -initrd option.
## 3) fvm_raw.blk
## This file is the initial raw image of the block device for the VM. It is
## not present in a "bringup" build configuration, but should be present for
## "core" builds and beyond. When using QEMU, this file is provided to the
## VM using the --drive option, but needs to be manifested in the machine as
## a device using --device options in order for it to be available for the OS
## to mount. An example of these flags might looks something like this:
##
## -drive file=<path_to_fvm_raw.zbi>,format=raw,if=none,id=mydisk
## -device ich9-ahci,id=ahci
## -device ide-hd,drive=mydisk,bus=ahci.0
##
## This command delegates to //zircon/scripts/run-zircon. Other flags are
## documented in that script, and can be discovered by passing -h or --help.
##
set -e
declare -a CLEANUP_LIST
function cleanup {
for i in "${CLEANUP_LIST[@]}"; do
rm -rf "${i}"
done
}
trap cleanup EXIT
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh || exit $?
fx-config-read
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/fvm.sh || exit $?
build_flag=true
ZBI_IMAGE=
PKG_TARGET=
run_zircon_args=()
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
fx-command-help
"${FUCHSIA_DIR}/zircon/scripts/run-zircon" -h
exit 1
;;
--no-build)
build_flag=false
;;
--archive)
shift
PKG_TARGET="$1.tgz"
;;
-z)
shift
ZBI_IMAGE="$1"
;;
--)
# Stop processing args if we hit a "--" argument.
break
;;
*)
run_zircon_args+=("$1")
esac
shift
done
authkeys_path="$(get-ssh-authkeys)" || {
fx-error "Cannot continue without a valid authorized keys file."
exit 1
}
qemu_dir="${PREBUILT_QEMU_DIR}/bin"
build_targets=()
KERNEL_IMAGE="$(fx-command-run list-build-artifacts --type kernel --name qemu-kernel images)"
build_targets+=( "${KERNEL_IMAGE}" )
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
# Not all builds use an FVM so failing to find a source FVM is OK.
fvm_source="$(fx-fvm-find-raw-source)"
[[ -n "${fvm_source}" ]] && build_targets+=( "${fvm_source}" )
args=(
-a "${FUCHSIA_ARCH}"
-q "${qemu_dir}"
-t "${FUCHSIA_BUILD_DIR}/${KERNEL_IMAGE}"
)
if $build_flag; then
_targets="$(printf ", %s" "${build_targets[@]}")"
echo >&2 "Building ${_targets:2}"
fx-command-run build "${build_targets[@]}"
fi
# Construction of a qcow image prevents qemu 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.
imgdir="$(mktemp -d ${FUCHSIA_BUILD_DIR}/tmp.XXX)"
if [[ ! -d "${imgdir}" ]]; then
echo >&2 "Failed to create temporary directory"
exit 1
fi
CLEANUP_LIST+=("$imgdir")
kernelzbi="${imgdir}/fuchsia-ssh.zbi"
args+=(-z "${kernelzbi}")
fx-zbi -o "${kernelzbi}" \
"${ZBI_IMAGE}" \
--entry "data/ssh/authorized_keys=${authkeys_path}" \
--type=entropy:64 /dev/urandom
fvm_raw=
if [[ -n "${fvm_source}" ]]; then
fvm_tool="$(fx-command-run host-tool --print fvm)"
fvm_raw="${imgdir}/fvm_raw.blk"
fx-fvm-extend-image "${fvm_tool}" "${FUCHSIA_BUILD_DIR}/${fvm_source}" "${fvm_raw}" "${IMAGE_SIZE}"
args+=(-d -D "${fvm_raw}" --diskfmt=raw)
fi
if [[ -z "${PKG_TARGET}" ]]; then
"${FUCHSIA_DIR}/zircon/scripts/run-zircon" "${run_zircon_args[@]}" "${args[@]}" "$@"
else
# Create symlinks to all of the various components in a temp directory, so
# that our tar file is just a archive of individual files with no paths.
SYMLINK_PATH="$(mktemp -d)"
CLEANUP_LIST+=("${SYMLINK_PATH}")
for i in "${kernelzbi}" "${fvm_raw}" "${FUCHSIA_BUILD_DIR}/${KERNEL_IMAGE}"; do
if [[ ! $i ]]; then
continue
fi
name="${i##*/}"
ln -s "${i}" "${SYMLINK_PATH}/${name}"
done
# Now go ahead and create the tarball, working from within the symlink
# directory (again, to avoid pathnames in the tarball)
echo >&2 "Packaging into ${PKG_TARGET}"
cd "${SYMLINK_PATH}" > /dev/null
tar cvzf "${PKG_TARGET}" --dereference *
echo >&2 "done"
fi