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
|
||||
@@ -63,6 +63,38 @@ boot:
|
||||
BNQ bootNoDisk
|
||||
INIA 0x01
|
||||
STA.0
|
||||
|
||||
; ---- Saying that this start arrived ----
|
||||
;
|
||||
; The loader marks the disk before handing over, and nothing clears it but this. A system
|
||||
; that crashes on the way here leaves the mark, and the loader finding it still set next
|
||||
; time is how a machine that will not start says so.
|
||||
;
|
||||
; HERE RATHER THAN LATER, and the threshold is the whole of what the mark means. It is
|
||||
; not a claim that anything works - a prompt can be reached by something broken in every
|
||||
; other way. It is the point where somebody can type, which is what the fallback exists
|
||||
; to give back: anything wrong past here can be fixed from the prompt, and nothing wrong
|
||||
; before it can be fixed at all.
|
||||
CALL sbfsBootState
|
||||
BNQ prompt
|
||||
SETD.0 SbfsStateWas
|
||||
LDA.0
|
||||
INIB 0d1
|
||||
XOR
|
||||
BRQ bootArrived
|
||||
INIB 0d2
|
||||
XOR
|
||||
BNQ prompt
|
||||
|
||||
; Started by the fallback, so the system somebody asked for is not the one running. Said
|
||||
; once, here, because there is nowhere else it would be noticed.
|
||||
SETD.0 OnFallback
|
||||
CALL printString
|
||||
BRI prompt
|
||||
|
||||
bootArrived:
|
||||
RSTA
|
||||
CALL sbfsSetBootState
|
||||
BRI prompt
|
||||
bootNoDisk:
|
||||
RSTA
|
||||
@@ -3370,6 +3402,9 @@ Banner:
|
||||
"CosmOS"
|
||||
PromptText:
|
||||
"> "
|
||||
OnFallback:
|
||||
"this is the fallback: what boot.cfg asks for did not start
|
||||
"
|
||||
NoDisk:
|
||||
"no filesystem on the disk"
|
||||
Unknown:
|
||||
|
||||
@@ -2984,8 +2984,86 @@ sbfsSaveFailed:
|
||||
ADD
|
||||
RET
|
||||
|
||||
; ---- How the last start went ----
|
||||
;
|
||||
; One byte of the superblock, written by the loader before it hands over and cleared by the
|
||||
; system once it is running. A system that never gets that far leaves the mark set, and the
|
||||
; loader seeing it still set next time is how a machine that cannot start says so to the
|
||||
; only thing in a position to do anything about it.
|
||||
;
|
||||
; Kept here rather than in either of them because BOTH read and write it, and two pieces of
|
||||
; code with their own idea of where a byte lives is the thing this filesystem has two
|
||||
; implementations and a byte for byte comparison to avoid.
|
||||
;
|
||||
; sbfsBootState leaves the state in SbfsStateWas, and Q zero if the disk answered.
|
||||
;
|
||||
; NOT IN A, and the first version of this tried to. CALL restores A, so a routine cannot
|
||||
; hand anything back in it: the value was set, the RET put the caller's own A back over it,
|
||||
; and every state read as whatever the caller happened to be holding. It is the trap this
|
||||
; system documents in its own manual and it still catches people.
|
||||
sbfsBootState:
|
||||
RSTA
|
||||
SETD.0 SbfsBlock
|
||||
STA.0
|
||||
INCD.0
|
||||
STA.0
|
||||
CALL sbfsReadBlock
|
||||
BNQ sbfsBootStateNo
|
||||
SETD.1 SbfsBuffer
|
||||
CALL sbfsBufferOut
|
||||
SETD.0 SbfsBuffer
|
||||
DPUP.0 0d17
|
||||
LDA.0
|
||||
SETD.1 SbfsStateWas
|
||||
STA.1
|
||||
RSTA
|
||||
RSTB
|
||||
CCF
|
||||
ADD ; Q is zero: SbfsStateWas is what the disk says.
|
||||
RET
|
||||
|
||||
sbfsBootStateNo:
|
||||
RSTA
|
||||
SETD.0 SbfsStateWas
|
||||
STA.0
|
||||
INIB 0d1
|
||||
CCF
|
||||
ADD ; Q is not zero, and the state reads as settled.
|
||||
RET
|
||||
|
||||
; A is what to write. Q is zero if it went down.
|
||||
;
|
||||
; The superblock is read back before it is changed rather than kept from the mount, because
|
||||
; everything between then and now has been reading other blocks over the buffer it was in.
|
||||
sbfsSetBootState:
|
||||
SETD.0 SbfsStateWants
|
||||
STA.0
|
||||
RSTA
|
||||
SETD.0 SbfsBlock
|
||||
STA.0
|
||||
INCD.0
|
||||
STA.0
|
||||
CALL sbfsReadBlock
|
||||
BNQ sbfsBootStateNo
|
||||
SETD.1 SbfsBuffer
|
||||
CALL sbfsBufferOut
|
||||
SETD.0 SbfsStateWants
|
||||
LDA.0
|
||||
SETD.1 SbfsBuffer
|
||||
DPUP.1 0d17
|
||||
STA.1
|
||||
SETD.1 SbfsBuffer
|
||||
CALL sbfsBufferIn
|
||||
CALL sbfsWriteBlock
|
||||
RET
|
||||
|
||||
#Data
|
||||
|
||||
SbfsStateWas:
|
||||
0x00
|
||||
SbfsStateWants:
|
||||
0x00
|
||||
|
||||
SbfsMagic:
|
||||
"SBFS"
|
||||
|
||||
|
||||
@@ -268,6 +268,7 @@ increment, decrement, addition, and subtraction when their inputs are known.
|
||||
| Command | What it does |
|
||||
| --- | --- |
|
||||
| `boot <image> <file> [slot]` | Write a file into a boot slot, padding the rest of it with zeroes. Slot 0 unless told otherwise. |
|
||||
| `bootstate <image> [0\|1\|2]` | Show how the last start went, or set it. Setting it to 0 is how a disk that fell back is told to try again. |
|
||||
| `bootslot <image> <slot>` | Choose which slot the machine starts from. One byte, on its own, so writing a slot and committing to it stay separate decisions. |
|
||||
| `format <image> [blocks] [dirblocks] [bootblocks]` | Lay down a fresh filesystem. 512 blocks and 8 of directory by default, which is 128K and room for 64 entries. A fourth number reserves a boot area of two slots that size. |
|
||||
| `list <image> [path]` | Show the whole disk, or one directory of it. |
|
||||
@@ -295,6 +296,43 @@ so a machine interrupted while updating its only boot slot would not boot at all
|
||||
the one failure on this disk with no way back. Writing the slot that is *not* live and then
|
||||
moving one byte in the superblock turns that into a machine that boots what it had before.
|
||||
|
||||
### Knowing Whether The Last Start Arrived:
|
||||
|
||||
The loader marks the disk before it hands over, and the system clears the mark when it
|
||||
reaches its prompt. **A system that crashes on the way there leaves the mark**, and 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.
|
||||
|
||||
| State | Means |
|
||||
| -- | -- |
|
||||
| 0 | Settled. The last start arrived, so start what the configuration says. |
|
||||
| 1 | Trying. The loader handed over and nothing came back to say it got there. |
|
||||
| 2 | Fell back. A try failed and the fallback was used, and will be until this is settled. |
|
||||
|
||||
Three starts of a machine whose configuration names something broken:
|
||||
|
||||
```
|
||||
stage two
|
||||
a system that never reaches a prompt <- marks the disk, dies
|
||||
|
||||
stage two
|
||||
the last start did not arrive <- finds the mark, uses the fallback
|
||||
CosmOS
|
||||
this is the fallback: what boot.cfg asks for did not start
|
||||
|
||||
stage two
|
||||
still on the fallback: settle it to try again <- does NOT retry
|
||||
```
|
||||
|
||||
That third one is the part worth having. A system known not to start is not tried every
|
||||
other boot for ever; it waits to be told the situation has changed.
|
||||
|
||||
**Reaching the prompt is a deliberate choice of 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 somebody can type, which is exactly what the fallback exists to give back:
|
||||
anything wrong past there can be fixed from the prompt, and nothing wrong before it can be
|
||||
fixed at all.
|
||||
|
||||
`bootBlocks` and `directoryStart` describe the same fact from two sides, so a disk where
|
||||
they disagree is refused rather than guessed at.
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ typedef struct {
|
||||
uint16_t freeBlocks;
|
||||
uint16_t bootBlocks; // Per slot. Zero on a disk that cannot be booted.
|
||||
uint8_t bootSlot; // Which of the two is live.
|
||||
uint8_t bootState; // How the last start went. See sbfs.h.
|
||||
} Superblock;
|
||||
|
||||
// Reads block 0 and checks it really is one of ours. Without the magic a blank image and
|
||||
@@ -97,6 +98,7 @@ static int readSuperblock(FILE *image, Superblock *super) {
|
||||
super->freeBlocks = readWord(block + SBFS_SUPER_FREE);
|
||||
super->bootBlocks = readWord(block + SBFS_SUPER_BOOTBLOCKS);
|
||||
super->bootSlot = block[SBFS_SUPER_BOOTSLOT];
|
||||
super->bootState = block[SBFS_SUPER_BOOTSTATE];
|
||||
|
||||
// The boot area and the directory's position describe the same fact from two sides,
|
||||
// so they have to agree or one of them is wrong and there is no way to tell which.
|
||||
@@ -130,6 +132,7 @@ static int writeSuperblock(FILE *image, const Superblock *super) {
|
||||
writeWord(block + SBFS_SUPER_FREE, super->freeBlocks);
|
||||
writeWord(block + SBFS_SUPER_BOOTBLOCKS, super->bootBlocks);
|
||||
block[SBFS_SUPER_BOOTSLOT] = super->bootSlot;
|
||||
block[SBFS_SUPER_BOOTSTATE] = super->bootState;
|
||||
return writeBlock(image, 0, block);
|
||||
}
|
||||
|
||||
@@ -481,6 +484,7 @@ static int commandFormat(const char *path, uint16_t blocks, uint16_t directoryBl
|
||||
super.freeBlocks = (uint16_t)(blocks - overhead);
|
||||
super.bootBlocks = bootBlocks;
|
||||
super.bootSlot = 0;
|
||||
super.bootState = SBFS_BOOT_SETTLED;
|
||||
if (writeSuperblock(image, &super)) {
|
||||
fclose(image);
|
||||
return 1;
|
||||
@@ -782,6 +786,51 @@ static int commandBootSlot(const char *path, long slot) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---- How the last start went, from the host ----
|
||||
//
|
||||
// Shown with no argument and set with one. Setting it is how a disk that fell back is told
|
||||
// to try again, which is a decision rather than a repair: the thing that did not start has
|
||||
// to be fixed first, or the next start marks it and falls back once more.
|
||||
static const char *bootStateName(uint8_t state) {
|
||||
switch (state) {
|
||||
case SBFS_BOOT_SETTLED: return "settled, so the next start will use the configuration";
|
||||
case SBFS_BOOT_TRYING: return "trying, so the last start never arrived";
|
||||
case SBFS_BOOT_FELLBACK: return "fell back, and will keep doing so until settled";
|
||||
default: return "a number this does not recognise";
|
||||
}
|
||||
}
|
||||
|
||||
static int commandBootState(const char *path, const char *setting) {
|
||||
FILE *image = openImage(path, setting ? "r+b" : "rb");
|
||||
if (image == NULL) {
|
||||
return 1;
|
||||
}
|
||||
Superblock super;
|
||||
if (readSuperblock(image, &super)) {
|
||||
fclose(image);
|
||||
return 1;
|
||||
}
|
||||
if (setting == NULL) {
|
||||
printf("%u: %s\n", super.bootState, bootStateName(super.bootState));
|
||||
fclose(image);
|
||||
return 0;
|
||||
}
|
||||
long wanted = strtol(setting, NULL, 0);
|
||||
if (wanted < 0 || wanted > SBFS_BOOT_FELLBACK) {
|
||||
fprintf(stderr, "Error: The boot state is 0, 1 or 2.\n");
|
||||
fclose(image);
|
||||
return 1;
|
||||
}
|
||||
super.bootState = (uint8_t)wanted;
|
||||
if (writeSuperblock(image, &super)) {
|
||||
fclose(image);
|
||||
return 1;
|
||||
}
|
||||
fclose(image);
|
||||
printf("%ld: %s\n", wanted, bootStateName((uint8_t)wanted));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int commandPut(const char *path, const char *hostFile, const char *asName) {
|
||||
FILE *source = fopen(hostFile, "rb");
|
||||
if (source == NULL) {
|
||||
@@ -1183,6 +1232,9 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
return commandBoot(path, argv[3], (argc > 4) ? strtol(argv[4], NULL, 0) : 0);
|
||||
}
|
||||
if (strcmp(command, "bootstate") == 0) {
|
||||
return commandBootState(path, (argc > 3) ? argv[3] : NULL);
|
||||
}
|
||||
if (strcmp(command, "bootslot") == 0) {
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "Error: bootslot needs the slot to start from.\n");
|
||||
|
||||
+24
-1
@@ -53,7 +53,8 @@
|
||||
// 12 2 Free blocks, a cache rather than the authority
|
||||
// 14 2 Blocks in each boot slot, or zero for a disk that cannot be booted
|
||||
// 16 1 Which boot slot is live, 0 or 1
|
||||
// 17 Reserved to the end of the block
|
||||
// 17 1 How the last start went. See below.
|
||||
// 18 Reserved to the end of the block
|
||||
|
||||
#define SBFS_SUPER_VERSION 4
|
||||
#define SBFS_SUPER_DISK 6
|
||||
@@ -86,6 +87,28 @@
|
||||
// 1 .. bootBlocks slot 0
|
||||
// bootBlocks+1 .. 2*bootBlocks slot 1
|
||||
// directoryStart .. the directory, and then files
|
||||
// ---- How the last start went ----
|
||||
//
|
||||
// Written by the loader before it hands over and cleared by the system once it is running,
|
||||
// so that a system which never gets that far leaves a mark saying so. THE MARK IS WHAT
|
||||
// MAKES A NEW SYSTEM SAFE TO TRY: without it, pointing boot.cfg at something that crashes
|
||||
// before the prompt is a machine that cannot be told anything ever again.
|
||||
//
|
||||
// What clears it is reaching the shell, and that is a deliberate choice of threshold. It
|
||||
// does not mean the system works - a shell can be reached by something that is broken in
|
||||
// every other way. It means A PERSON HAS CONTROL AGAIN, which is exactly what the fallback
|
||||
// exists to restore and therefore exactly when it has done its job.
|
||||
//
|
||||
// 0 Settled. The last start finished. Start what the configuration says.
|
||||
// 1 Trying. The loader handed over and nothing came back to say it arrived.
|
||||
// 2 Fell back. A try failed and the fallback was used instead. Stays until somebody
|
||||
// settles it, so that a system which crashes is not retried every other
|
||||
// boot for ever.
|
||||
#define SBFS_SUPER_BOOTSTATE 17
|
||||
#define SBFS_BOOT_SETTLED 0
|
||||
#define SBFS_BOOT_TRYING 1
|
||||
#define SBFS_BOOT_FELLBACK 2
|
||||
|
||||
#define SBFS_BOOT_SLOTS 2
|
||||
#define SBFS_FIRST_BOOT_BLOCK 1
|
||||
|
||||
|
||||
@@ -220,6 +220,14 @@ d = open('boot.img','rb').read()
|
||||
slot = d[256:256 + 32 * 256]
|
||||
sys.exit(1 if b'aaaa' in slot else 0)"
|
||||
|
||||
# ---- How the last start went ----
|
||||
check "the boot state reads" "$TOOL" bootstate boot.img
|
||||
check "and can be set" "$TOOL" bootstate boot.img 2
|
||||
refuses "but only to a state there is" "$TOOL" bootstate boot.img 7
|
||||
check "a fresh disk is settled" python3 -c "
|
||||
import sys
|
||||
sys.exit(0 if open('plain.img','rb').read()[17] == 0 else 1)"
|
||||
|
||||
echo
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
echo "All $PASS disk tool checks passed."
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
stage two
|
||||
no /System/Boot/cosmos.bin
|
||||
trying the fallback
|
||||
nothing to start
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
stage two
|
||||
a system that never reaches a prompt
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
@@ -0,0 +1,8 @@
|
||||
stage two
|
||||
the last start did not arrive
|
||||
CosmOS
|
||||
this is the fallback: what boot.cfg asks for did not start
|
||||
>
|
||||
halted
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
@@ -0,0 +1,8 @@
|
||||
stage two
|
||||
still on the fallback: settle it to try again
|
||||
CosmOS
|
||||
this is the fallback: what boot.cfg asks for did not start
|
||||
>
|
||||
halted
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
@@ -446,3 +446,24 @@ printf 'system /System/Boot/bare.bin\n' > "$WORK/bare.cfg"
|
||||
printf 'fallback /System/Boot/cosmos.bin\n'
|
||||
} > "$WORK/fallback.cfg"
|
||||
"$TOOL" put "$DISKS/cfgfallback.img" "$WORK/fallback.cfg" /System/Boot/boot.cfg >/dev/null
|
||||
|
||||
# ---- A system that never reaches a prompt ----
|
||||
#
|
||||
# The case the boot state exists for. Pointing the configuration at something that dies
|
||||
# before the shell is, without a mark on the disk, a machine that can never be told
|
||||
# anything again - so the loader marks it before handing over and the system clears the
|
||||
# mark on arrival, which makes "did not arrive" a thing the next start can see.
|
||||
"$ROOT/Assembler" "$ROOT/Programs/Boot/wedged.asm" -o "$WORK/wedged.bin" >/dev/null
|
||||
for stage in first second third; do
|
||||
cp "$DISKS/selfboot.img" "$DISKS/wedge$stage.img"
|
||||
"$TOOL" put "$DISKS/wedge$stage.img" "$WORK/wedged.bin" /System/Boot/wedged.bin >/dev/null
|
||||
{
|
||||
printf 'system /System/Boot/wedged.bin\n'
|
||||
printf 'fallback /System/Boot/cosmos.bin\n'
|
||||
} > "$WORK/wedge.cfg"
|
||||
"$TOOL" put "$DISKS/wedge$stage.img" "$WORK/wedge.cfg" /System/Boot/boot.cfg >/dev/null
|
||||
done
|
||||
# Each disk begins where the one before it ended, so the three tests read as three
|
||||
# consecutive starts of one machine without any of them depending on the others running.
|
||||
"$TOOL" bootstate "$DISKS/wedgesecond.img" 1 >/dev/null
|
||||
"$TOOL" bootstate "$DISKS/wedgethird.img" 2 >/dev/null
|
||||
|
||||
@@ -419,6 +419,20 @@ cfgBroken | Boot/stage1.asm | rom | -
|
||||
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 | - | -
|
||||
|
||||
# ---- A system that never reaches a prompt ----
|
||||
#
|
||||
# Three disks that differ only in the boot state on them, so the three tests read as three
|
||||
# consecutive starts of one machine while none of them depends on another having run.
|
||||
#
|
||||
# wedgeFirst tries it and marks the disk. wedgeSecond finds the mark still set - nothing
|
||||
# came back to say the last start arrived - and uses the fallback. wedgeThird finds that
|
||||
# already happened and does the same again WITHOUT retrying, which is the part worth
|
||||
# pinning down: a system known not to start should not be tried every other boot for ever.
|
||||
wedgeFirst | Boot/stage1.asm | rom | - | 90000000 | disks/wedgefirst.img
|
||||
wedgeSecond | Boot/stage1.asm | rom | - | 90000000 | disks/wedgesecond.img
|
||||
wedgeThird | Boot/stage1.asm | rom | - | 90000000 | disks/wedgethird.img
|
||||
wedgedImage | Boot/wedged.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.
|
||||
|
||||
Reference in New Issue
Block a user