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
+49 -2
View File
@@ -306,8 +306,8 @@ has versions - all of that lives in the boot area, on the disk, where it can be
It reads the live slot into Program Memory, jumps to the first byte, and prints one
character and stops if there is nothing to start.
`Programs/Boot/stage2.asm` is what sits in the slot. It mounts the filesystem, finds the
system by name, and takes the image apart: code into Program Memory, data into Data
`Programs/Boot/stage2.asm` is what sits in the slot. It mounts the filesystem, reads
`/System/Boot/boot.cfg` to find out what to start, and takes the image apart: code into Program Memory, data into Data
Memory, and each vector written through the controller, which is the only thing that can
write Program Memory at all. The entry point is noticed on the boot vector's way past,
because Program Memory cannot be read back to look it up afterwards.
@@ -318,6 +318,53 @@ normal image format is not a boot-specific mechanism, so **bare metal SplitBit s
a special case.** A program that wants no operating system under it is just an image,
written under CosmOS like any other, and startable because it is a file.
### Configuration:
One setting to a line: a key, a space, and the rest of the line is the value. A semicolon
starts a comment and a blank line is nothing.
```
; /System/Boot/boot.cfg
system /System/Boot/cosmos.bin
fallback /System/Boot/cosmos-previous.bin
```
That format was noticed rather than designed. `textSplit` already cuts the first word off a
line and leaves the rest; `textSame` already compares two strings and insists they end
together, so `system` and `systemd` are different words. Reading a setting is those two
routines and a loop - and it is the shape the shell already reads, so **a configuration
line is a command line the machine reads instead of a person typing one.**
**Configuration is advice.** A missing file, a missing key, a value that makes no sense, a
line too long to read: all of them mean *use the default*, and none of them is a failure. A
program that cannot run without its configuration has turned its configuration into a
single point of failure, and for the thing that starts the machine that would mean a
mistyped file is a machine that will not start.
**But quiet is not silent.** A setting somebody meant, which did not take effect, says so:
```
a setting nothing asked for: fallbcak
a setting with no value: system
a line too long to read: ...
```
So `config.asm` has two routines rather than one. `cfgGet` reads and never says anything -
reading three settings should not report the same bad line three times. `cfgCheck` reads
the file once and reports what it did not understand, and is given the caller's list of
keys, because whether a key means anything is the only part of this the reader cannot
judge for itself.
Keys are matched exactly and case sensitively, the first line that matches wins, and
unknown keys are ignored rather than refused - so a file written by a newer system loses
the settings an older one never had and keeps the ones it did. A line is at most 128 bytes
and a key at most 22, which is what a name is everywhere else on this machine.
Deliberately absent: sections, nesting, types, includes, substitution, conditions. Each is
a step from reading a file toward running one, and the boot loader is the worst place on
this machine to put an interpreter. The test to apply when the pressure arrives is: **if
this file cannot be read, can the machine still start?**
Stage two arranges its own Data Segment. Stage one places Program Memory and nothing else,
since knowing where a payload's data ended would mean knowing a format, so the image is
written into the slot as code followed by data and stage two's first act is to blit its