B4: the disk remembers whether the last start arrived
The loader marks the superblock before it hands over and the system clears the mark when it reaches its prompt, so a system that crashes on the way there leaves it set. The loader finding it still set next time is how a machine that will not start says so to the only thing in a position to do anything about it. Without that, pointing boot.cfg at something that dies before the shell is a machine that can never be told anything again - the shell is the only way to change the file, and the file is what stops the shell from starting. Three states rather than two, and the third is the one worth having: 0 settled the last start arrived; use the configuration 1 trying handed over, and nothing came back to say it got there 2 fell back a try failed and the fallback was used, until settled With only 0 and 1 the machine alternates for ever: fall back, reach a prompt, clear the mark, retry the broken system, crash, fall back. State 2 stops that. A system known not to start is not tried again until somebody says the situation has changed. REACHING THE PROMPT IS A DELIBERATE THRESHOLD. It is not a claim that the system works - a shell can be reached by something broken in every other way. It is the point where a person can type, which is exactly what the fallback exists to give back: anything wrong past there is fixable from the prompt and nothing wrong before it is fixable at all. The routines live in sbfs.asm because both the loader and the system read and write this byte, and two pieces of code with their own idea of where a byte lives is what this format has two implementations and a byte for byte comparison to avoid. And the trap this system documents in its own manual caught me anyway: the first version handed the state back in A, which CALL restores, so every read got whatever the caller happened to be holding. It comes back in memory now, and the comment says why. Three disks differing only in the state on them, so the tests read as three consecutive starts of one machine while none depends on another running.
This commit is contained in:
@@ -111,16 +111,50 @@ systemChosen:
|
||||
STA.0
|
||||
noFallbackSet:
|
||||
|
||||
; ---- How the last start went ----
|
||||
;
|
||||
; Settled means the last one arrived, so try what the configuration asks for. Trying
|
||||
; means the loader handed over last time and nothing came back to say it got there, so
|
||||
; the thing named is what broke the machine and the fallback is the way out. Fell back
|
||||
; means that already happened and nobody has settled it since, so do the same again
|
||||
; rather than retrying a system that is known not to start.
|
||||
CALL sbfsBootState
|
||||
SETD.0 SbfsStateWas
|
||||
LDA.0
|
||||
BRA stateSettled
|
||||
INIB 0d1
|
||||
XOR
|
||||
BRQ stateFailedLast
|
||||
SETD.0 StillBackText
|
||||
RCAL say
|
||||
BRI useFallback
|
||||
|
||||
stateFailedLast:
|
||||
SETD.0 DidNotArriveText
|
||||
RCAL say
|
||||
INIA 0d2
|
||||
CALL sbfsSetBootState
|
||||
BRI useFallback
|
||||
|
||||
stateSettled:
|
||||
; The mark goes down BEFORE the jump, because after it there is nothing here to do it.
|
||||
; What clears it is the system reaching its prompt, which is not a claim that the system
|
||||
; works - it is the moment a person can tell it otherwise.
|
||||
INIA 0d1
|
||||
CALL sbfsSetBootState
|
||||
|
||||
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 FallbackText
|
||||
RCAL say
|
||||
|
||||
useFallback:
|
||||
SETD.0 HaveFallback
|
||||
LDA.0
|
||||
BRA noSystem
|
||||
SETD.0 FallbackText
|
||||
RCAL say
|
||||
SETD.0 FallbackName
|
||||
RCAL tryImage
|
||||
BRI noSystem
|
||||
@@ -509,6 +543,12 @@ KnownKeys:
|
||||
FallbackText:
|
||||
"trying the fallback
|
||||
"
|
||||
DidNotArriveText:
|
||||
"the last start did not arrive
|
||||
"
|
||||
StillBackText:
|
||||
"still on the fallback: settle it to try again
|
||||
"
|
||||
NothingText:
|
||||
"nothing to start
|
||||
"
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
; wedged.asm
|
||||
; A system that starts and never reaches a prompt.
|
||||
;
|
||||
; Not a broken program so much as a stand in for one: what matters is that it is handed the
|
||||
; machine and never clears the mark the loader put on the disk, which is what every real
|
||||
; way of failing before the shell has in common.
|
||||
;
|
||||
; Without that mark, pointing /System/Boot/boot.cfg at something like this would be a
|
||||
; machine that could not be told anything ever again - the shell is the only way to change
|
||||
; the file, and the file is what stops the shell from starting.
|
||||
;
|
||||
; Written by Anachronaut
|
||||
|
||||
#Program
|
||||
|
||||
start:
|
||||
SETD.0 Dying
|
||||
sayLoop:
|
||||
LDA.0
|
||||
BRA gone
|
||||
OUTA 0x00
|
||||
INCD.0
|
||||
BRI sayLoop
|
||||
gone:
|
||||
HALT
|
||||
|
||||
#Data
|
||||
|
||||
Dying:
|
||||
"a system that never reaches a prompt
|
||||
"
|
||||
|
||||
#Vectors
|
||||
|
||||
Boot start
|
||||
Reference in New Issue
Block a user