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 2022-11-07.
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).
At offset 1020 (3FCh) there is the signature ‘lD
’. Behind that there are two bytes with printable non-blank ASCII codepoints. Currently the following signatures are defined:
lDOS
’
lDRx
’
lDFD
’
lDeb
’
lDDb
’
lDbC
’
lDTP
’
lDTW
’
Under this protocol, the pointer ‘ss:bp
’ is passed. It points to a boot sector with (E)BPB. The stack pointer must be at most ‘bp - 10h
’. Below the pointed to location there live the Load Stack Variables. These follow this structure:
struc LOADSTACKVARS, -10h
lsvFirstCluster: resd 1
lsvFATSector: resd 1
lsvFATSeg: resw 1
lsvLoadSeg: resw 1
lsvDataStart: resd 1
endstruc
An LSV extension allows to pass a command line to the kernel. The stack pointer must be at most ‘bp - 114h
’ then. This follows the structure like this:
lsvclSignature equ "CL"
lsvclBufferLength equ 256
struc LSVCMDLINE, LOADSTACKVARS - lsvclBufferLength - 4
lsvCommandLine:
.start: resb lsvclBufferLength
.signature: resw 1
lsvExtra: resw 1
endstruc
CL
’ if command line is given.
If no command line is passed then either the stack pointer must be ‘bp - 10h
’, or ‘bp - 12h
’, or the word in the lsvCommandLine.signature variable (word [ss:bp - 14h]
) must not equal the string ‘CL
’.
sp = bp - 10h
’
cmdline=0 push_dpt=0
sets ‘sp = bp - 10h
’
The initial loader part that is loaded must be loaded at above or equal to linear 00600h. The FAT buffer segment (if used) must also be stored at above or equal to linear 00600h. The stack (which should extend at least 512 bytes below ‘ss:bp
’) and boot sector (pointed to by ‘ss:bp
’, at least 512 bytes length) should also be stored at above or equal to linear 00600h.
There is an additional memory area, the Low Memory Area top reservation, which should be unused by the load protocol at handoff time but be at least 20 KiB in size. It is located below the usable Low Memory Area top. That is, directly below the EBDA, RPL-reserved memory, video memory, or otherwise UMA. This area is reserved in order to facilitate initial loader operation.
None of the memory areas may overlap. This does not include the FAT buffer in case it is uninitialised.
The boot sector area may be expected to contain a valid 8.3 format (blank-padded FCB) filename behind the (E)BPB. This name should not contain blanks other than trailing in the file name portion or trailing in the file extension portion. It should consist of printable ASCII codepoints. That is, byte values between 20h and 7Eh inclusive. It should not consist of eleven times the same byte value. Additional FAT Short File Name restrictions may be assumed.
Although a loader should not depend on this for crucial operation, it may want to detect the kernel name it was presumably loaded from for informational or optional purposes. The canonical implementation of this is currently the function ‘findname
’ in the testpl.asm
test payload kernel. It is found within the ldosboot repo. This handling is based on the function of the same name in the instsect application.
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 _EXEC_SEGMENT
(default 0), and the offset by the define _EXEC_OFFSET
(default 0).
Above the LSV, 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 ‘sectors per FAT’ field. It is filled with the contents of the FAT16/FAT12 ‘sectors per FAT’ field.
Refer to section 1.1.2.
Below the LSV, iniload passes the LOADDATA (1) structure.
struc LOADDATA, LOADSTACKVARS - 10h
ldMemoryTop: resw 1
ldLoadTop: resw 1
ldSectorSeg: resw 1
ldFATType: resb 1
ldHasLBA: resb 1
ldClusterSize: resw 1
ldParaPerSector:resw 1
ldLoadingSeg: resw 1
ldLoadUntilSeg: resw 1
endstruc
Below the LOADDATA structure, iniload passes the LOADCMDLINE structure.
lsvclBufferLength equ 256
struc LOADCMDLINE, LOADDATA - lsvclBufferLength
ldCommandLine:
.start: resb lsvclBufferLength
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, RxDOS.3, or FreeDOS protocols. When iniload is loaded as a Multiboot1 or Multiboot2 specification kernel, it is also assumed that a command line can be passed.
hg e88f6a6424a3, from commit on at 2022-11-07 20:28:44 +0100
If this is in ecm's repository, you can find it at https://hg.pushbx.org/ecm/ldosboot/rev/e88f6a6424a3