1#!/bin/bash -xe 2############################################################################### 3# Launch QEMU using the raw commands 4# 5# Can be run by specifying the BASE_DIR and QEMU_ARCH when the script is 6# called. Additionally, this script is automatically called by running the 7# run-robot-qemu-test.sh, it's used to launch the QEMU test container. 8# 9############################################################################### 10# 11# Variables BASE_DIR and QEMU_ARCH are both required but can be optionally 12# input as parameters following the initial script call. Alternatively, they 13# can be input by exporting them or sourcing the script into an environment 14# that has them declared. 15# 16# Parameters: 17# parm1: <optional, QEMU architecture to use > 18# default is ${QEMU_ARCH} - ppc64le-linux or x86_64-linux 19# parm2: <optional, full path to base directory of qemu binary and images > 20# default is ${HOME} 21# 22# Optional Env Variable: 23# 24# QEMU_BIN = Location of qemu-system-arm binary to use when starting 25# QEMU relative to upstream workspace. Default is 26# ./tmp/sysroots/${QEMU_ARCH}/usr/bin/qemu-system-arm 27# which is the default location when doing a bitbake 28# of obmc-phosphor-image 29# 30# MACHINE = Machine to run test against. Options are "witherspoon", 31# "palmetto", "romulus", or undefined (default). Default 32# will use the versatilepb model. 33############################################################################### 34 35set -uo pipefail 36 37QEMU_ARCH=${1:-$QEMU_ARCH} 38# If QEMU_ARCH is empty exit, it is required to continue 39echo "QEMU_ARCH = $QEMU_ARCH" 40if [[ -z $QEMU_ARCH ]]; then 41 echo "Did not pass in required QEMU arch parameter" 42 exit 1 43fi 44 45BASE_DIR=${2:-$HOME} 46# If BASE_DIR doesn't exist exit, it is required to continue 47echo "BASE_DIR = $BASE_DIR" 48if [[ ! -d $BASE_DIR ]]; then 49 echo "No input directory and HOME not set!" 50 exit 1 51fi 52 53# Set the location of the qemu binary relative to BASE_DIR 54QEMU_BIN=${QEMU_BIN:-./tmp/sysroots/${QEMU_ARCH}/usr/bin/qemu-system-arm} 55 56DEFAULT_MACHINE=versatilepb 57MACHINE=${MACHINE:-${DEFAULT_MACHINE}} 58 59# Enter the base directory 60cd "${BASE_DIR}" 61 62# Find the correct drive file, and save its name. OpenBMC has 3 different 63# image formats. The UBI based one, the standard static.mtd one, and the 64# default QEMU basic image (rootfs.ext4). 65DEFAULT_IMAGE_LOC="${DEFAULT_IMAGE_LOC:-./tmp/deploy/images/}" 66if [ -f "${DEFAULT_IMAGE_LOC}/${MACHINE}/obmc-phosphor-image-${MACHINE}".ubi.mtd ]; then 67 DRIVE="obmc-phosphor-image-${MACHINE}.ubi.mtd" 68elif [ -f "${DEFAULT_IMAGE_LOC}/${MACHINE}/obmc-phosphor-image-${MACHINE}".static.mtd ]; then 69 DRIVE="obmc-phosphor-image-${MACHINE}.static.mtd" 70else 71 # shellcheck disable=SC2010 72 DRIVE=$(ls "${DEFAULT_IMAGE_LOC}"/qemuarm | grep rootfs.ext4) 73fi 74 75# Copy the drive file off to /tmp so that QEMU does not write anything back 76# to the drive file and make it unusable for future QEMU runs. 77 78TMP_DRIVE_PATH=$(mktemp "/tmp/${DRIVE}-XXXXX") 79 80# The drive file is stored in different locations depending on if we are 81# using the default or real platforms. 82if [ "${MACHINE}" = "${DEFAULT_MACHINE}" ]; then 83 cp "${DEFAULT_IMAGE_LOC}/qemuarm/${DRIVE}" "${TMP_DRIVE_PATH}" 84else 85 cp "${DEFAULT_IMAGE_LOC}/${MACHINE}/${DRIVE}" "${TMP_DRIVE_PATH}" 86fi 87 88# Obtain IP from /etc/hosts if IP is not valid set to localhost 89IP=$(awk 'END{print $1}' /etc/hosts) 90if [[ "$IP" != *.*.*.* ]]; then 91 IP=127.0.0.1 92fi 93 94# Forward all needed ports for the robot test framework to run 95# Since this is run in docker, the standard ports can be used 96NET_FORWARDING=hostfwd=:${IP}:22-:22,hostfwd=:${IP}:443-:443,hostfwd=tcp:${IP}:80-:80,hostfwd=tcp:${IP}:2200-:2200,hostfwd=udp:${IP}:623-:623,hostfwd=udp:${IP}:664-:664 97 98# Most system only have one NIC so set this as default 99NIC="-net nic,model=ftgmac100,netdev=netdev1 -netdev user,id=netdev1,$NET_FORWARDING" 100if [ "${MACHINE}" = "tacoma" ]; then 101 # Tacoma requires us to specify up to four NICs, with the third one being 102 # the active device. 103 NIC="-net nic,model=ftgmac100,netdev=netdev1 -netdev user,id=netdev1 " 104 NIC+="-net nic,model=ftgmac100,netdev=netdev2 -netdev user,id=netdev2 " 105 NIC+="-net nic,model=ftgmac100,netdev=netdev3 -netdev user,id=netdev3,$NET_FORWARDING " 106 NIC+="-net nic,model=ftgmac100,netdev=netdev4 -netdev user,id=netdev4" 107fi 108 109# The syntax to start old qemu / default version requires different syntax 110# then new qemu with the real platforms 111if [ "${MACHINE}" = "${DEFAULT_MACHINE}" ]; then 112 # Launch default QEMU using the qemu-system-arm 113 ${QEMU_BIN} \ 114 -device virtio-net,netdev=mynet \ 115 -netdev "user,id=mynet,hostfwd=tcp:${IP}:22-:22,hostfwd=tcp:${IP}:443-:443,hostfwd=tcp:${IP}:80-:80,hostfwd=tcp:${IP}:2200-:2200,hostfwd=udp:${IP}:623-:623,hostfwd=udp:${IP}:664-:664" \ 116 -machine versatilepb \ 117 -m 256 \ 118 -drive file="${TMP_DRIVE_PATH}",if=virtio,format=raw \ 119 -show-cursor \ 120 -usb \ 121 -usbdevice tablet \ 122 -device virtio-rng-pci \ 123 -serial mon:vc \ 124 -serial mon:stdio \ 125 -serial null \ 126 -kernel "${DEFAULT_IMAGE_LOC}"/qemuarm/zImage \ 127 -append 'root=/dev/vda rw highres=off console=ttyS0 mem=256M ip=dhcp console=ttyAMA0,115200 console=tty'\ 128 -dtb "${DEFAULT_IMAGE_LOC}"/qemuarm/zImage-versatile-pb.dtb 129else 130 # shellcheck disable=SC2086 # NIC is intentionally word-split. 131 ${QEMU_BIN} \ 132 -machine "${MACHINE}"-bmc \ 133 -nographic \ 134 -drive file="${TMP_DRIVE_PATH}",format=raw,if=mtd \ 135 ${NIC} 136fi 137