summaryrefslogtreecommitdiffstats
path: root/scripts/run.sh
blob: 4b6f48186efc2630ef732356606d624dc55c1e1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env bash
#
# scripts/run.sh — build, stage and boot the system image in QEMU.
#
# Usage:
#   ./scripts/run.sh                 build + stage + boot (window + serial)
#   ./scripts/run.sh --headless      serial console only, no window
#   ./scripts/run.sh --debug         GDB stub on :1234, CPU starts paused
#                                    (attach: gdb -x scripts/debug-kernel.py)
#   ./scripts/run.sh --monitor       HMP monitor socket for sendkeys.py /
#                                    test-focus.py (default path below)
#   ./scripts/run.sh --fresh         re-create the system image first
#                                    (wipes runtime data on the image)
#   ./scripts/run.sh --mem 512M      guest memory (default 256M)
#   ./scripts/run.sh --smp 2         guest CPUs (default 1)
#   ./scripts/run.sh --bios FILE     OVMF firmware (default: system path)
#   ./scripts/run.sh --image FILE    system image (default: /tmp/system.img)
#   ./scripts/run.sh --grab          confine the pointer: GTK runs as an X11
#                                    (XWayland) client and grabs on hover
#   ./scripts/run.sh --no-grab       Wayland-native window, no pointer grab
#
# Mouse:  Wayland forbids global pointer grabs, so a Wayland-native window
#         cannot confine the cursor (QEMU's grab silently does nothing).
#         In a Wayland session with XWayland, run.sh defaults to --grab;
#         Ctrl+Alt+G toggles the grab in either mode.
#
# Environment (same names the other scripts honour): TARGET, PROFILE,
# SYSTEM_IMG, OVMF, QEMU, MEM, SMP.
#
# Two-command flow:      ./scripts/build.sh && ./scripts/run.sh
# One-command flow:      ./scripts/run.sh        (builds what is missing)
#
# Monitor socket:        /tmp/rsdos-monitor.sock
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

usage() {
	awk 'NR > 1 && /^#/ { sub(/^# ?/, ""); print; next } NR > 1 { exit }' "$0"
}

HEADLESS=0
DEBUG=0
FRESH=0
MON=0
MON_SOCK="/tmp/rsdos-monitor.sock"
GRAB="" # "" = auto: grab when a Wayland session has XWayland

while [ $# -gt 0 ]; do
	case "$1" in
	--headless | -H) HEADLESS=1 ;;
	# GDB stub + keep whatever profile the env asked for (release is the
	# default; PROFILE=debug ./scripts/run.sh --debug adds line symbols).
	--debug | -d) DEBUG=1 ;;
	--fresh) FRESH=1 ;;
	--monitor) MON=1 ;;
	--mem) shift; MEM="$1" ;;
	--smp) shift; SMP="$1" ;;
	--bios) shift; OVMF="$1" ;;
	--image | -i) shift; SYSTEM_IMG="$1" ;;
	--grab) GRAB=1 ;;
	--no-grab) GRAB=0 ;;
	--help | -h)
		usage
		exit 0
		;;
	*)
		echo "run.sh: unknown argument: $1" >&2
		usage >&2
		exit 1
		;;
	esac
	shift
done

# shellcheck source=lib.sh
source "$SCRIPT_DIR/lib.sh" # reads MEM/SMP/OVMF/SYSTEM_IMG from the env

# build.sh is a separate process: it re-derives OUT_DIR/KERNEL from these,
# so whatever we resolved above (including a --mem/--bios override) wins
# there too.
export TARGET PROFILE QEMU MEM SMP OVMF SYSTEM_IMG

# ---- mouse grab (Wayland) --------------------------------------------------
# Wayland forbids global pointer grabs, so a Wayland-native GTK window cannot
# confine the cursor — QEMU's grab silently does nothing there.  XWayland can,
# so a Wayland session that has XWayland (DISPLAY set) defaults to GTK-on-X11
# plus grab-on-hover.  Ctrl+Alt+G toggles the grab; --no-grab keeps the
# Wayland-native window.
if [ -z "$GRAB" ]; then
	if [ "${XDG_SESSION_TYPE:-}" = "wayland" ] && [ -n "${DISPLAY:-}" ]; then
		GRAB=1
	else
		GRAB=0
	fi
fi
[ "$HEADLESS" -eq 1 ] && GRAB=0 # no window, nothing to grab
if [ "$GRAB" -eq 1 ]; then
	if [ -n "${DISPLAY:-}" ]; then
		export GDK_BACKEND=x11
	else
		echo "run.sh: --grab needs XWayland (DISPLAY is unset); not grabbing" >&2
		GRAB=0
	fi
fi

# ---- build + stage --------------------------------------------------------
"$SCRIPT_DIR/build.sh"
if [ "$FRESH" -eq 1 ]; then
	stage_image --force
else
	stage_image
fi

# ---- boot -----------------------------------------------------------------
mapfile -t QARGS < <(qemu_args)
if [ "$HEADLESS" -eq 1 ]; then
	QARGS+=(-display none)
else
	QARGS+=(-vga std)
	if [ "$GRAB" -eq 1 ]; then
		QARGS+=(-display gtk,grab-on-hover=on)
	fi
fi
[ "$MON" -eq 1 ] && QARGS+=(-monitor "unix:$MON_SOCK,server,nowait")
[ "$DEBUG" -eq 1 ] && QARGS+=(-s -S)
QARGS+=(-serial stdio)

echo ""
echo "=== boot ==="
echo "  image:  $SYSTEM_IMG"
echo "  ovmf:   $OVMF"
echo "  mem:    $MEM   smp: $SMP"
echo "  mode:   $([ "$HEADLESS" -eq 1 ] && echo headless || echo window)   gdb: $([ "$DEBUG" -eq 1 ] && echo ':1234 (paused)' || echo off)"
if [ "$HEADLESS" -eq 0 ]; then
	echo "  mouse:  $([ "$GRAB" -eq 1 ] && echo 'grab on hover (XWayland; Ctrl+Alt+G toggles)' || echo 'not grabbed (Wayland cannot confine the pointer)')"
fi
[ "$MON" -eq 1 ] && echo "  monitor: unix:$MON_SOCK"
echo ""

exec "$QEMU" "${QARGS[@]}"