Rework bootloader to have adjustable memory layout

This commit is contained in:
Nero 2019-09-14 13:17:44 +00:00
parent 83d6b76ed5
commit 4c9086e365

View File

@ -1,18 +1,17 @@
org 0x7600
; Memory layout:
; 060:0000 PSP for loaded program
; 060:0100 Loaded program
; 060:7800 Our code (= 0:7C00)
; 060:8000 FAT table
; 060:E000 Root directory
; 060:FF00 Stack area
%define mbr 0x00600 ; 1 sector
%define self 0x00800 ; 1 sector
%define fattab 0x01000 ; variable size
%define rootdir 0x06000 ; variable size
%define psp 0x07B00 ; 0x100 bytes
%define prog 0x07C00 ; 64k - psp
init:
jmp 0x060:main
org self
times (0x0B - ($-$$)) db 0
fdc:
.jmp:
jmp short main
times (0x0B - ($-$$)) db 0
.ss:
dw 0x200 ; sector size
.sc:
@ -50,6 +49,87 @@ fdc:
db "FAT12"
times (62 - ($-$$)) db " "
main:
cli
; Stack grows down from PSP + 64k
mov ax, (psp >> 4)
mov ss, ax
xor sp, sp
; Relocate from [prog] to [self]
xor ax, ax
mov ds, ax
mov es, ax
mov si, prog
mov di, self
mov cx, 0x100
rep movsw
; Jump into relocated code
jmp 0:.relocated
.relocated:
mov [fdc.drv], dl ; save drive number in fd
sti
; load fat table into memory
mov ax, [fdc.rsc]
mov cx, [fdc.sf]
xor dx, dx
mov bx, fattab
call load_sectors
; calculate length of rootdir
mov ax, [fdc.rde]
mov cl, 4
shr ax, cl ; 32 bytes per entry
mov cx, ax
; load root dir
xor dx, dx
mov ax, [fdc.sf]
mul byte [fdc.fn]
add ax, [fdc.rsc]
mov bx, rootdir
call load_sectors
; remember where we left off
; clusters start after rootdir
mov [cluster_offset], ax
call load_file
mov bp, 0x0032
jc error
; get length of arguments
mov cx, 0x007F
mov di, arguments
xor ax, ax
repne scasb
dec di
sub di, arguments
mov cx, di
; setup arguments field
mov [psp+0x080], cl
mov di, 0x081
mov si, arguments
rep movsb
mov BYTE [di], 0x0D
; setup int 19h call at 0000, and push its address to stack
mov WORD [psp], 0x19CD
push sp
; clear out registers and jump into target
xor ax, ax
xor cx, cx
xor dx, dx
xor bx, bx
mov dl, [fdc.drv]
jmp 0x07B0:0x0100
; Read sectors from disk
; Does not return on error
; ax and bx will be incremented, cx decremented
@ -99,7 +179,7 @@ load_sectors:
; Load the file in [filename]
; or exit with carry set
load_file:
mov si, 0xE000
mov si, rootdir
mov cx, [fdc.rde]
.loop:
call file_match
@ -127,7 +207,7 @@ file_match:
read_clusters:
add si, 0x1A
lodsw
mov bx, 0x0100
mov bx, prog
.loop:
; read cluster into area for target file
push ax
@ -144,7 +224,7 @@ read_clusters:
mov si, ax
shr si, 1
add si, ax
add si, 0x8000
add si, fattab
; load entry from FAT, truncate to 12 bit
mov dx, [si]
@ -161,76 +241,6 @@ read_clusters:
ret
main:
cli
; Everything in one segment, stack starts on top
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
xor sp, sp
mov [fdc.drv], dl ; save drive number in fdc
sti
; load fat table into memory
mov ax, [fdc.rsc]
mov cx, [fdc.sf]
xor dx, dx
mov bx, 0x8000
call load_sectors
; calculate length of rootdir
mov ax, [fdc.rde]
dec ax
mov cl, 4
shr ax, cl ; 32 bytes per entry
inc ax
mov cx, ax
; load root dir
xor dx, dx
mov ax, [fdc.sf]
mul byte [fdc.fn]
add ax, [fdc.rsc]
mov bx, 0xE000
call load_sectors
; remember where we left off
; clusters start after rootdir
mov [cluster_offset], ax
call load_file
mov bp, 0x0032
jc error
; get length of arguments
mov cx, 0x007F
mov di, arguments
xor ax, ax
repne scasb
dec di
sub di, arguments
mov cx, di
; setup arguments field
mov [0x080], cl
mov di, 0x081
mov si, arguments
rep movsb
mov BYTE [di], 0x0D
; setup int 19h call at 0000, and push its address to stack
mov WORD [0000], 0x19CD
push sp
; clear out registers and jump into target
xor ax, ax
xor cx, cx
xor dx, dx
xor bx, bx
mov dl, [fdc.drv]
jmp 0x0100
error:
mov ax, bp
mov ah, 0x0e
@ -245,8 +255,6 @@ error:
cluster_offset:
dw 0
times (0x174 - ($-$$)) db 0
filename:
db "KERNEL COM"