Use COM-based format, get bootloader working
This commit is contained in:
parent
11b4d07dc1
commit
d853b87ec7
12
Makefile
12
Makefile
@ -25,8 +25,8 @@ endif
|
|||||||
|
|
||||||
default: kernel.rom
|
default: kernel.rom
|
||||||
|
|
||||||
kernel.rom: kernel/*.asm lib/*.inc
|
kernel.com: kernel/*.asm 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
|
||||||
|
|
||||||
debug.rom: debug/*.asm lib/*.inc
|
debug.rom: debug/*.asm lib/*.inc
|
||||||
nasm -s -o $@ -I lib -I debug debug/main.asm && scripts/fix-rom.sh $@
|
nasm -s -o $@ -I lib -I debug debug/main.asm && scripts/fix-rom.sh $@
|
||||||
@ -34,11 +34,11 @@ debug.rom: debug/*.asm lib/*.inc
|
|||||||
boot/%.bin: boot/%.asm lib/*.inc
|
boot/%.bin: boot/%.asm lib/*.inc
|
||||||
nasm -s -o $@ -I boot -I lib $<
|
nasm -s -o $@ -I boot -I lib $<
|
||||||
|
|
||||||
fdimage.img: boot/floppy.bin kernel.rom
|
fdimage.img: boot/floppy.bin kernel.com
|
||||||
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.com ::kernel.com
|
||||||
mattrib -i $@ +s ::kernel.rom
|
mattrib -i $@ +s ::kernel.com
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.com *.bin *.rom *.img *.log boot/*.bin
|
rm -f *.com *.bin *.rom *.img *.log boot/*.bin
|
||||||
@ -47,7 +47,7 @@ qemu-rom: kernel.rom $(DEBUGROM)
|
|||||||
$(QEMU) $(QEMU_ARGS) -option-rom kernel.rom
|
$(QEMU) $(QEMU_ARGS) -option-rom kernel.rom
|
||||||
|
|
||||||
qemu-floppy: fdimage.img $(DEBUGROM)
|
qemu-floppy: fdimage.img $(DEBUGROM)
|
||||||
$(QEMU) $(QEMU_ARGS) -boot c -hda fdimage.img
|
$(QEMU) $(QEMU_ARGS) -boot c -fda fdimage.img
|
||||||
|
|
||||||
qemu-serial: boot/serial.bin $(DEBUGROM)
|
qemu-serial: boot/serial.bin $(DEBUGROM)
|
||||||
$(QEMU) $(QEMU_ARGS) -hda boot/serial.bin
|
$(QEMU) $(QEMU_ARGS) -hda boot/serial.bin
|
||||||
|
47
boot/chs.inc
47
boot/chs.inc
@ -1,47 +0,0 @@
|
|||||||
fix_chs:
|
|
||||||
mov ah, 0x08
|
|
||||||
int 0x13
|
|
||||||
jc chs_end ; skip if function does not exist
|
|
||||||
inc dh
|
|
||||||
mov [cs:fdc.nos], dh
|
|
||||||
push cx
|
|
||||||
and cx, 0x003F
|
|
||||||
mov [cs:fdc.spt], cx ; no adjustment because sectors are 1-indexed
|
|
||||||
pop ax
|
|
||||||
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:
|
|
289
boot/floppy.asm
289
boot/floppy.asm
@ -1,8 +1,17 @@
|
|||||||
org 0x0000
|
org 0x7600
|
||||||
|
|
||||||
jmp 0x07C0:main
|
; 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
|
||||||
|
|
||||||
times (0x0B - ($-$$)) db 0 ; space-padded
|
init:
|
||||||
|
jmp 0x060:main
|
||||||
|
|
||||||
|
times (0x0B - ($-$$)) db 0
|
||||||
fdc:
|
fdc:
|
||||||
.ss:
|
.ss:
|
||||||
dw 0x200 ; sector size
|
dw 0x200 ; sector size
|
||||||
@ -41,119 +50,207 @@ fdc:
|
|||||||
db "FAT12"
|
db "FAT12"
|
||||||
times (62 - ($-$$)) db " "
|
times (62 - ($-$$)) db " "
|
||||||
|
|
||||||
main:
|
; Read sectors from disk
|
||||||
cli
|
; Does not return on error
|
||||||
; setup stack area growing down from directly below us
|
; ax and bx will be incremented, cx decremented
|
||||||
xor ax, ax
|
; in dx:ax sector number
|
||||||
mov ss, ax
|
; es:bx buffer
|
||||||
mov sp, 0x7C00
|
; cx number of sectors to read
|
||||||
; setup base segments
|
; out dx:ax next sector to read
|
||||||
mov ax, cs
|
; es:bx next free buffer
|
||||||
mov ds, ax
|
; cx zero
|
||||||
mov es, ax
|
load_sectors:
|
||||||
; save initial environment
|
; fail instantly if reading sectors > 16 bit
|
||||||
push bx
|
test dx, dx
|
||||||
|
mov bp, 0x0030
|
||||||
|
jnz error
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
push ax
|
||||||
push cx
|
push cx
|
||||||
push dx
|
push dx
|
||||||
|
|
||||||
mov [fdc.drv], dl ; fix drive number in fdc
|
; calculate CHS data
|
||||||
|
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
|
||||||
|
mov bp, 0x0031
|
||||||
|
jc error
|
||||||
|
|
||||||
%include "chs.inc"
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop ax
|
||||||
|
|
||||||
mov di, 0x1000 ; loading address for roms
|
; count up for next sector
|
||||||
call search_rootdir
|
add bx, 0x0200
|
||||||
|
inc ax
|
||||||
|
|
||||||
mov ax, 0xFFFF
|
loop .loop
|
||||||
call error
|
ret
|
||||||
db "THING", 0
|
|
||||||
|
|
||||||
search_rootdir:
|
; Load the file in [filename]
|
||||||
|
; or exit with carry set
|
||||||
|
load_file:
|
||||||
|
mov si, 0xE000
|
||||||
|
mov cx, [fdc.rde]
|
||||||
|
.loop:
|
||||||
|
call file_match
|
||||||
|
je read_clusters
|
||||||
|
add si, 0x20
|
||||||
|
loop .loop
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Compares the FAT dirent against [filename]
|
||||||
|
; in ds:si filename
|
||||||
|
; out ZF zero flag set if equal
|
||||||
|
file_match:
|
||||||
|
push cx
|
||||||
|
push si
|
||||||
|
mov di, filename
|
||||||
|
mov cx, 11
|
||||||
|
repe cmpsb
|
||||||
|
pop si
|
||||||
|
pop cx
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Read the file given by cluster number
|
||||||
|
; into the target program area
|
||||||
|
; in ax cluster number
|
||||||
|
read_clusters:
|
||||||
|
add si, 0x1A
|
||||||
|
lodsw
|
||||||
|
mov bx, 0x0100
|
||||||
|
.loop:
|
||||||
|
; read cluster into area for target file
|
||||||
|
push ax
|
||||||
|
sub ax, 2
|
||||||
|
mul BYTE [fdc.sc]
|
||||||
|
add ax, [cluster_offset]
|
||||||
|
xor dx, dx
|
||||||
|
mov cx, [fdc.sc]
|
||||||
|
xor ch, ch
|
||||||
|
call load_sectors
|
||||||
|
pop ax
|
||||||
|
|
||||||
|
; calculate index in FAT
|
||||||
|
mov si, ax
|
||||||
|
shr si, 1
|
||||||
|
add si, ax
|
||||||
|
add si, 0x8000
|
||||||
|
|
||||||
|
; load entry from FAT, truncate to 12 bit
|
||||||
|
mov dx, [si]
|
||||||
|
test ax, 1
|
||||||
|
jz .noshift
|
||||||
|
mov cl, 4
|
||||||
|
shr dx, 4
|
||||||
|
.noshift:
|
||||||
|
mov ax, dx
|
||||||
|
|
||||||
|
and ax, 0x0FFF
|
||||||
|
cmp ax, 0x0FF8
|
||||||
|
jc .loop
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
main:
|
||||||
|
cli
|
||||||
|
; Everything in one segment, stack starts on top
|
||||||
|
mov ax, cs
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, ax
|
||||||
|
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]
|
mov ax, [fdc.sf]
|
||||||
mul byte [fdc.fn]
|
mul byte [fdc.fn]
|
||||||
add ax, [fdc.rsc]
|
add ax, [fdc.rsc]
|
||||||
mul word [fdc.ss]
|
mov bx, 0xE000
|
||||||
mov si, ax ; now pointing to start of rootdir
|
call load_sectors
|
||||||
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
|
; remember where we left off
|
||||||
loadrom:
|
; clusters start after rootdir
|
||||||
call print16
|
mov [cluster_offset], ax
|
||||||
ret
|
|
||||||
|
|
||||||
; Makes sure the block starting with (or under SI) is
|
call load_file
|
||||||
; already fetched from disk
|
mov bp, 0x0032
|
||||||
; in ds:si data expected to be fetched from disk
|
jc error
|
||||||
; trashes ax, bx and dx
|
|
||||||
lazy_load:
|
; get length of arguments
|
||||||
cmp si, [max_si]
|
mov cx, 0x007F
|
||||||
jc .end
|
mov di, arguments
|
||||||
; calculate next sector number
|
xor ax, ax
|
||||||
mov ax, [max_si]
|
repe scasb
|
||||||
|
sub di, arguments
|
||||||
|
mov cx, di
|
||||||
|
|
||||||
|
; setup arguments field
|
||||||
|
mov [0x080], cl
|
||||||
|
mov di, [0x081]
|
||||||
|
mov si, arguments
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
; 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 dx, dx
|
||||||
div word [fdc.ss]
|
xor bx, bx
|
||||||
; write to es:bx
|
mov dl, [fdc.drv]
|
||||||
xor dx, dx
|
jmp 0x0100
|
||||||
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
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
call print16
|
mov ax, bp
|
||||||
pop si
|
|
||||||
mov bx, 0x0000
|
|
||||||
mov al, 0x20
|
|
||||||
.loop:
|
|
||||||
mov ah, 0x0e
|
mov ah, 0x0e
|
||||||
|
mov bx, 7
|
||||||
int 0x10
|
int 0x10
|
||||||
lodsb
|
mov al, 0x21
|
||||||
cmp al, 0x00
|
int 0x10
|
||||||
jne .loop
|
xor ax, ax
|
||||||
.hlt:
|
int 0x16
|
||||||
hlt
|
int 0x19
|
||||||
jmp .hlt
|
|
||||||
|
|
||||||
%include "print.asm"
|
cluster_offset:
|
||||||
|
dw 0
|
||||||
|
|
||||||
times (0x1FA - ($-$$)) db 0
|
times (0x175 - ($-$$)) db 0
|
||||||
|
|
||||||
dw 0x2B2B
|
filename:
|
||||||
|
db "KERNEL COM"
|
||||||
|
|
||||||
max_si:
|
arguments:
|
||||||
dw 0x200
|
db " ", 0
|
||||||
|
|
||||||
|
times (0x1FE - ($-$$)) db 0
|
||||||
|
|
||||||
dw 0xAA55
|
dw 0xAA55
|
||||||
|
@ -1,60 +1,5 @@
|
|||||||
cpu 8086
|
cpu 8086
|
||||||
org 0x0000
|
org 0x0100
|
||||||
rom:
|
|
||||||
db 0x55, 0xAA
|
|
||||||
.sectors:
|
|
||||||
db 0x00
|
|
||||||
.init:
|
|
||||||
push cs
|
|
||||||
pop es
|
|
||||||
|
|
||||||
mov di, start
|
|
||||||
mov ax, 0x18
|
|
||||||
call intr_register
|
|
||||||
|
|
||||||
retf
|
|
||||||
.name:
|
|
||||||
db "ROM DOS", 0
|
|
||||||
|
|
||||||
times (0x18 - ($-$$)) db 0
|
|
||||||
.pcir_ptr:
|
|
||||||
dw 0
|
|
||||||
|
|
||||||
times (0x1A - ($-$$)) db 0
|
|
||||||
.pnp_ptr:
|
|
||||||
dw pnp
|
|
||||||
|
|
||||||
pnp:
|
|
||||||
db "$PnP"
|
|
||||||
.version:
|
|
||||||
db 1 ; version 1
|
|
||||||
.length:
|
|
||||||
db 2 ; 2 * 16 length
|
|
||||||
dw 0 ; offset of next header
|
|
||||||
db 0
|
|
||||||
.checksum:
|
|
||||||
db 0 ; checksum (filled by fix-rom)
|
|
||||||
dd 0 ; device identifier
|
|
||||||
dw 0 ; manufacturer string
|
|
||||||
dw rom.name ; product name string
|
|
||||||
db 0,0,0 ; device type string
|
|
||||||
db 0x20 ; device indicator, bit for "read cacheable" set
|
|
||||||
dw 0 ; boot connection vector
|
|
||||||
dw 0 ; boot disconnect vector
|
|
||||||
dw start ; bootstrap entry point
|
|
||||||
dw 0 ; reserved
|
|
||||||
dw 0
|
|
||||||
|
|
||||||
start:
|
|
||||||
xor ax, ax
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov ss, ax
|
|
||||||
mov sp, 0x800
|
|
||||||
mov di, sp
|
|
||||||
|
|
||||||
call drvtab_create
|
|
||||||
|
|
||||||
push cs
|
push cs
|
||||||
pop es
|
pop es
|
||||||
mov di, isr_dos_main
|
mov di, isr_dos_main
|
||||||
@ -64,7 +9,6 @@ start:
|
|||||||
.loop:
|
.loop:
|
||||||
mov ah, 0x01
|
mov ah, 0x01
|
||||||
int 0x21
|
int 0x21
|
||||||
int3
|
|
||||||
jmp .loop
|
jmp .loop
|
||||||
|
|
||||||
cli
|
cli
|
||||||
@ -91,4 +35,4 @@ isr_return:
|
|||||||
|
|
||||||
%include "chario.asm"
|
%include "chario.asm"
|
||||||
|
|
||||||
align 512
|
times 1000 db 0xEA
|
||||||
|
Loading…
Reference in New Issue
Block a user