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
+36
View File
@@ -0,0 +1,36 @@
; bare.asm
; A machine with no operating system on it at all.
;
; THIS IS THE POINT OF LOADING AN ORDINARY IMAGE. The second stage does not know what
; CosmOS is; it knows what a boot image is, and this is one. So a program that wants the
; whole machine to itself - no shell, no filesystem, no services - is not a special case
; needing a special path. It is a file, written under CosmOS like any other, and started by
; naming it in /System/Boot/boot.cfg.
;
; It owns everything from address zero upward, and the only thing it can be sure of is the
; console, because that is all it asked for.
;
; Written by Anachronaut
#Program
start:
SETD.0 Said
sayLoop:
LDA.0
BRA sayDone
OUTA 0x00
INCD.0
BRI sayLoop
sayDone:
HALT
#Data
Said:
"bare metal: no system, just this
"
#Vectors
Boot start
+131 -8
View File
@@ -66,9 +66,74 @@ start:
CALL sbfsMount
BNQ noFilesystem
; ---- What to start ----
;
; Read before the image is, because the configuration is staged where the image will go:
; there is one large free area down here and no reason to have two.
SETD.0 ConfigPath
SETD.2 StageAt
LDD.1.2
INIA 0d4
CALL cfgLoad
; Said before anything is started, so that a setting somebody meant which did not happen
; is on the screen above whatever happened instead.
SETD.0 KnownKeys
CALL cfgCheck
SETD.0 KeySystem
CALL cfgGet
SETD.1 BootName
BNQ systemDefault
SETD.2 CfgValue
LDD.0.2
RCAL copyString
BRI systemChosen
systemDefault:
SETD.0 SystemName
RCAL copyString
systemChosen:
; And what to fall back to, kept now because the configuration is about to be written
; over by the image itself.
RSTA
SETD.0 HaveFallback
STA.0
SETD.0 KeyFallback
CALL cfgGet
BNQ noFallbackSet
SETD.1 FallbackName
SETD.2 CfgValue
LDD.0.2
RCAL copyString
INIA 0x01
SETD.0 HaveFallback
STA.0
noFallbackSet:
SETD.0 BootName
RCAL tryImage
; It did not start. Whatever went wrong has already said so, and if there is something
; else to try then trying it is the whole reason for having said it rather than stopping.
SETD.0 HaveFallback
LDA.0
BRA noSystem
SETD.0 FallbackText
RCAL say
SETD.0 FallbackName
RCAL tryImage
BRI noSystem
; ---- Starting one particular image ----
;
; DP0 names it. Returns only if it could not be started, having said why; everything that
; works ends in the jump at the bottom and never comes back.
tryImage:
SETD.1 TryName
STD.0.1
CALL sbfsFind
BNQ noSystem
BNQ tryMissing
; ---- The image, read whole into somewhere nothing else is using ----
SETD.2 StageAt
@@ -205,33 +270,59 @@ vectorsDone:
unreadable:
SETD.0 UnreadableText
RCAL say
HALT
RCAL sayName
RRET
notAnImage:
SETD.0 NotImageText
RCAL say
HALT
RCAL sayName
RRET
wrongVersion:
SETD.0 VersionText
RCAL say
HALT
RCAL sayName
RRET
wantsMore:
SETD.0 FeatureText
RCAL say
HALT
RCAL sayName
RRET
noFilesystem:
SETD.0 NoDiskText
RCAL say
HALT
noSystem:
tryMissing:
SETD.0 NoSystemText
RCAL say
SETD.0 SystemName
RCAL sayName
RRET
; Whichever image was being tried, said after the reason it did not work.
sayName:
SETD.0 TryName
LDD.0.0
RCAL say
RCAL newLine
RRET
noSystem:
SETD.0 NothingText
RCAL say
HALT
; DP0 names a string and DP1 where to put it, terminator and all.
copyString:
LDA.0
STA.1
BRA copyDone
INCD.0
INCD.1
BRI copyString
copyDone:
RRET
; ---- Comparing a marker and stepping past it ----
;
; DP0 is in the image, DP2 names what it should say, A is how many bytes. DP0 is left past
@@ -398,8 +489,38 @@ NoSystemText:
; What to start. A name for now; the plan is for this to be read out of a file so that any
; number of systems can sit on one disk and the choice is an ordinary safe write.
; Where the configuration lives, and what to start when it does not say.
ConfigPath:
"/System/Boot/boot.cfg"
SystemName:
"/System/cosmos.bin"
"/System/Boot/cosmos.bin"
KeySystem:
"system"
KeyFallback:
"fallback"
; The keys this knows. Anything else in the file is a setting nothing asked for, and
; cfgCheck says so rather than letting it look as though it worked.
KnownKeys:
"system"
"fallback"
""
FallbackText:
"trying the fallback
"
NothingText:
"nothing to start
"
BootName:
#Reserve 0d128
FallbackName:
#Reserve 0d128
HaveFallback:
0x00
TryName:
0x00 0x00
UnreadableText:
"could not read it
@@ -449,6 +570,8 @@ StageAt:
0x20 0x00
#Include sbfs.asm
#Include text.asm
#Include config.asm
; ---- The end of everything ----
;