1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-15 04:28:06 +11:00
collapseos/doc/bootstrap.txt

134 lines
4.8 KiB
Plaintext
Raw Normal View History

2020-08-16 22:33:02 +10:00
# Bootstrap guide
2020-09-20 00:32:28 +10:00
You want to deploy Collapse OS on a new system? Read usage.txt,
impl.txt, cross.txt, then continue here.
2020-08-16 22:33:02 +10:00
What is Collapse OS? It is a binary placed either in ROM on
in RAM by a bootloader. That binary, when executed, initializes
itself to a Forth interpreter. In most cases, that Forth
interpreter will have some access to a mass storage device,
2020-09-19 23:04:18 +10:00
which allows it to access Collapse OS' disk blocks and bootstrap
itself some more.
2020-08-16 22:33:02 +10:00
This binary can be separated in 5 distinct layers:
2020-09-19 23:04:18 +10:00
1. Arch-specific boot code (B280 for Z80)
2. Arch-specific boot words (B305 for Z80)
3. Arch-independant core words (low) (B350)
4. Drivers, might contain arch-specific code
2020-11-01 06:27:00 +11:00
5. Arch-independant core words (high) (B390)
2020-08-16 22:33:02 +10:00
2020-09-19 23:04:18 +10:00
# Boot code
2020-08-16 22:33:02 +10:00
This part contains core routines that underpins Forth fundamen-
2020-09-19 23:04:18 +10:00
tal structures: dict navigation and FIND, PSP/RSP bounds checks,
word types.
2020-08-16 22:33:02 +10:00
It also of course does core initialization: set RSP/PSP, HERE
CURRENT, then call BOOT.
It also contains what we call the "stable ABI" in its first
2020-11-01 06:27:00 +11:00
few (<0x20) bytes.
2020-08-16 22:33:02 +10:00
2020-09-19 23:04:18 +10:00
# Boot words
2020-08-16 22:33:02 +10:00
Then come the implementation of core Forth words in native
assembly. Performance is not Collapse OS' primary design goal,
so we try to keep this section to a minimum: we much prefer
to implement our words in Forth.
However, some words are in this section for performance
reasons. Sometimes, the gain is too great to pass up.
2020-09-19 23:04:18 +10:00
# Core words (low)
2020-08-16 22:33:02 +10:00
Then comes the part where we begin defining words in Forth.
Core words are designed to be cross-compiled (B260), from a
full Forth interpreter. This means that it has access to more
than boot words. This comes with tricky limitations.
See B260 for details.
# Drivers
2020-11-01 06:27:00 +11:00
Core words don't include (key) and (emit) implementations be-
cause that's hardware-dependant. This is where we need to load
code that implement it, as well as any other code we want to
include in the binary.
2020-08-16 22:33:02 +10:00
2020-11-01 06:27:00 +11:00
We do it now because if we wait until the high layer of core
words is loaded, we'll have messed up immediates and ":" will
be broken. If we load our code before, we won't have access to
a wide vocabulary.
2020-08-16 22:33:02 +10:00
2020-09-19 23:04:18 +10:00
# Core words (high)
2020-08-16 22:33:02 +10:00
2020-11-01 06:27:00 +11:00
The final layer of core words contains the BOOT word as well
as tricky immediates which, if they're defined sooner, mess
cross compilation up. Once this layer is loaded, we become
severly limited in the words we can use without messing up.
2020-08-16 22:33:02 +10:00
2020-11-15 06:34:01 +11:00
# Hook word
After having loaded that last core words layer, we end that
with a hook word, the "(entry) _" line. A hook word is an empty
word at the end of the dictionary which serves 3 purposes:
1. After having created that word, PC conveniently holds the
value that should go in the LATEST field in stable ABI. Had
the word been non-empty, getting that value would be less
straightforward.
2. Because LATEST points to an empty word, it means that it also
points to the initialization string, which directly follows.
If it was non-empty, we would need to know the word's length
to get to that string.
3. If, for some reason, you want to "graft" another dictionary
on top of this one, having it end with an empty word makes
grafting convenient: you already know what your "prev field"
offset should be for the grafting to be correct.
# Initialization string
After the last word of the dictionary comes the "source init"
part. The boot sequence is designed to interpret whatever comes
after LATEST as Forth source, and this, until it reads ASCII
EOT character (4). This is generally used for driver init.
# Building it
2020-08-16 22:33:02 +10:00
So that's the anatomy of a Collapse OS binary. How do you build
one? If your machine is already covered by a recipe, you're in
luck: follow instructions.
If you're deploying to a new machine, you'll have to write a
new xcomp (cross compilation) unit. Let's look at its
anatomy. First, we have constants. Some of them are device-
specific, but some of them are always there. SYSVARS is the
address at which the RAM starts on the system. System variables
2020-09-19 23:04:18 +10:00
will go there and use 0x80 bytes. See impl.txt.
2020-08-16 22:33:02 +10:00
HERESTART determines where... HERE is at startup. 0 means
"same as CURRENT".
RS_ADDR is where RSP starts and PS_ADDR is where PSP starts.
RSP and PSP are designed to be contiguous. RSP goes up and PSP
goes down. If they meet, we know we have a stack overflow.
Then, we load the assembler and cross compilation unit, which
will be needed for the task ahead.
Then, it's a matter of adding layer after layer. For most
system, all those layers except the drivers will be added the
same way. Drivers are a bit tricker and machine specific. I
can't help you there, you'll have to use your wits.
After we've loaded the high part of the core words, we're at
2020-11-15 06:34:01 +11:00
the "wrapping up" part. We add the hook word and init string.
2020-08-16 22:33:02 +10:00
2020-11-01 06:27:00 +11:00
To produce a Collapse OS binary, you run that xcomp unit and
then observe the values of "ORG @" and "H@". That will give you
the start and stop offset of your binary, which you can then
copy to your target media.
2020-08-16 22:33:02 +10:00
Good luck!