Rework VBR
This commit is contained in:
parent
c288bbffb9
commit
1259fe14fe
3
Makefile
3
Makefile
@ -23,12 +23,13 @@ kernel.rom: kernel/*.asm kernel/*.inc lib/*.inc
|
|||||||
nasm -s -o $@ -I lib -I kernel kernel/main.asm && scripts/fix-rom.sh $@
|
nasm -s -o $@ -I lib -I kernel kernel/main.asm && scripts/fix-rom.sh $@
|
||||||
|
|
||||||
boot/%.bin: boot/%.asm lib/*.inc
|
boot/%.bin: boot/%.asm lib/*.inc
|
||||||
nasm -s -o $@ -I lib $<
|
nasm -s -o $@ -I boot -I lib $<
|
||||||
|
|
||||||
fdimage.img: boot/floppy.bin kernel.rom
|
fdimage.img: boot/floppy.bin kernel.rom
|
||||||
dd if=/dev/zero bs=512 count=$$(( $(FD_CYLINDERS) * $(FD_HEADS) * $(FD_SECTORS) )) of=$@
|
dd if=/dev/zero bs=512 count=$$(( $(FD_CYLINDERS) * $(FD_HEADS) * $(FD_SECTORS) )) of=$@
|
||||||
mformat -i $@ -t $(FD_CYLINDERS) -h $(FD_HEADS) -n $(FD_SECTORS) -B boot/floppy.bin ::
|
mformat -i $@ -t $(FD_CYLINDERS) -h $(FD_HEADS) -n $(FD_SECTORS) -B boot/floppy.bin ::
|
||||||
mcopy -i $@ kernel.rom ::kernel.rom
|
mcopy -i $@ kernel.rom ::kernel.rom
|
||||||
|
mattrib -i $@ +s ::kernel.rom
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.com *.bin *.rom *.img *.log boot/*.bin
|
rm -f *.com *.bin *.rom *.img *.log boot/*.bin
|
||||||
|
47
boot/chs.inc
Normal file
47
boot/chs.inc
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
fix_chs:
|
||||||
|
mov ah, 0x08
|
||||||
|
int 0x13
|
||||||
|
jc chs_end ; skip if function does not exist
|
||||||
|
inc dh
|
||||||
|
mov [cs:fdc.nos], dh
|
||||||
|
mov ax, cx
|
||||||
|
and ax, 0x003F
|
||||||
|
mov [cs:fdc.spt], ax ; no adjustment because sectors are 1-indexed
|
||||||
|
mov ax, cx
|
||||||
|
xchg al, ah
|
||||||
|
mov cl,6
|
||||||
|
shr ah,cl
|
||||||
|
inc ax ; convert from maximum number (0-based) to total number (1-based) of cylinders
|
||||||
|
mul word [cs:fdc.nos] ; number of tracks = number of cylinders * heads
|
||||||
|
mul word [cs:fdc.spt] ; number of sectors = number of tracks * sectors per track
|
||||||
|
mov [cs:fdc.ts], ax
|
||||||
|
jmp chs_end
|
||||||
|
|
||||||
|
; Load a single sector into memory
|
||||||
|
; Does not return on error
|
||||||
|
; in dx:ax sector number (will be trashed)
|
||||||
|
; es:bx buffer
|
||||||
|
load_sector:
|
||||||
|
push cx
|
||||||
|
div word [cs:fdc.spt] ; ax:temp = (lba / spt)
|
||||||
|
inc dx ; dx:sector = (lba % spt) + 1
|
||||||
|
mov cl, dl ; sector number
|
||||||
|
xor dx, dx
|
||||||
|
div word [cs:fdc.nos] ; ax:cylinder = (tmp / heads)
|
||||||
|
; dx:head = (tmp % heads)
|
||||||
|
mov ch, al ; cylinder number
|
||||||
|
mov dh, dl ; head number
|
||||||
|
mov dl, [cs:fdc.drv] ; driver number
|
||||||
|
mov ax, 0x0201 ; ah=0x02 al=0x01
|
||||||
|
int 0x13
|
||||||
|
jc disk_error
|
||||||
|
; return
|
||||||
|
pop cx
|
||||||
|
ret
|
||||||
|
|
||||||
|
disk_error:
|
||||||
|
xchg al, ah
|
||||||
|
call error
|
||||||
|
db "DISK ERROR", 0
|
||||||
|
|
||||||
|
chs_end:
|
260
boot/floppy.asm
260
boot/floppy.asm
@ -1,11 +1,9 @@
|
|||||||
org 0x0000
|
org 0x0000
|
||||||
|
|
||||||
fdc: ; FDC Descriptor as per ECMA-107
|
jmp 0x07C0:main
|
||||||
jmp _startup
|
|
||||||
times (0x03 - ($-$$)) nop
|
times (0x0B - ($-$$)) db 0 ; space-padded
|
||||||
.oem:
|
fdc:
|
||||||
db "2B" ; creating system identifier
|
|
||||||
times (0x0B - ($-$$)) db " " ; space-padded
|
|
||||||
.ss:
|
.ss:
|
||||||
dw 0x200 ; sector size
|
dw 0x200 ; sector size
|
||||||
.sc:
|
.sc:
|
||||||
@ -43,62 +41,99 @@ fdc: ; FDC Descriptor as per ECMA-107
|
|||||||
db "FAT12"
|
db "FAT12"
|
||||||
times (62 - ($-$$)) db " "
|
times (62 - ($-$$)) db " "
|
||||||
|
|
||||||
_startup:
|
|
||||||
xor ax, ax
|
|
||||||
; setup stack area growing down from 0x10000
|
|
||||||
mov ss, ax
|
|
||||||
mov sp, ax
|
|
||||||
; adjust CS
|
|
||||||
jmp 0x07C0:main
|
|
||||||
|
|
||||||
; non-fdc variables
|
|
||||||
rootdir:
|
|
||||||
.start:
|
|
||||||
dw 0
|
|
||||||
.length:
|
|
||||||
dw 0
|
|
||||||
|
|
||||||
main:
|
main:
|
||||||
cli
|
cli
|
||||||
|
; setup stack area growing down from directly below us
|
||||||
; backup important values
|
xor ax, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, 0x7C00
|
||||||
|
; setup base segments
|
||||||
|
mov ax, cs
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
; save initial environment
|
||||||
push bx
|
push bx
|
||||||
push cx
|
push cx
|
||||||
push dx
|
push dx
|
||||||
|
|
||||||
; setup buffer area directly at 4k
|
mov [fdc.drv], dl ; fix drive number in fdc
|
||||||
mov ax, 0x0100
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
mov [cs:fdc.drv], dl ; backup drive number
|
%include "chs.inc"
|
||||||
|
|
||||||
call fix_chs
|
mov di, 0x1000 ; loading address for roms
|
||||||
call calc_sectors
|
call search_rootdir
|
||||||
call find_first_cluster
|
|
||||||
xor bx, bx
|
|
||||||
call load_cluster
|
|
||||||
|
|
||||||
; restore important variables
|
mov ax, 0xFFFF
|
||||||
xor ax, ax
|
|
||||||
pop dx
|
|
||||||
pop cx
|
|
||||||
pop bx
|
|
||||||
mov di, [0x001A]
|
|
||||||
mov ax, [di+0x1A]
|
|
||||||
push ds
|
|
||||||
push ax
|
|
||||||
retf
|
|
||||||
call error
|
call error
|
||||||
db "ROM ERROR", 0
|
db "THING", 0
|
||||||
|
|
||||||
|
search_rootdir:
|
||||||
|
mov ax, [fdc.sf]
|
||||||
|
mul byte [fdc.fn]
|
||||||
|
add ax, [fdc.rsc]
|
||||||
|
mul word [fdc.ss]
|
||||||
|
mov si, ax ; now pointing to start of rootdir
|
||||||
|
mov cx, [fdc.rde]
|
||||||
|
jmp .start
|
||||||
|
.next:
|
||||||
|
dec cx
|
||||||
|
jz .end
|
||||||
|
add si, 0x20
|
||||||
|
.start:
|
||||||
|
call lazy_load
|
||||||
|
cmp byte [si], 0 ; end of directory
|
||||||
|
je .end
|
||||||
|
cmp byte [si], 0xe5 ; deleted entry
|
||||||
|
je .next
|
||||||
|
cmp word [si+8], 0x4F52 ; first 2 chars of extension: "RO"
|
||||||
|
jne .next
|
||||||
|
mov ax, [si+10] ; 3rd char of extension, file flags
|
||||||
|
and ax, 0x14FF ; zero out flags except directory and system
|
||||||
|
cmp ax, 0x044D ; "M" , system flag set, directory flag unset
|
||||||
|
jne .next
|
||||||
|
mov ax, [si+26]
|
||||||
|
push si
|
||||||
|
push cx
|
||||||
|
call loadrom
|
||||||
|
pop cx
|
||||||
|
pop si
|
||||||
|
jmp .next
|
||||||
|
.end:
|
||||||
|
ret
|
||||||
|
|
||||||
|
; in ax cluster number
|
||||||
|
loadrom:
|
||||||
|
call print16
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Makes sure the block starting with (or under SI) is
|
||||||
|
; already fetched from disk
|
||||||
|
; in ds:si data expected to be fetched from disk
|
||||||
|
; trashes ax, bx and dx
|
||||||
|
lazy_load:
|
||||||
|
cmp si, [max_si]
|
||||||
|
jc .end
|
||||||
|
; calculate next sector number
|
||||||
|
mov ax, [max_si]
|
||||||
|
xor dx, dx
|
||||||
|
div word [fdc.ss]
|
||||||
|
; write to es:bx
|
||||||
|
xor dx, dx
|
||||||
|
push cs
|
||||||
|
pop es
|
||||||
|
mov bx, [max_si]
|
||||||
|
call load_sector
|
||||||
|
; update max_si counter
|
||||||
|
mov ax, [max_si]
|
||||||
|
add ax, [fdc.ss]
|
||||||
|
mov [max_si], ax
|
||||||
|
; loop until requirement is satisfied
|
||||||
|
jmp lazy_load
|
||||||
|
.end:
|
||||||
|
ret
|
||||||
|
|
||||||
; Write AX, a string and bail out
|
|
||||||
; Return pointer is the string start
|
|
||||||
; String must be 0 suffixed
|
|
||||||
error:
|
error:
|
||||||
call print16
|
call print16
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
pop si
|
pop si
|
||||||
mov bx, 0x0000
|
mov bx, 0x0000
|
||||||
mov al, 0x20
|
mov al, 0x20
|
||||||
@ -112,132 +147,13 @@ error:
|
|||||||
hlt
|
hlt
|
||||||
jmp .hlt
|
jmp .hlt
|
||||||
|
|
||||||
; Read CHS data from BIOS and fix fdc values
|
|
||||||
fix_chs:
|
|
||||||
mov ah, 0x08
|
|
||||||
int 0x13
|
|
||||||
jc .end ; skip if function does not exist
|
|
||||||
inc dh
|
|
||||||
mov [cs:fdc.nos], dh
|
|
||||||
mov ax, cx
|
|
||||||
and ax, 0x003F
|
|
||||||
mov [cs:fdc.spt], ax ; no adjustment because sectors are 1-indexed
|
|
||||||
mov ax, cx
|
|
||||||
xchg al, ah
|
|
||||||
mov cl,6
|
|
||||||
shr ah,cl
|
|
||||||
inc ax ; convert from maximum number (0-based) to total number (1-based) of cylinders
|
|
||||||
mul word [cs:fdc.nos] ; number of tracks = number of cylinders * heads
|
|
||||||
mul word [cs:fdc.spt] ; number of sectors = number of tracks * sectors per track
|
|
||||||
mov [cs:fdc.ts], ax
|
|
||||||
.end:
|
|
||||||
ret
|
|
||||||
|
|
||||||
calc_sectors:
|
|
||||||
mov bx, [cs:fdc.ss] ; bytes per sector
|
|
||||||
mov cl, 5
|
|
||||||
shr bx, cl ; div by 2^5, 32 bytes per entry
|
|
||||||
mov ax, [cs:fdc.rde] ; number of entries
|
|
||||||
xor dx, dx
|
|
||||||
div bx
|
|
||||||
mov [cs:rootdir.length], ax
|
|
||||||
mov ax, [cs:fdc.sf] ; sectors per fat
|
|
||||||
mul byte [cs:fdc.fn] ; number of fats
|
|
||||||
add ax, [cs:fdc.rsc] ; reserved sectors
|
|
||||||
mov [cs:rootdir.start], ax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Load the root directory
|
|
||||||
find_first_cluster:
|
|
||||||
mov ax, [cs:rootdir.start]
|
|
||||||
mov cx, [cs:rootdir.length]
|
|
||||||
xor bx, bx
|
|
||||||
.blkloop:
|
|
||||||
call loadblk
|
|
||||||
add bx, [cs:fdc.ss]
|
|
||||||
add ax, 1
|
|
||||||
loop .blkloop
|
|
||||||
push cs
|
|
||||||
pop es
|
|
||||||
mov cx, [cs:fdc.rde]
|
|
||||||
xor bx, bx
|
|
||||||
.dirloop:
|
|
||||||
push cx
|
|
||||||
mov cx, 0x000B
|
|
||||||
mov si, bx
|
|
||||||
mov di, bootfilename
|
|
||||||
repe cmpsb
|
|
||||||
pop cx
|
|
||||||
jz .found
|
|
||||||
add bx, 0x0020 ; 32 bytes per directory entry
|
|
||||||
loop .dirloop
|
|
||||||
call error
|
|
||||||
db "NOT FOUND", 0
|
|
||||||
.found:
|
|
||||||
push ds
|
|
||||||
pop es
|
|
||||||
add bx, 26
|
|
||||||
mov ax, [bx]
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Load a single FAT cluster into memory
|
|
||||||
; in ax cluster number
|
|
||||||
; es:bx buffer
|
|
||||||
;
|
|
||||||
load_cluster:
|
|
||||||
xor ch, ch
|
|
||||||
mov cl, [cs:fdc.sc] ; sectors per cluster
|
|
||||||
xor dx, dx
|
|
||||||
dec ax ; somehow 2 is first cluster
|
|
||||||
div word cx
|
|
||||||
add ax, [cs:rootdir.start]
|
|
||||||
add ax, [cs:rootdir.length]
|
|
||||||
.loop:
|
|
||||||
call loadblk
|
|
||||||
inc ax
|
|
||||||
add bx, [cs:fdc.ss]
|
|
||||||
loop .loop
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Load a single block into memory
|
|
||||||
; Does not return on error
|
|
||||||
; in ax sector number
|
|
||||||
; es:bx buffer
|
|
||||||
loadblk:
|
|
||||||
push ax
|
|
||||||
push cx
|
|
||||||
push dx
|
|
||||||
xor dx, dx
|
|
||||||
div word [cs:fdc.spt] ; ax:temp = (lba / spt)
|
|
||||||
inc dx ; dx:sector = (lba % spt) + 1
|
|
||||||
mov cl, dl ; sector number
|
|
||||||
xor dx, dx
|
|
||||||
div word [cs:fdc.nos] ; ax:cylinder = (tmp / heads)
|
|
||||||
; dx:head = (tmp % heads)
|
|
||||||
mov ch, al ; cylinder number
|
|
||||||
mov dh, dl ; head number
|
|
||||||
mov dl, [cs:fdc.drv] ; driver number
|
|
||||||
mov ax, 0x0201 ; ah=0x02 al=0x01
|
|
||||||
int 0x13
|
|
||||||
jc .error
|
|
||||||
pop dx
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
ret
|
|
||||||
.error:
|
|
||||||
xchg al, ah
|
|
||||||
call error
|
|
||||||
db "DISK ERROR", 0
|
|
||||||
|
|
||||||
%include "print.asm"
|
%include "print.asm"
|
||||||
|
|
||||||
times (0x1F0 - ($-$$)) db 0
|
times (0x1FA - ($-$$)) db 0
|
||||||
|
|
||||||
bootfilename:
|
dw 0x2B2B
|
||||||
db "KERNEL"
|
|
||||||
times (0x1F8 - ($-$$)) db " "
|
|
||||||
db "ROM"
|
|
||||||
|
|
||||||
times (0x1FE - ($-$$)) db 0
|
max_si:
|
||||||
|
dw 0x200
|
||||||
|
|
||||||
dw 0xAA55
|
dw 0xAA55
|
||||||
|
Loading…
Reference in New Issue
Block a user