5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / run_qemu.sh SH
#!/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}