Advance on bootloader: load cluster data

This commit is contained in:
Nero 2020-03-25 21:19:40 +00:00
parent c51dca9949
commit 76880e9275
3 changed files with 87 additions and 10 deletions

View File

@ -1,7 +1,7 @@
FLOPPY = 360 FLOPPY = 360
PROGRAMS = hello.com PROGRAMS = hello.com
DISTFILES = $(PROGRAMS) rdos86.bs DISTFILES = $(PROGRAMS) kernel.bs
ROMS = ROMS =
QEMU_ARCH = $(shell uname -m) QEMU_ARCH = $(shell uname -m)

View File

@ -1,9 +1,12 @@
; Bootsector for FAT32 filesystems ; Bootsector for FAT32 filesystems
org 0x0800 org 0x0800
jmp near init jmp short init
nop
; WORD reserved sector count ; WORD reserved sector count
rsc: equ ( $$ + 0x00E ) rsc: equ ( $$ + 0x00E )
; BYTE number of sectors per cluster
sc: equ ( $$ + 0x00D )
; BYTE number of FATs ; BYTE number of FATs
fn: equ ( $$ + 0x010 ) fn: equ ( $$ + 0x010 )
; DWORD hidden sector count (partition offset) ; DWORD hidden sector count (partition offset)
@ -53,6 +56,7 @@ read: pop bp
mov dl, 0x80 mov dl, 0x80
mov si, sp mov si, sp
mov di, [si+4]
int 0x13 int 0x13
jc err jc err
@ -61,31 +65,33 @@ read: pop bp
push bp push bp
ret ret
; Advances cluster number to next entry ; Advances [clus] to next FAT entry
next: ; Upper two words for sector num next: ; push upper two words for sector num
xor ax, ax xor ax, ax
push ax push ax
push ax push ax
; Lower two words for sector num ; get current cluster number
mov ax, [clus] mov ax, [clus]
mov dx, [clus+2] mov dx, [clus+2]
; 32-bit >> 7 ; shift 2 left for dword-sized FAT entries
; shift 9 right for sector size
mov cl, 7 mov cl, 7
shftl: clc shftl: clc
rcr dx, 1 rcr dx, 1
rcr ax, 1 rcr ax, 1
loop shftl loop shftl
; Add reserved sector count ; add reserved sector count
add ax, word [rsc] add ax, word [rsc]
adc dx, 0 adc dx, 0
; push lower dword of sector number
push dx push dx
push ax push ax
; target buffer ; push ptr to target buffer
push cs push cs
mov ax, buf mov ax, buf
push ax push ax
@ -93,13 +99,16 @@ shftl: clc
mov cx, 1 mov cx, 1
call read call read
; Stow off offset in FAT sector ; get lower part of cluster number
mov si, [clus] mov si, [clus]
; multiply with 4
sal si, 1 sal si, 1
sal si, 1 sal si, 1
; make sure its within sector range
and si, 0x1FF and si, 0x1FF
add si, buf add si, buf
mov di, clus mov di, clus
; copy dword from FAT to [clus]
movsw movsw
movsw movsw
@ -107,9 +116,67 @@ shftl: clc
add sp, 12 add sp, 12
ret ret
main: call next ; reads current cluster into [dest]
readc: ; load cluster number
mov ax, [clus] mov ax, [clus]
mov dx, [clus+2] mov dx, [clus+2]
; subtract the two dummy entries from FAT start
sub ax, 2
sbb dx, 0
; convert cluster number to sector number
; this is some cheapo multiplication with 2^n
mov ch, [sc]
l02: shr cl, 1
jz l02e
clc
rcl dx, 1
rcl ax, 1
jmp l02
l02e:
; dx:ax is now sector num in data area
; get number of FATs
xor ch, ch
mov cl, byte [fn]
; add their sizes up
floop: add ax, [sf]
adc dx, [sf+2]
loop floop
; add reserved sector count
add ax, [rsc]
add dx, 0
; push sector num QWORD
xor cx, cx
push cx
push cx
push dx
push ax
; push target buffer DWORD
; dest gives the segment register
mov ax, [dest]
push ax
push cx
; push sector count
; always an full cluster
mov cx, [sc]
xor ch, ch
call read
cmp cl, [sc]
jne err
add sp, 12
ret
main: call readc
int 3 int 3
xor ah,ah xor ah,ah
@ -117,7 +184,17 @@ main: call next
int 0x19 int 0x19
jmp hlt jmp hlt
; the packing is so that it looks nice in a hexdump
times (0x1E0 - ($-$$)) db 0
; directory the kernel is in
tdir: db "RDOS "
; current cluster number
clus: dd 2 clus: dd 2
times (0x1F0 - ($-$$)) db 0
; filename for hte kernel
tfile: db "KERNEL BS "
; segment register for data
dest: dw 0x07c0
; Padding and signature ; Padding and signature
times (0x1FE - ($-$$)) db 0 times (0x1FE - ($-$$)) db 0