blob: e81e1deaa2ad57eca9a60c744f0d44690c4866c0 [file] [log] [blame]
#!/bin/bash
#
# Copyright (C) 2018 The Android Open Source Project
#
# 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.
#
print_command() {
binary=$1; shift
binary_args=("$@")
printf %s "${binary}"
for i in "${binary_args[@]}"; do
case "$i" in
-*) printf "\\%s %s " $'\n' "$i" ;;
*) printf "%s " "$i" ;;
esac
done
echo
}
exec_run() {
binary=$1; shift
binary_args=("$@")
print_command "${binary}" "${binary_args[@]}"
exec "${binary}" "${binary_args[@]}"
}
run() {
binary=$1; shift
binary_args=("$@")
print_command "${binary}" "${binary_args[@]}"
"${binary}" "${binary_args[@]}"
}
default_instance_number() {
if [[ "${USER::5}" == "vsoc-" ]]; then
echo "${USER: -2}"
else
echo "01"
fi
}
CUTTLEFISH_INSTANCE="${CUTTLEFISH_INSTANCE:-$(default_instance_number)}"
default_instance_name="cvd-${CUTTLEFISH_INSTANCE}"
default_uuid="699acfc4-c8c4-11e7-882b-5065f31dc1${CUTTLEFISH_INSTANCE}"
default_dir="${HOME}/cuttlefish_runtime"
default_mobile_tap_name="cvd-mtap-${CUTTLEFISH_INSTANCE}"
default_wifi_tap_name="cvd-wtap-${CUTTLEFISH_INSTANCE}"
qemu_binary=${qemu_binary=/usr/bin/qemu-system-x86_64}
dtc_binary=${dtc_binary:-dtc}
if [[ -z "${ivshmem_vector_count}" ]]; then
echo "The required ivshmem_vector_count environment variable is not set" >&2
exit 1
fi
if [[ "${qemu_binary##*/}" = "qemu-system-aarch64" ]]; then
# On ARM, the early console can be PCI, and ISA is not supported
kernel_console_serial="pci-serial"
machine="virt,gic_version=2"
cpu=cortex-a53
else
# On x86, the early console must be ISA, not PCI, so we start to get kernel
# messages as soon as possible. ISA devices do not have 'addr' assignments.
kernel_console_serial="isa-serial"
machine="pc-i440fx-2.8,accel=kvm"
cpu=host
fi
# Put anything here that might affect the machine configuration generated by
# QEMU. Anything which connects statefully to another service (like a socket)
# should be added in another section below.
args=(
-name "guest=${instance_name:-${default_instance_name}},debug-threads=on"
-machine "${machine},usb=off,dump-guest-core=off"
-m "${memory_mb:-2048}"
-realtime mlock=off
-smp "${cpus:-2},sockets=${cpus:-2},cores=1,threads=1"
-uuid "${uuid:-${default_uuid}}"
-display none
-no-user-config
-nodefaults
-rtc "base=utc"
-no-shutdown
-boot "strict=on"
-kernel "${kernel_image_path:-${HOME}/kernel}"
-append "${kernel_cmdline:-"loop.max_part=7 console=ttyS0 androidboot.console=ttyS1 androidboot.hardware=vsoc enforcing=0 audit=1 androidboot.selinux=permissive mac80211_hwsim.radios=0 security=selinux buildvariant=userdebug androidboot.serialno=CUTTLEFISHCVD01 androidboot.lcd_density=160 androidboot.boot_devices=pci0000:00/0000:00:03.0"}"
-device "piix3-usb-uhci,id=usb,addr=0x1.0x2"
-device "virtio-serial-pci,id=virtio-serial0"
)
if [[ -n "${composite_disk_path}" ]]; then
args+=(
-drive "file=${composite_disk_path:-${HOME}/composite.img},format=raw,if=none,id=drive-virtio-disk0,aio=threads"
-device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1"
)
else
if [[ -n "${super_image_path}" ]]; then
args+=(
-drive "file=${super_image_path:-${HOME}/obj/PACKAGING/super.img_intermediates/super.img},format=raw,if=none,id=drive-virtio-disk0,aio=threads"
-device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0"
)
else
args+=(
-drive "file=${system_image_path:-${HOME}/system.img},format=raw,if=none,id=drive-virtio-disk0,aio=threads"
-device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1"
)
fi
args+=(
-drive "file=${data_image_path:-${HOME}/userdata.img},format=raw,if=none,id=drive-virtio-disk1,aio=threads"
-device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk1,id=virtio-disk1"
-drive "file=${cache_image_path:-${HOME}/cache.img},format=raw,if=none,id=drive-virtio-disk2,aio=threads"
-device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk2,id=virtio-disk2"
-drive "file=${metadata_image_path:-${HOME}/metadata.img},format=raw,if=none,id=drive-virtio-disk3,aio=threads"
-device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk3,id=virtio-disk3"
)
if [[ -z "${super_image_path}" ]]; then
args+=(
-drive "file=${vendor_image_path:-${HOME}/vendor.img},format=raw,if=none,id=drive-virtio-disk4,aio=threads"
-device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk4,id=virtio-disk4"
-drive "file=${product_image_path:-${HOME}/product.img},format=raw,if=none,id=drive-virtio-disk5,aio=threads"
-device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk5,id=virtio-disk5"
)
fi
fi
args+=(
-netdev "tap,id=hostnet0,ifname=${wifi_tap_name:-${default_wifi_tap_name}},script=no,downscript=no"
-device "virtio-net-pci,netdev=hostnet0,id=net0"
-netdev "tap,id=hostnet1,ifname=${mobile_tap_name:-${default_mobile_tap_name}},script=no,downscript=no"
-device "virtio-net-pci,netdev=hostnet1,id=net1"
-device "virtio-balloon-pci,id=balloon0"
-object "rng-random,id=objrng0,filename=/dev/urandom"
-device "virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=1024,period=2000"
-cpu "${cpu}"
-msg "timestamp=on"
-device "AC97"
)
if [[ -n "${dtb_path}" ]]; then
if [[ "${qemu_binary##*/}" = "qemu-system-aarch64" ]]; then
# Decompile the dt fragment to include in our machine FDT
dtsi_path="${default_dir}/android.dtsi"
dtc_args=(
-I dtb
"${dtb_path}"
-O dts
-o "${dtsi_path}"
)
run "${dtc_binary}" "${dtc_args[@]}"
# Remove duplicate version definition from the dtsi
sed_binary=sed
sed_args=(
-i "/^\/dts-v1\/;$/d"
${dtsi_path}
)
run "${sed_binary}" "${sed_args[@]}"
# Dump the machine FDT blob
dts_path="${default_dir}/cuttlefish.dts"
dtb_path="${default_dir}/cuttlefish.dtb"
dtb_args=(-machine "dumpdtb=${dtb_path}")
run "${qemu_binary}" "${args[@]}" "${dtb_args[@]}"
# Decompile the FDT blob
dtc_args=(
-I dtb
${dtb_path}
-O dts
-o ${dts_path}
)
run "${dtc_binary}" "${dtc_args[@]}"
# Concatenate the dts and dtsi sources
echo "cat ${dtsi_path} >>${dts_path}"
echo
cat ${dtsi_path} >>${dts_path}
# Compile the patched machine FDT
dtc_args=(
-i "${dts_path%/*}"
-I dts
"${dts_path}"
-O dtb
-o "${dtb_path}"
)
run "${dtc_binary}" "${dtc_args[@]}"
fi
args+=(-dtb "${dtb_path}")
fi
# The services providing these sockets don't expect multiple connections,
# so we must not have them in 'args' when we dump the machine FDT. It's
# OK to add them now, after the dumping and patching has completed.
# The (maybe patched) DTB can also be provided now.
args+=(
-chardev "socket,id=charmonitor,path=${monitor_path:-${default_dir}/qemu_monitor.sock},server,nowait"
-mon "chardev=charmonitor,id=monitor,mode=control"
-chardev "file,id=charserial0,path=${kernel_log_pipe_name:-${default_dir}/kernel-log},append=on"
-device "${kernel_console_serial},chardev=charserial0,id=serial0"
-chardev "socket,id=charserial1,path=${console_path:-${default_dir}/console},server,nowait"
-device "pci-serial,chardev=charserial1,id=serial1"
-chardev "socket,path=${ivshmem_qemu_socket_path:-${default_dir}/ivshmem_socket_qemu},id=ivsocket"
-device "ivshmem-doorbell,chardev=ivsocket,vectors=${ivshmem_vector_count}"
)
if [[ "${logcat_mode}" == "serial" ]]; then
args+=(
-chardev "file,id=charchannel0,path=${logcat_path:-${default_dir}/logcat},append=on"
-device "virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=cf-logcat"
)
fi
if [[ -n "${gdb_flag}" ]]; then
args+=(-gdb "${gdb_flag}")
fi
if [[ -n "${ramdisk_image_path}" ]]; then
args+=(-initrd "${ramdisk_image_path}")
fi
if [[ -n "${usb_v1_socket_name}" ]]; then
args+=(
-chardev "socket,id=charchannel1,path=${usb_v1_socket_name:-${default_dir}/usb-v1}"
-device "virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=cf-gadget-usb-v1"
)
fi
if [[ ${vsock_guest_cid:-0} -gt 2 ]]; then
args+=(-device "vhost-vsock-pci,guest-cid=${vsock_guest_cid}")
fi
export QEMU_AUDIO_DRV=none
exec_run "${qemu_binary}" "${args[@]}"