README.md
Rendering markdown...
#!/usr/bin/env bash
# =============================================================================
# run_qemu.sh — Launch the QEMU v8 OP-TEE environment
#
# Reference: https://optee.readthedocs.io/en/latest/building/devices/qemu.html#qemu-v8
#
# Architecture:
# - Normal World UART: TCP 54320 (Linux console)
# - Secure World UART: TCP 54321 (OP-TEE TEE core log)
# - GDB server: TCP 1234 (optional debugging)
#
# Usage:
# ./run_qemu.sh # Start QEMU (two terminal windows needed for UART)
# ./run_qemu.sh --help # Show help
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OPTEE_DIR="${SCRIPT_DIR}/optee"
BINARIES_DIR="${OPTEE_DIR}/out/bin"
# Colored output helpers
info() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
die() { echo -e "\033[1;31m[FAIL]\033[0m $*" >&2; exit 1; }
# --------------------------------------------------------------------------- #
# Help
# --------------------------------------------------------------------------- #
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
cat <<'EOF'
Usage: ./run_qemu.sh [options]
Options:
--no-gdb Do not attach a GDB server (default: attach -s -S)
--virtfs Enable VirtFS shared directory (host optee/ mounted at /mnt/host)
--help Show this help
Ports:
54320 Normal World UART (Linux console)
54321 Secure World UART (OP-TEE secure log)
1234 GDB server (-S flag: waits for GDB to connect before continuing boot)
Recommended: open three terminals and connect separately:
# Terminal 1 (Normal World):
python3 optee/build/soc_term.py 54320
# Terminal 2 (Secure World):
python3 optee/build/soc_term.py 54321
# Terminal 3 (optional GDB):
aarch64-linux-gnu-gdb -q
(gdb) target remote localhost:1234
(gdb) c
After QEMU starts, type 'c' at the QEMU monitor prompt to continue execution.
EOF
exit 0
fi
# --------------------------------------------------------------------------- #
# Check required files
# --------------------------------------------------------------------------- #
[[ -d "${OPTEE_DIR}" ]] || die "optee/ directory not found. Please run ./setup.sh first"
# Locate QEMU binary (OP-TEE 3.18.0 requires QEMU v7.0.0)
QEMU_BIN="${OPTEE_DIR}/qemu/build/aarch64-softmmu/qemu-system-aarch64"
[[ -x "${QEMU_BIN}" ]] || die "qemu-system-aarch64 not found. Please build QEMU first"
info "Using QEMU: ${QEMU_BIN}"
# Check required binaries
for f in bl1.bin Image rootfs.cpio.gz; do
[[ -f "${BINARIES_DIR}/${f}" ]] || die "Missing ${BINARIES_DIR}/${f}. Please run ./setup.sh first"
done
# --------------------------------------------------------------------------- #
# QEMU arguments
# --------------------------------------------------------------------------- #
GDB_ARGS="-s -S"
VIRTFS_ARGS=""
for arg in "$@"; do
case "$arg" in
--no-gdb) GDB_ARGS="" ;;
--virtfs) VIRTFS_ARGS="-fsdev local,id=fsdev0,path=${OPTEE_DIR},security_model=none \
-device virtio-9p-device,fsdev=fsdev0,mount_tag=host" ;;
esac
done
# --------------------------------------------------------------------------- #
# Launch helper terminals (soc_term.py acts as TCP server; QEMU connects as client)
# --------------------------------------------------------------------------- #
SOC_TERM="${OPTEE_DIR}/build/soc_term.py"
launch_uart() {
local port=$1 title=$2
if command -v gnome-terminal &>/dev/null; then
gnome-terminal --title="$title" -- bash -c \
"python3 ${SOC_TERM} ${port}; read" &
elif command -v xterm &>/dev/null; then
xterm -title "$title" -e \
"bash -c 'python3 ${SOC_TERM} ${port}; read'" &
else
info "Please run in another terminal: python3 ${SOC_TERM} ${port}"
fi
}
wait_for_ports() {
info "Waiting for UART ports to be ready (54320, 54321)..."
while ! nc -z 127.0.0.1 54320 || ! nc -z 127.0.0.1 54321; do
sleep 1
done
info "UART ports ready"
}
info "Starting UART terminals..."
launch_uart 54320 "OP-TEE Normal World (Linux)"
launch_uart 54321 "OP-TEE Secure World (TEE Core)"
wait_for_ports
# --------------------------------------------------------------------------- #
# Start QEMU
# --------------------------------------------------------------------------- #
info "Starting QEMU v8 (AArch64)..."
info "Normal World UART: TCP:54320"
info "Secure World UART: TCP:54321"
[[ -n "${GDB_ARGS}" ]] && info "GDB server: TCP:1234 (waiting for GDB to connect)"
echo ""
info "Type 'c' at the QEMU monitor prompt to continue booting..."
cd "${BINARIES_DIR}"
ln -sf "${OPTEE_DIR}/out-br/images/rootfs.cpio.gz" "${BINARIES_DIR}/rootfs.cpio.gz" 2>/dev/null || true
exec "${QEMU_BIN}" \
-nographic \
-serial tcp:localhost:54320 \
-serial tcp:localhost:54321 \
${GDB_ARGS} \
-smp 2 \
-machine virt,secure=on,mte=off,gic-version=3,virtualization=false \
-cpu max,sve=off \
-d unimp \
-semihosting-config enable=on,target=native \
-m 1057 \
-bios bl1.bin \
-initrd rootfs.cpio.gz \
-kernel Image \
-no-acpi \
-append 'console=ttyAMA0,38400 keep_bootcon root=/dev/vda2' \
${VIRTFS_ARGS}