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: ; Memory layout:
; 060:0000 PSP for loaded program %define mbr 0x00600 ; 1 sector
; 060:0100 Loaded program %define self 0x00800 ; 1 sector
; 060:7800 Our code (= 0:7C00) %define fattab 0x01000 ; variable size
; 060:8000 FAT table %define rootdir 0x06000 ; variable size
; 060:E000 Root directory %define psp 0x07B00 ; 0x100 bytes
; 060:FF00 Stack area %define prog 0x07C00 ; 64k - psp
init: org self
jmp 0x060:main
times (0x0B - ($-$$)) db 0
fdc: fdc:
.jmp:
jmp short main
times (0x0B - ($-$$)) db 0
.ss: .ss:
dw 0x200 ; sector size dw 0x200 ; sector size
.sc: .sc:
@ -50,6 +49,87 @@ fdc:
db "FAT12" db "FAT12"
times (62 - ($-$$)) db " " 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 ; Read sectors from disk
; Does not return on error ; Does not return on error
; ax and bx will be incremented, cx decremented ; ax and bx will be incremented, cx decremented
@ -99,7 +179,7 @@ load_sectors:
; Load the file in [filename] ; Load the file in [filename]
; or exit with carry set ; or exit with carry set
load_file: load_file:
mov si, 0xE000 mov si, rootdir
mov cx, [fdc.rde] mov cx, [fdc.rde]
.loop: .loop:
call file_match call file_match
@ -127,7 +207,7 @@ file_match:
read_clusters: read_clusters:
add si, 0x1A add si, 0x1A
lodsw lodsw
mov bx, 0x0100 mov bx, prog
.loop: .loop:
; read cluster into area for target file ; read cluster into area for target file
push ax push ax
@ -144,7 +224,7 @@ read_clusters:
mov si, ax mov si, ax
shr si, 1 shr si, 1
add si, ax add si, ax
add si, 0x8000 add si, fattab
; load entry from FAT, truncate to 12 bit ; load entry from FAT, truncate to 12 bit
mov dx, [si] mov dx, [si]
@ -161,76 +241,6 @@ read_clusters:
ret 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: error:
mov ax, bp mov ax, bp
mov ah, 0x0e mov ah, 0x0e
@ -245,8 +255,6 @@ error:
cluster_offset: cluster_offset:
dw 0 dw 0
times (0x174 - ($-$$)) db 0
filename: filename:
db "KERNEL COM" db "KERNEL COM"