Once: start something else on the next start, and only that one

A program that owns the whole machine had nowhere to run. It cannot be
started from the shell, because starting it means there is no shell, and
pointing boot.cfg at it means a machine that keeps starting it - which is a
poor place to find a mistake in something written five minutes ago.

Once writes /System/Boot/once.cfg, in the same format as boot.cfg and read
with the same routines, because a second format for one setting would be a
second format. The loader reads it before boot.cfg and DELETES IT BEFORE IT
JUMPS, which is the only moment there is: after the jump the loader does
not exist.

Consumed by being read rather than by working, so a one shot that hangs
cannot hang twice - the request is gone before the image ran, and the next
start reads boot.cfg like any other.

THE BOOT STATE IS NOT TOUCHED, and the first version got that wrong. It
marked the start the way any other start is marked, and then every
successful bare metal boot reported that it had never arrived - because a
program with the whole machine has no filesystem to clear a mark with and
is doing nothing wrong by not having one. Found by running it: the image
printed its line and the next start still said the last one did not.

Three disks, each a start further along, so none of the tests depends on
another having run.

The loop is closed on the machine now: write it in Edit, assemble it with
Asm, ask for it with Once, restart, watch it own the machine, and the
system comes back without being asked.
This commit is contained in:
Anachronaut
2026-08-27 20:02:42 -04:00
parent 89c667848b
commit 7b28f48f52
10 changed files with 287 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
stage two
CosmOS
>
halted
Execution halted.
[exit 0]
+9
View File
@@ -0,0 +1,9 @@
CosmOS
> next start: /System/Boot/bare.bin, once
finished
> System <dir>
Apps <dir>
0 files, 2 directories
> halted
Execution halted.
[exit 0]
+5
View File
@@ -0,0 +1,5 @@
stage two
just this once: /System/Boot/bare.bin
bare metal: no system, just this
Execution halted.
[exit 0]
+3
View File
@@ -0,0 +1,3 @@
Once /System/Boot/bare.bin
dir /System/Boot
exit
+22
View File
@@ -528,3 +528,25 @@ done
{ printf 'short line\n'; printf 'x%.0s' $(seq 1 200); printf '\nanother short one\n'; } \
> "$WORK/toolong.txt"
"$TOOL" put "$DISKS/editlong.img" "$WORK/toolong.txt" /long.txt >/dev/null
# ---- Starting something else just this once ----
#
# A program that owns the whole machine has nowhere to run: it cannot be started from the
# shell, because starting it means there is no shell, and pointing boot.cfg at it means a
# machine that keeps starting it. Once writes a request the loader reads before boot.cfg
# and deletes before it jumps.
#
# Three disks, each one start further along, so the three tests read as three consecutive
# starts of one machine without any of them depending on another having run.
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
"$ROOT/Programs/CosmOS/Apps/Once.asm" -o "$WORK/Once.sbx" >/dev/null
cp "$DISKS/selfboot.img" "$DISKS/onceasked.img"
"$TOOL" put "$DISKS/onceasked.img" "$WORK/Once.sbx" /Apps/Once.sbx >/dev/null
# The request, written by hand so that the second and third disks do not depend on the
# first test having run to make it.
printf 'system /System/Boot/bare.bin\n' > "$WORK/once.cfg"
cp "$DISKS/onceasked.img" "$DISKS/oncedue.img"
"$TOOL" put "$DISKS/oncedue.img" "$WORK/once.cfg" /System/Boot/once.cfg >/dev/null
# And after it has been taken: the request is gone, and nothing else changed.
cp "$DISKS/onceasked.img" "$DISKS/onceafter.img"
+17
View File
@@ -466,6 +466,23 @@ statusApp | CosmOS/Apps/Status.asm | assemble | -
# been looked at.
cosmosEditLong | CosmOS/Source/cosmos.asm | run | editLong.in | 200000000 | disks/editlong.img
# ---- Starting something else just this once ----
#
# A bare metal program has nowhere to run: starting it from the shell means there is no
# shell, and pointing boot.cfg at it means a machine that keeps starting it. Once writes a
# request the loader reads before boot.cfg and DELETES BEFORE IT JUMPS, so the image runs on
# the next start and on no other, whatever becomes of it.
#
# Three disks, each a start further on, so none of them depends on another having run.
onceAsked | CosmOS/Source/cosmos.asm | run | once.in | 200000000 | disks/onceasked.img
# The start the request was for. It starts an image with no operating system in it at all,
# and THE BOOT STATE IS NOT TOUCHED: a one shot is already self limiting, and marking it
# would report every successful bare metal boot as a start that never arrived.
onceDue | Boot/stage1.asm | rom | - | 200000000 | disks/oncedue.img
# And the start after, which is an ordinary one again.
onceAfter | Boot/stage1.asm | rom | - | 200000000 | disks/onceafter.img
onceApp | CosmOS/Apps/Once.asm | assemble | - | -
# A failed start with NOTHING to fall back to. The mark must not become a reason to refuse
# to start at all - a failure that was passing recovers here, and one that is not leaves
# the machine exactly where it would have been without any of this.