mirror of
https://github.com/FDOS/kernel.git
synced 2025-04-08 17:15:17 +02:00
247 lines
5.0 KiB
NASM
247 lines
5.0 KiB
NASM
|
|
%if 0
|
|
|
|
Loader adjustment to load FreeDOS kernel
|
|
by C. Masloch, 2017
|
|
|
|
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.
|
|
|
|
%endif
|
|
|
|
|
|
%include "lmacros3.mac"
|
|
|
|
struc BS
|
|
bsJump: resb 3
|
|
bsOEM: resb 8
|
|
bsBPB:
|
|
endstruc
|
|
|
|
struc EBPB ; BPB sec
|
|
bpbBytesPerSector: resw 1 ; offset 00h 0Bh
|
|
bpbSectorsPerCluster: resb 1 ; offset 02h 0Dh
|
|
bpbReservedSectors: resw 1 ; offset 03h 0Eh
|
|
bpbNumFATs: resb 1 ; offset 05h 10h
|
|
bpbNumRootDirEnts: resw 1 ; offset 06h 11h -- 0 for FAT32
|
|
bpbTotalSectors: resw 1 ; offset 08h 13h
|
|
bpbMediaID: resb 1 ; offset 0Ah 15h
|
|
bpbSectorsPerFAT: resw 1 ; offset 0Bh 16h -- 0 for FAT32
|
|
bpbCHSSectors: resw 1 ; offset 0Dh 18h
|
|
bpbCHSHeads: resw 1 ; offset 0Fh 1Ah
|
|
bpbHiddenSectors: resd 1 ; offset 11h 1Ch
|
|
bpbTotalSectorsLarge: resd 1 ; offset 15h 20h
|
|
bpbNew: ; offset 19h 24h
|
|
|
|
ebpbSectorsPerFATLarge: resd 1 ; offset 19h 24h
|
|
ebpbFSFlags: resw 1 ; offset 1Dh 28h
|
|
ebpbFSVersion: resw 1 ; offset 1Fh 2Ah
|
|
ebpbRootCluster: resd 1 ; offset 21h 2Ch
|
|
ebpbFSINFOSector: resw 1 ; offset 25h 30h
|
|
ebpbBackupSector: resw 1 ; offset 27h 32h
|
|
ebpbReserved: resb 12 ; offset 29h 34h
|
|
ebpbNew: ; offset 35h 40h
|
|
endstruc
|
|
|
|
struc BPBN ; ofs B16 S16 B32 S32
|
|
bpbnBootUnit: resb 1 ; 00h 19h 24h 35h 40h
|
|
resb 1 ; 01h 1Ah 25h 36h 41h
|
|
bpbnExtBPBSignature: resb 1 ; 02h 1Bh 26h 37h 42h -- 29h for valid BPBN
|
|
bpbnSerialNumber: resd 1 ; 03h 1Ch 27h 38h 43h
|
|
bpbnVolumeLabel: resb 11 ; 07h 20h 2Bh 3Ch 47h
|
|
bpbnFilesystemID: resb 8 ; 12h 2Bh 36h 47h 52h
|
|
endstruc ; 1Ah 33h 3Eh 4Fh 5Ah
|
|
|
|
|
|
%ifndef _MAP
|
|
%elifempty _MAP
|
|
%else ; defined non-empty, str or non-str
|
|
[map all _MAP]
|
|
%endif
|
|
|
|
strdef PAYLOAD_FILE, "KERNEL.SYS"
|
|
|
|
|
|
struc LOADSTACKVARS, -10h
|
|
lsvFirstCluster: resd 1
|
|
lsvFATSector: resd 1
|
|
lsvFATSeg: resw 1
|
|
lsvLoadSeg: resw 1
|
|
lsvDataStart: resd 1
|
|
endstruc
|
|
|
|
|
|
lsvclSignature equ "CL"
|
|
lsvclBufferLength equ 256
|
|
|
|
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: ; word
|
|
lsvCommandLine: ; word
|
|
.start: equ $ - lsvclBufferLength
|
|
.signature: resw 1
|
|
ldLoadUntilSeg: ; word
|
|
lsvExtra: ; word
|
|
.partition: resb 1 ; byte
|
|
.flags: resb 1 ; byte
|
|
endstruc
|
|
|
|
lsvefNoDataStart equ 1
|
|
lsvefPartitionNumber equ 2
|
|
|
|
struc LOADCMDLINE, LOADDATA - lsvclBufferLength
|
|
ldCommandLine:
|
|
.start: resb lsvclBufferLength
|
|
endstruc
|
|
|
|
|
|
cpu 8086
|
|
org 0
|
|
addsection ENTRY, start=0 vstart=0
|
|
entry:
|
|
|
|
mov ax, cs
|
|
add ax, entry_size_p + payload_size_p
|
|
xor bx, bx
|
|
push ax
|
|
push bx
|
|
retf
|
|
|
|
align 16
|
|
endarea entry
|
|
|
|
|
|
addsection PAYLOAD, follows=ENTRY
|
|
payload:
|
|
realpayload:
|
|
incbin _PAYLOAD_FILE
|
|
align 16, db 38
|
|
endarea realpayload
|
|
|
|
|
|
addsection STACKRELOCATE, follows=PAYLOAD vstart=0
|
|
stackrelocate:
|
|
|
|
mov ax, 60h + payload_size_p
|
|
mov es, ax
|
|
xor di, di
|
|
xor si, si
|
|
lea cx, [ bp + 512 ]
|
|
rep movsb
|
|
mov ds, ax
|
|
mov si, bp
|
|
xor di, di
|
|
cmp word [ds:bp + ldCommandLine], 0FF00h
|
|
je @F
|
|
lea si, [bp + ldCommandLine + lsvclBufferLength - 2]
|
|
lea di, [bp + lsvCommandLine.start + lsvclBufferLength - 2]
|
|
mov cx, words(lsvclBufferLength)
|
|
%if words(lsvclBufferLength) <= 20
|
|
%error AMD erratum 109 workaround needed
|
|
%endif
|
|
std
|
|
rep movsw
|
|
cld
|
|
lea si, [bp + lsvCommandLine.start]
|
|
mov di, lsvclSignature
|
|
@@:
|
|
cli
|
|
mov ss, ax
|
|
mov sp, si
|
|
mov word [bp + lsvCommandLine.signature], di
|
|
; Note that this access uses the new ss.
|
|
; Also note: If no command line is passed,
|
|
; si will equal bp. That means the word
|
|
; written here is technically below sp,
|
|
; that is it belongs to the unused stack.
|
|
; This does not cause any problems however.
|
|
; It hardens the next load stage against
|
|
; accidentally expecting a command line if
|
|
; it does not check the offsets properly.
|
|
sti
|
|
|
|
jmp 60h:0
|
|
|
|
align 16
|
|
endarea stackrelocate
|
|
|
|
payload_size equ realpayload_size + stackrelocate_size
|
|
endarea payload, 1
|
|
|
|
|
|
addsection RELOCATE, follows=STACKRELOCATE vstart=0
|
|
relocate:
|
|
mov bx, 1000h
|
|
mov ax, 60h
|
|
mov es, ax
|
|
mov cx, payload_size_p
|
|
mov ax, cs
|
|
sub ax, cx
|
|
mov ds, ax
|
|
xor si, si
|
|
xor di, di
|
|
|
|
mov ax, cx
|
|
cmp ax, bx
|
|
jbe @F
|
|
mov cx, bx
|
|
@@:
|
|
sub ax, cx
|
|
shl cx, 1
|
|
shl cx, 1
|
|
shl cx, 1
|
|
rep movsw
|
|
|
|
@@:
|
|
mov dx, es
|
|
add dx, bx
|
|
mov es, dx ; next segment
|
|
|
|
mov dx, ds
|
|
add dx, bx
|
|
mov ds, dx ; next segment
|
|
|
|
sub ax, bx ; = how much to relocate after this round
|
|
mov cx, 1000h << 3 ; in case another full 64 KiB to relocate
|
|
jae @F ; another full 64 KiB to relocate -->
|
|
add ax, bx ; restore
|
|
shl ax, 1
|
|
shl ax, 1
|
|
shl ax, 1 ; convert paragraphs to words
|
|
mov cx, ax ; that many words
|
|
xor ax, ax ; no more to relocate after this round
|
|
|
|
@@:
|
|
xor si, si
|
|
xor di, di
|
|
rep movsw ; relocate next chunk
|
|
test ax, ax ; another round needed?
|
|
jnz @BB ; yes -->
|
|
; ax = 0
|
|
|
|
mov dl, [bp + bsBPB + ebpbNew + bpbnBootUnit]
|
|
mov bl, dl
|
|
|
|
push ss
|
|
pop ds
|
|
cmp word [bp + bsBPB + bpbSectorsPerFAT], ax
|
|
je @F
|
|
push ss
|
|
pop es
|
|
lea si, [bp + bsBPB + ebpbNew]
|
|
lea di, [bp + bsBPB + bpbNew]
|
|
mov cx, (512 - bsBPB - bpbNew + 1) >> 1
|
|
rep movsw
|
|
@@:
|
|
|
|
jmp 60h + realpayload_size_p:0
|