Configuration files, and boot.cfg as the first of them

One setting to a line: a key, a space, the rest of the line is the value.
A semicolon starts a comment. The format was noticed rather than designed -
textSplit already cuts the first word off a line and leaves the rest, and
textSame already insists two strings end together, so reading a setting is
those two routines and a loop. It is also what the shell reads, which makes
a configuration line a command line the machine reads instead of a person
typing one.

The format was chosen by asking what the BOOT LOADER could manage, because
it is the worst case in every direction: a few kilobytes, no operating
system to report to, and if it fails the machine does not start. Two
formats would be worse than one and the loader cannot have the richer one.

CONFIGURATION IS ADVICE. A missing file, a missing key, an unusable value,
a line too long to read: all of them mean use the default and none is a
failure. BUT QUIET IS NOT SILENT - a setting somebody meant, which did not
take effect, says so. That was the user's addition and it is the better
rule: the default alone leaves the only symptom being that the machine did
not do what somebody asked.

So two routines. cfgGet reads and says nothing, because reading three
settings should not report one bad line three times. cfgCheck reads the
file once and reports, and is handed the caller's list of keys - whether a
key means anything is the only part of this a shared reader cannot judge.

/System/Boot/ holds the boot files, and stage two reads boot.cfg for what
to start, with a fallback to try if it does not work and a name compiled in
for when the file says nothing.

THE TEST FOUND A REAL BUG, and it is the interaction I would not have
thought to look for. First-match-wins met an empty value: a file with

  system
  system /System/Boot/bare.bin

matched the first line, handed back nothing, and the machine tried to start
a file with no name while a good setting sat underneath. An unusable value
is an absent one - which is what "configuration is advice" says, and this
is where it earns its keep.

cfgBare starts an image with no operating system in it at all, which is
what loading an ordinary boot image buys: a program wanting the whole
machine is a file like any other, chosen the same way the system is. Three
disks differing ONLY in boot.cfg, so each is a test of the file rather than
of the machinery under it.
This commit is contained in:
Anachronaut
2026-08-27 16:04:21 -04:00
parent 54ff7196c9
commit 546f336823
11 changed files with 767 additions and 12 deletions
+4
View File
@@ -0,0 +1,4 @@
stage two
bare metal: no system, just this
Execution halted.
[exit 0]
+6
View File
@@ -0,0 +1,6 @@
stage two
a setting nothing asked for: fallbcak
a setting with no value: system
bare metal: no system, just this
Execution halted.
[exit 0]
+16
View File
@@ -0,0 +1,16 @@
stage two
no /System/Boot/missing.bin
trying the fallback
CosmOS
> saved it
read it back, 22 bytes:
a file kept by asking
renamed it
deleted it
and it is gone
finished
> made
> /Notes> 0 files
/Notes> halted
Execution halted.
[exit 0]
+2 -1
View File
@@ -1,4 +1,5 @@
stage two
no /System/cosmos.bin
no /System/Boot/cosmos.bin
nothing to start
Execution halted.
[exit 0]
+1
View File
@@ -12,6 +12,7 @@ Programs/CosmOS/Assembler/readTest.asm redundant-setd 1
Programs/CosmOS/Assembler/token.asm redundant-assignment 4
Programs/CosmOS/Assembler/token.asm redundant-setd 2
Programs/CosmOS/Assembler/tokenTest.asm redundant-setd 1
Programs/CosmOS/Source/config.asm redundant-assignment 1
Programs/CosmOS/Source/cosmos.asm redundant-assignment 1
Programs/CosmOS/Source/cosmos.asm redundant-setd 9
Programs/CosmOS/Source/sbfs.asm branch-to-next 1
+35 -1
View File
@@ -401,8 +401,11 @@ tail -c +17 "$WORK/stage2.sbx" > "$WORK/stage2.raw"
"$ROOT/Assembler" -I "$ROOT/Programs/Libraries" -I "$ROOT/Programs/CosmOS/Source" \
"$ROOT/Programs/CosmOS/Source/cosmos.asm" -o "$WORK/bootCosmos.bin" >/dev/null
"$ROOT/Assembler" "$ROOT/Programs/Boot/bare.asm" -o "$WORK/bare.bin" >/dev/null
"$TOOL" mkdir "$DISKS/selfboot.img" /System >/dev/null
"$TOOL" put "$DISKS/selfboot.img" "$WORK/bootCosmos.bin" /System/cosmos.bin >/dev/null
"$TOOL" mkdir "$DISKS/selfboot.img" /System/Boot >/dev/null
"$TOOL" put "$DISKS/selfboot.img" "$WORK/bootCosmos.bin" /System/Boot/cosmos.bin >/dev/null
"$TOOL" put "$DISKS/selfboot.img" "$WORK/bare.bin" /System/Boot/bare.bin >/dev/null
"$TOOL" mkdir "$DISKS/selfboot.img" /Apps >/dev/null
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
"$ROOT/Programs/CosmOS/Apps/Files.asm" -o "$WORK/bootFiles.sbx" >/dev/null
@@ -412,3 +415,34 @@ tail -c +17 "$WORK/stage2.sbx" > "$WORK/stage2.raw"
# says so rather than jumping somewhere.
"$TOOL" format "$DISKS/nosystem.img" 512 4 32 >/dev/null
"$TOOL" boot "$DISKS/nosystem.img" "$WORK/stage2.raw" 0 >/dev/null
# ---- Configuration choosing what starts ----
#
# The same disk three ways, differing only in /System/Boot/boot.cfg. Nothing else about
# any of them changes, which is what makes these tests of the FILE rather than of the
# machinery under it.
for variant in bare broken fallback; do
cp "$DISKS/selfboot.img" "$DISKS/cfg$variant.img"
done
# A bare metal image, which is the whole point of loading an ordinary boot image: a program
# wanting no operating system is a file like any other.
printf 'system /System/Boot/bare.bin\n' > "$WORK/bare.cfg"
"$TOOL" put "$DISKS/cfgbare.img" "$WORK/bare.cfg" /System/Boot/boot.cfg >/dev/null
# Every kind of mistake at once, and a good setting underneath them. The machine still
# starts, and says what it could not use on the way.
{
printf '; a file with things wrong in it\n'
printf 'fallbcak /System/Boot/cosmos.bin\n'
printf 'system\n'
printf 'system /System/Boot/bare.bin\n'
} > "$WORK/broken.cfg"
"$TOOL" put "$DISKS/cfgbroken.img" "$WORK/broken.cfg" /System/Boot/boot.cfg >/dev/null
# A system that is not there, and something to fall back to.
{
printf 'system /System/Boot/missing.bin\n'
printf 'fallback /System/Boot/cosmos.bin\n'
} > "$WORK/fallback.cfg"
"$TOOL" put "$DISKS/cfgfallback.img" "$WORK/fallback.cfg" /System/Boot/boot.cfg >/dev/null
+18
View File
@@ -401,6 +401,24 @@ selfBootNoSystem | Boot/stage1.asm | run | -
# that is what is IN the ROM: the makefile builds rom.c from that file, so assembling it
# here says the thing the emulator carries is a thing that still assembles.
romBoot | Boot/stage1.asm | rom | selfBoot.in | 90000000 | disks/selfboot.img
# ---- What starts is a setting, not a name compiled into the loader ----
#
# Three disks differing only in /System/Boot/boot.cfg, so each is a test of the file rather
# than of the machinery under it.
#
# cfgBare starts an image with NO OPERATING SYSTEM IN IT, which is what loading an ordinary
# boot image buys: a program wanting the whole machine is a file like any other, and is
# chosen the same way the system is.
cfgBare | Boot/stage1.asm | rom | - | 90000000 | disks/cfgbare.img
# cfgBroken has every kind of mistake in it and a good setting underneath them. The machine
# STILL STARTS - configuration is advice - and says what it could not use on the way, so a
# setting somebody meant which did not happen is not silent.
cfgBroken | Boot/stage1.asm | rom | - | 90000000 | disks/cfgbroken.img
# cfgFallback names a system that is not there. What was tried, and what was tried next.
cfgFallback | Boot/stage1.asm | rom | selfBoot.in | 90000000 | disks/cfgfallback.img
# And the bare image on its own, which has to keep assembling.
bareMetal | Boot/bare.asm | assemble | - | -
# Reading a disk that has directories on it. The machine can walk a path at this point but
# cannot make a directory, so the disk is built by the host tool and read here - which is
# the two implementations checking each other rather than either checking itself.