|  | #!/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" "${args[@]}" "${run_zircon_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 |