326 lines
9.0 KiB
Plaintext
326 lines
9.0 KiB
Plaintext
|
\cfg{chapter}{Section}
|
||
|
|
||
|
\cfg{text-filename}{ldosboot.txt}
|
||
|
\cfg{text-chapter-numeric}{true}
|
||
|
\cfg{text-indent-preamble}{false}
|
||
|
\cfg{text-quotes}{"}{"}
|
||
|
\cfg{text-indent}{4}
|
||
|
\cfg{text-width}{72}
|
||
|
|
||
|
\cfg{html-chapter-numeric}{true}
|
||
|
\cfg{html-suppress-address}{true}
|
||
|
\cfg{html-single-filename}{ldosboot.htm}
|
||
|
\cfg{html-leaf-level}{0}
|
||
|
\cfg{html-template-fragment}{%k}{%b}
|
||
|
\cfg{html-head-end}{<meta name="viewport" content="width=device-width, initial-scale=1.0">}
|
||
|
|
||
|
\cfg{pdf-filename}{ldosboot.pdf}
|
||
|
|
||
|
\cfg{ps-filename}{ldosboot.ps}
|
||
|
|
||
|
\cfg{info-filename}{ldosboot.info}
|
||
|
|
||
|
\cfg{chm-filename}{ldosboot.chm}
|
||
|
|
||
|
\cfg{winhelp-filename}{ldosboot.hlp}
|
||
|
|
||
|
\cfg{man-filename}{ldosboot.7}
|
||
|
\cfg{man-identity}{ldosboot}{7}{2020}{}{C. Masloch}
|
||
|
|
||
|
\title lDOS boot documentation
|
||
|
|
||
|
\copyright 2020 by C. Masloch.
|
||
|
Usage of the works is permitted provided that this
|
||
|
instrument is retained with the works, so that any entity
|
||
|
that uses the works is notified of this instrument.
|
||
|
DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
|
||
|
|
||
|
This document has been compiled on \date{%Y-%m-%d}.
|
||
|
|
||
|
|
||
|
\C{protocols} lDOS boot protocols
|
||
|
|
||
|
|
||
|
\H{protocol-sector-iniload} Sector to iniload protocol
|
||
|
|
||
|
The iniload kernel is loaded to an arbitrary segment.
|
||
|
The segment must be at least 60h.
|
||
|
Common choices are 60h, 70h, and 200h.
|
||
|
At least 1536 bytes of the file must be loaded.
|
||
|
Current loaders will load at least 8192 bytes
|
||
|
if the file is as large or larger than that.
|
||
|
The entrypoint is found by applying no segment adjustment (0)
|
||
|
and choosing the offset 400h (1024).
|
||
|
|
||
|
|
||
|
\S{protocol-sector-iniload-signatures} Signatures
|
||
|
|
||
|
At offset 1020 (3FCh) there is the signature \cq{lD}.
|
||
|
Behind that there are two bytes with printable non-blank ASCII codepoints.
|
||
|
Currently the following signatures are defined:
|
||
|
|
||
|
\dt \cq{lDOS}
|
||
|
|
||
|
\dd lDOS kernel (not yet in use)
|
||
|
|
||
|
\dt \cq{lDRx}
|
||
|
|
||
|
\dd RxDOS kernel
|
||
|
|
||
|
\dt \cq{lDFD}
|
||
|
|
||
|
\dd FreeDOS kernel wrapped in iniload (fdkernpl.asm)
|
||
|
|
||
|
\dt \cq{lDeb}
|
||
|
|
||
|
\dd lDebug
|
||
|
|
||
|
\dt \cq{lDDb}
|
||
|
|
||
|
\dd lDDebug (debuggable lDebug)
|
||
|
|
||
|
\dt \cq{lDTP}
|
||
|
|
||
|
\dd lDOS test payload kernel (testpl.asm)
|
||
|
|
||
|
\dt \cq{lDTW}
|
||
|
|
||
|
\dd lDOS test result writer kernel (testwrit.asm)
|
||
|
|
||
|
|
||
|
\S{protocol-sector-iniload-lsv} Load Stack Variables (LSV)
|
||
|
|
||
|
Under this protocol, the pointer \cq{ss:bp} is passed.
|
||
|
It points to a boot sector with (E)BPB.
|
||
|
The stack pointer must be at most \cq{bp - 10h}.
|
||
|
Below the pointed to location there live the Load Stack Variables.
|
||
|
These follow this structure:
|
||
|
|
||
|
\c struc LOADSTACKVARS, -10h
|
||
|
\c lsvFirstCluster: resd 1
|
||
|
\c lsvFATSector: resd 1
|
||
|
\c lsvFATSeg: resw 1
|
||
|
\c lsvLoadSeg: resw 1
|
||
|
\c lsvDataStart: resd 1
|
||
|
\c endstruc
|
||
|
|
||
|
\dt lsvFirstCluster
|
||
|
|
||
|
\dd (FAT12, FAT16) Low word gives starting cluster of file.
|
||
|
High word uninitialised.
|
||
|
|
||
|
\dd (FAT32) Dword gives starting cluster of file.
|
||
|
|
||
|
\dd (else) Should be zero.
|
||
|
|
||
|
\dt lsvFATSector
|
||
|
|
||
|
\dd (FAT16) Low word gives loaded sector-in-FAT.
|
||
|
-1 if none loaded yet.
|
||
|
High word uninitialised.
|
||
|
|
||
|
\dd (FAT32) Dword gives loaded sector-in-FAT.
|
||
|
-1 if none loaded yet.
|
||
|
|
||
|
\dd (FAT12, else) Unused.
|
||
|
|
||
|
\dt lsvFATSeg
|
||
|
|
||
|
\dd (FAT16, FAT32) Word gives segment of FAT buffer
|
||
|
if word/dword [lsvFATSector] != -1.
|
||
|
|
||
|
\dd (FAT12) Word gives segment of FAT buffer.
|
||
|
Zero if none.
|
||
|
Otherwise, buffer holds entire FAT data, up to 6 KiB.
|
||
|
|
||
|
\dt lsvLoadSeg
|
||
|
|
||
|
\dd Word points to segment beyond last loaded paragraph.
|
||
|
Allows iniload to determine how much of it is already loaded.
|
||
|
|
||
|
\dt lsvDataStart
|
||
|
|
||
|
\dd Dword gives sector-in-partition of first cluster's data.
|
||
|
|
||
|
|
||
|
An LSV extension allows to pass a command line to the kernel.
|
||
|
The stack pointer must be at most \cq{bp - 114h} then.
|
||
|
This follows the structure like this:
|
||
|
|
||
|
\c lsvclSignature equ "CL"
|
||
|
\c lsvclBufferLength equ 256
|
||
|
\c
|
||
|
\c struc LSVCMDLINE, LOADSTACKVARS - lsvclBufferLength - 4
|
||
|
\c lsvCommandLine:
|
||
|
\c .start: resb lsvclBufferLength
|
||
|
\c .signature: resw 1
|
||
|
\c lsvExtra: resw 1
|
||
|
\c endstruc
|
||
|
|
||
|
\dt lsvCommandLine.start
|
||
|
|
||
|
\dd Command line buffer. Contains zero-terminated command line string.
|
||
|
|
||
|
\dt lsvCommandLine.signature
|
||
|
|
||
|
\dd Contains the signature value \cq{CL} if command line is given.
|
||
|
|
||
|
\dt lsvExtra
|
||
|
|
||
|
\dd Used internally by iniload.
|
||
|
Space for this must be reserved when passing a command line.
|
||
|
|
||
|
If no command line is passed then either the stack pointer
|
||
|
must be \cq{bp - 10h}, or \cq{bp - 12h}, or
|
||
|
the word in the lsvCommandLine.signature variable
|
||
|
(\cw{word [ss:bp - 14h]})
|
||
|
must not equal the string \cq{CL}.
|
||
|
|
||
|
\b dosemu2's RxDOS.3 support sets \cq{sp = bp - 10h}
|
||
|
|
||
|
\b ldosboot boot.asm (FAT12/FAT16) loader
|
||
|
uses the variable for a \q{paragraphs per sector} value
|
||
|
which is always a power of two and always below-or-equal 200h.
|
||
|
|
||
|
\b ldosboot boot32.asm (FAT32) loader
|
||
|
uses the variable for an \q{entries per sector} value
|
||
|
which is always a power of two and always below-or-equal 100h.
|
||
|
|
||
|
\b lDebug with protocol options \cw{cmdline=0 push_dpt=0}
|
||
|
sets \cq{sp = bp - 10h}
|
||
|
|
||
|
|
||
|
\H{protocol-iniload-payload} Iniload to payload protocol
|
||
|
|
||
|
The payload is loaded to an arbitrary segment.
|
||
|
The segment must be at least 60h.
|
||
|
The entire payload must be loaded.
|
||
|
The size of the payload is determined at iniload build time.
|
||
|
The entrypoint is found by applying a segment adjustment
|
||
|
and choosing an offset.
|
||
|
The segment adjustment is specified at iniload build time
|
||
|
by the numeric define \cw{_EXEC_SEGMENT} (default 0),
|
||
|
and the offset by the define \cw{_EXEC_OFFSET} (default 0).
|
||
|
|
||
|
|
||
|
\S{protocol-iniload-payload-ebpb} Extended BIO Parameter Block (EBPB)
|
||
|
|
||
|
Above the LSV, \cw{ss:bp} points to an EBPB and surrrounding boot sector.
|
||
|
Note that this is always a FAT32-style EBPB.
|
||
|
If the filesystem that is loaded from is not FAT32,
|
||
|
and is therefore FAT16 or FAT12,
|
||
|
then the FAT16/FAT12 BPBN structure is moved up.
|
||
|
It is placed where the FAT32 BPBN is usually expected.
|
||
|
In this case, the entire boot sector contents behind the BPBN
|
||
|
are also moved up by the size of the FAT32-specific fields.
|
||
|
The FAT32-specific fields are filled with zeros,
|
||
|
except for the FAT32 \q{sectors per FAT} field.
|
||
|
It is filled with the contents of the FAT16/FAT12
|
||
|
\q{sectors per FAT} field.
|
||
|
|
||
|
|
||
|
\S{protocol-iniload-payload-lsv} Load Stack Variables (LSV)
|
||
|
|
||
|
Refer to \k{protocol-sector-iniload-lsv}.
|
||
|
|
||
|
|
||
|
\S{protocol-iniload-payload-ld} Load Data 1 (LD)
|
||
|
|
||
|
Below the LSV, iniload passes the LOADDATA (1) structure.
|
||
|
|
||
|
\c struc LOADDATA, LOADSTACKVARS - 10h
|
||
|
\c ldMemoryTop: resw 1
|
||
|
\c ldLoadTop: resw 1
|
||
|
\c ldSectorSeg: resw 1
|
||
|
\c ldFATType: resb 1
|
||
|
\c ldHasLBA: resb 1
|
||
|
\c ldClusterSize: resw 1
|
||
|
\c ldParaPerSector:resw 1
|
||
|
\c ldLoadingSeg: resw 1
|
||
|
\c ldLoadUntilSeg: resw 1
|
||
|
\c endstruc
|
||
|
|
||
|
\dt ldMemoryTop
|
||
|
|
||
|
\dd Word. Segment pointer to behind usable memory.
|
||
|
Points at the first of the EBDA, RPL-reserved memory, or
|
||
|
video memory or otherwise UMA.
|
||
|
Indicates how much memory may be used by a typical kernel.
|
||
|
(lDebug detects the EBDA to move that below where it installs.)
|
||
|
|
||
|
\dt ldLoadTop
|
||
|
|
||
|
\dd Word. Segment pointer to lowest lDOS boot memory in use.
|
||
|
All memory between linear 600h and the segment indicated here
|
||
|
is usable by the payload.
|
||
|
Only the payload itself is stored in this area.
|
||
|
The other buffers, stack, and structures passed by iniload
|
||
|
must live above this segment.
|
||
|
|
||
|
\dt ldSectorSeg
|
||
|
|
||
|
\dd Word. Segment pointer to an 8 KiB transfer buffer.
|
||
|
It is insured that this buffer does not cross a 64 KiB boundary.
|
||
|
This may be needed by some disk units.
|
||
|
The buffer is not initialised to anything generally.
|
||
|
|
||
|
\dt ldFATType
|
||
|
|
||
|
\dd Byte. Indicates length of FAT entry in bits.
|
||
|
12 indicates FAT12, 16 FAT16, 32 FAT32.
|
||
|
It is planned to allow zero for non-FAT filesystems.
|
||
|
|
||
|
\dt ldHasLBA
|
||
|
|
||
|
\dd Byte. Only least significant bit used.
|
||
|
Bit on indicates LBA extensions available for the load disk unit.
|
||
|
Bit off indicates LBA extensions not available.
|
||
|
|
||
|
\dt ldClusterSize
|
||
|
|
||
|
\dd Word. Contains amount of sectors per cluster.
|
||
|
Unlike the byte field for the same purpose in the BPB,
|
||
|
this field can encode 256 (EDR-DOS compatible) without any masking.
|
||
|
May be given as zero for non-FAT filesystems.
|
||
|
|
||
|
\dt ldParaPerSector
|
||
|
|
||
|
\dd Word. Contains amount of paragraphs per sector.
|
||
|
Must be a power of two between 2 (32 B/s) and 200h (8192 B/s).
|
||
|
May be given as zero for non-FAT filesystems.
|
||
|
|
||
|
\dt ldLoadingSeg
|
||
|
|
||
|
\dd Word. Internally used by iniload.
|
||
|
Available for re-use by payload.
|
||
|
|
||
|
\dt ldLoadUntilSeg
|
||
|
|
||
|
\dd Word. Internally used by iniload.
|
||
|
Available for re-use by payload.
|
||
|
|
||
|
|
||
|
\S{protocol-iniload-payload-lcl} Load Command Line (LCL)
|
||
|
|
||
|
Below the LOADDATA structure, iniload passes the LOADCMDLINE structure.
|
||
|
|
||
|
\c lsvclBufferLength equ 256
|
||
|
\c
|
||
|
\c struc LOADCMDLINE, LOADDATA - lsvclBufferLength
|
||
|
\c ldCommandLine:
|
||
|
\c .start: resb lsvclBufferLength
|
||
|
\c endstruc
|
||
|
|
||
|
This buffer is always initialised to an ASCIZ string.
|
||
|
At most 255 bytes may be initialised to string data.
|
||
|
At most the 256th byte is a zero.
|
||
|
|
||
|
If the first word of the buffer is equal to 0FF00h,
|
||
|
that is there is an empty command line
|
||
|
the terminator of which is followed by a byte with the value 0FFh,
|
||
|
then no command line was passed to iniload.
|
||
|
Currently lDebug can pass a command line to iniload when
|
||
|
loading with its lDOS, RxDOS.2, or RxDOS.3 protocols.
|
||
|
When iniload is loaded as a Multiboot1 or Multiboot2 specification kernel,
|
||
|
it is also assumed that a command line can be passed.
|