The Bootstrap Process (including LMC)
Basic BootStrap Process Requirements
- Who Loads the Loader? - If the Operating
System provides the instructions necessary to load other
programs, where do the instructions come from to load the
Operating System? The traditional answer to this is that
instructions to load the Operating System are contained in a
ROM (Read Only Memory) which receives control on initial "power
up". The instructions that perform this load of the Operating
System (or of enough of the Operating System so that it can
complete loading itself) is called a "bootstrap" program. Other
possibilities (than ROM) exist, including a hardware facility
to directly load values into memory locations through "toggle
switches".
- Minimal Bootstrap Requirements - The
bootstrap program must be able to read data from a secondary
storage device into memory (typically from a
non-file-structured area of a disk) into memory and "jump" to
the area of memory where this data was stored.
- Possibility of Re-Use of Bootstrap ROM
space - ROM memory is of no use once the function of
its program has completed. The addresses used by the ROM become
"wasted space", unavailable for other program use. In some
systems this is overcome by having the ROM instructions include
as a terminal action, the setting of an electronic switch which
causes a separate "bank" of RAM memory to replace the ROM with
respect to "address space".
LMC Bootstrap Loader Choices
Assumptions:
- the bootstrap code will be stored in ROM memory; 20
locations will be reserved for this purpose.
- the application program will be loaded from the "Input
Slot"
Choices:
-
Bootstrap Code Location
- First 20 Mailboxes Will Be Bootstrap
ROM: this means that all "application" programs must
be re-translated to start at mailbox 20
- Last 20 Mailboxes Will Be Bootstrap
ROM: this means that the "Reset" button will need to
be "re-wired" to set the Counter to 80 (instead of 00)
- Bootstrap ROM Will Be Somewhere In The
Middle Of The Mailbox Range: this will be considered
"unworkable" since it divides the available memory for
"application" programs into two small areas (note, however,
this is how it is arranged for IBM PC machines with more
than 1 Megabyte of memory).
-
Determining Size Of Application Program For
Input
- Fixed Size Applications: all
"application" programs will be the same size (padded with
00's or garbage if necessary to reach the maximum
size)
- Terminated With A Sentinal
Value: the problem with this method is determining
what to use as a "terminal" value and how to permit this
value to appear (for example as a DAT value) without
signalling the end of the application program.
The most common solution is to use a mechanism similar to
that used for backslashes in C/C++ strings; in the string
"...\t..." the \t has a "special meaning", namely "treate
as a "tab" character; to get a single backslash, C/C++
requires that two be entered in a string e.g. "...\\t..."
is treated as a single backslash followed by the letter
"t". Similarly we could use the sequence 999 000 to signal
end of input and require that 999 be duplicated when a
single 999 value were intended (so the sequence ... 999 999
000 would be treated as a single 999 value followed by a
000 value, and not as an end of input signal).
- Prefix Run-Length Value: an
initial number could be sent before the actual code,
containing the number of mailbox values which were to
follow in forming the "application" program/
Sample LMC Bootstrap Loader
Assumptions for LMC Bootstrap Loader
- Applications will continue to be loaded into RAM starting at mailbox location zero.
- The bootstrap code will be stored in high ROM memory; 20
locations with high mailbox addresses 80 to 99 will be reserved for
this purpose. These 20 locations will be assumed to keep their
values even when the LMC is powered off.
- The application program will be loaded into LMC RAM memory one word
at a time from the "Input Slot".
The very first word read will be a "prefix run-length" value
giving the total number of words that follow to be loaded.
-
The LMC must be modified to start executing at the location
of the bootstrap loader - mailbox 80 - not a the usual counter location of zero.
At power-on, the counter must start at 80 so that the bootstrap program
is the first thing to execute.
-
The LMC "Reset" button must also be modified to set the counter to the address
of the bootstrap loader at 80, not to zero.
LMC Bootstrap Loader Pseudocode
input countOfWordsToLoad
set ptr to lowestAddressForApplications
while (--countOfWordsToLoad) >= 0
input Word
store Word to memory location given by ptr (i.e. Memory[ptr] = Word)
ptr++
endwhile
jump to lowestAddressForApplications
-
Another way of writing "Memory[ptr]=Word" is "*ptr = Word".
-
The value of lowestAddressForApplications is usually mailbox
zero for the LMC.
Issues with LMC implementation
-
Any modifiable value must be in RAM, although the bootstrap program must
itself be in ROM.
Therefore, the bootstrap program will need to use some of the available
RAM for its own use.
We steal some RAM mailbox locations from 76-79.
We cannot load any program larger than 00-75 mailboxes.
-
The LMC makes it difficult to implement indirect addressing
(the "Memory[ptr]=Word" instruction), where we want to loop placing
values into memory at increasing memory locations.
We have to simulate indirect addressing using self-modifying code.
We build a little two-instruction subroutine in RAM and update the
STO instruction inside it to store in increasing memory locations
each time through the loop.
-
The LMC "Reset" button starts the counter at zero, not at 80.
We have to remember, before we start the LMC, to set the counter to 80.
Just in case we forget, the code below puts a JMP BOOT instruction into
location zero that will jump to the BOOT loader.
LMC Bootstrap Loader Mnemonic Code
The listing below is in standard 5-column format: Mailbox, Code, Label, Mnemonic, Operand, with comments added on the right.
=== ==== ===== ==== ========
MBX CODE LABEL MNEM OPERANDS
=== ==== ===== ==== ========
00 ORG 00 ; applications load here at location zero
00 980 START JMP BOOT ; kludge to start BOOT loader when RESET is pushed
76 ORG 76 ; reserve space in RAM in front of bootstrap loader
76 000 SRET DAT ; return address of subroutine, used by "CALL"
77 000 SSTO DAT ; subroutine copied here from ROM: STO 00 (200)
78 000 SJMP DAT ; subroutine copied here from ROM: JMP SRET (976)
79 000 COUNT DAT ; variable - program length - first value input
80 ORG 80 ; start of BOOT: read-only ROM part of bootstrap loader
80 500 BOOT IN ; first input is length of the program being loaded
81 279 STO COUNT
; copy small two-mailbox subroutine from ROM into RAM
82 198 LDA XSTO ; - copy "STO START" (machine code: 200)
83 277 STO SSTO ;
84 199 LDA XJMP ; - copy "JMP SRET" (machine code: 976)
85 278 STO SJMP ;
86 179 WHILE LDA COUNT ; loop while there are still words to be loaded
87 497 SUB ONE
88 279 STO COUNT
89 802 SKP ; skip *into* loop body if count >= 0
90 900 JMP START ; load is done - jump to start application just loaded
91 500 IN
92 077 CALL SSTO ; call the "store" subroutine copied to RAM above
93 177 LDA SSTO ; add one to the "STO" instruction (self-modifying!)
94 397 ADD ONE ; so that it stores into the next memory location
95 277 STO SSTO
96 986 JMP WHILE
97 001 ONE DAT 001 ; constant 001 (everything from 80 to 99 is in ROM)
98 200 XSTO STO START ; constant 200 ("STO 00") - part of small subroutine
99 976 XJMP JMP SRET ; constant 976 ("JMP SRET") - part of small subroutine
References