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[@]}"
|