kernel: implement diskio using drive table
This commit is contained in:
parent
4a294ee21c
commit
f0a000b7d1
@ -39,17 +39,18 @@ intlp: movsw
|
|||||||
stosw
|
stosw
|
||||||
loop intlp
|
loop intlp
|
||||||
|
|
||||||
; file descriptor 0 = CON
|
|
||||||
mov word [fd_table], con_ftab
|
|
||||||
|
|
||||||
; print banner
|
|
||||||
mov dx, banner
|
|
||||||
mov cx, 13
|
|
||||||
mov bx, 0
|
|
||||||
call fd_write
|
|
||||||
|
|
||||||
call drives_init
|
call drives_init
|
||||||
|
|
||||||
|
mov dl, 0
|
||||||
|
call drive_select
|
||||||
|
xor ax, ax
|
||||||
|
xor dx, dx
|
||||||
|
call drive_seek
|
||||||
|
call drive_read
|
||||||
|
mov ax, [diskbuf+0x1FE]
|
||||||
|
int 3
|
||||||
|
|
||||||
loop: int 0x28
|
loop: int 0x28
|
||||||
jmp loop
|
jmp loop
|
||||||
|
|
||||||
@ -235,12 +236,7 @@ fputc: push ax
|
|||||||
pop ax
|
pop ax
|
||||||
iret
|
iret
|
||||||
|
|
||||||
%include "kernel/fd.asm"
|
|
||||||
%include "kernel/con.asm"
|
|
||||||
|
|
||||||
%include "kernel/drive.asm"
|
%include "kernel/drive.asm"
|
||||||
%include "kernel/diskio.asm"
|
|
||||||
%include "kernel/fat.asm"
|
|
||||||
|
|
||||||
zero: dw 0
|
zero: dw 0
|
||||||
|
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
con_ftab: dw con_read
|
|
||||||
dw con_write
|
|
||||||
|
|
||||||
con_read: stc
|
|
||||||
ret
|
|
||||||
|
|
||||||
con_write: push si
|
|
||||||
push bx
|
|
||||||
push cx
|
|
||||||
test cx, cx
|
|
||||||
jz .end
|
|
||||||
mov si, dx
|
|
||||||
mov ah, 0x0E
|
|
||||||
xor bx, bx
|
|
||||||
.loop: lodsb
|
|
||||||
int 0x10
|
|
||||||
loop .loop
|
|
||||||
pop cx
|
|
||||||
.end: pop bx
|
|
||||||
pop si
|
|
||||||
ret
|
|
||||||
|
|
@ -1,192 +0,0 @@
|
|||||||
section .bss
|
|
||||||
|
|
||||||
disk_buffer:
|
|
||||||
resb 512
|
|
||||||
|
|
||||||
disk_current:
|
|
||||||
resb 1
|
|
||||||
|
|
||||||
lba_supported:
|
|
||||||
resb 1
|
|
||||||
|
|
||||||
; Seek state and geometry info for CHS access
|
|
||||||
disk_chs: ; DL, DH, CL, CH for int 13h CHS functions
|
|
||||||
resb 4
|
|
||||||
disk_spc: ; sectors per cylinder = heads * spt
|
|
||||||
resw 1
|
|
||||||
disk_spt:
|
|
||||||
resb 1
|
|
||||||
|
|
||||||
; Partition conf from MBR or dummy for floppies
|
|
||||||
part_offset:
|
|
||||||
resd 1
|
|
||||||
part_size:
|
|
||||||
resd 1
|
|
||||||
|
|
||||||
dap: ; Disk access packet for EBIOS extensions
|
|
||||||
resw 1
|
|
||||||
dap_sectors:
|
|
||||||
resw 1
|
|
||||||
dap_buffer:
|
|
||||||
resd 1
|
|
||||||
dap_sector:
|
|
||||||
resq 1
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
; Convert between drive number and BIOS dl
|
|
||||||
; Bidirectional mapping
|
|
||||||
; 0 <-> 0, 1 <-> 1, 2 <-> 0x80, 3 <-> 0x81
|
|
||||||
dnconv: mov cx, 7
|
|
||||||
ror dx, 1
|
|
||||||
rol dl, 1
|
|
||||||
dncl: rcl dl, 1
|
|
||||||
rcr dh, 1
|
|
||||||
loop dncl
|
|
||||||
xchg dh, dl
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Select a drive for I/O
|
|
||||||
; This leave the first sector of the partition in the buffer
|
|
||||||
; IN dl 0=A, 1=B, 2=C, 3=D
|
|
||||||
select: mov byte [disk_current], 0xFF
|
|
||||||
mov byte [lba_supported], 0
|
|
||||||
call dnconv
|
|
||||||
mov byte [disk_chs], dl
|
|
||||||
cmp dl, 0x80
|
|
||||||
jc select_floppy
|
|
||||||
; detect EBIOS/LBA extensions
|
|
||||||
mov ah, 0x41
|
|
||||||
mov bx, 0x55AA
|
|
||||||
int 0x13
|
|
||||||
test cx, 1
|
|
||||||
jz select_hdd
|
|
||||||
cmp bx, 0xAA55
|
|
||||||
jnz select_hdd
|
|
||||||
mov byte [lba_supported], 1
|
|
||||||
jmp select_hdd
|
|
||||||
|
|
||||||
select_floppy:
|
|
||||||
push dx
|
|
||||||
call seek_zero
|
|
||||||
call read
|
|
||||||
; load disk geometry
|
|
||||||
mov ax, [disk_buffer+0x0B+bpb_spt]
|
|
||||||
mov [disk_spt], ax
|
|
||||||
mul word [disk_buffer+0x0B+bpb_nos]
|
|
||||||
mov [disk_spc], ax
|
|
||||||
; set partition size
|
|
||||||
; we dont rely on the 'total sectors' given in the BPB
|
|
||||||
; instead, we assume maximum cylinder
|
|
||||||
; 1023 is the maximum encodable for int 13h
|
|
||||||
lea di, [part_offset]
|
|
||||||
xor ax, ax
|
|
||||||
; partition offset = 0
|
|
||||||
stosw
|
|
||||||
stosw
|
|
||||||
; partition size = 0x00010000 = 32MB
|
|
||||||
stosw
|
|
||||||
inc ax
|
|
||||||
stosw
|
|
||||||
|
|
||||||
pop dx
|
|
||||||
ret
|
|
||||||
|
|
||||||
select_hdd:
|
|
||||||
push dx
|
|
||||||
; load CHS geometry for drive
|
|
||||||
mov ah, 0x8
|
|
||||||
int 0x13
|
|
||||||
xor ah, ah
|
|
||||||
mov al, cl
|
|
||||||
mov [disk_spt], ax
|
|
||||||
mul byte dh
|
|
||||||
mov [disk_spc], ax
|
|
||||||
; load offset and size of first partition
|
|
||||||
call seek_zero
|
|
||||||
call read
|
|
||||||
mov bx, disk_buffer+0x1BE
|
|
||||||
lea si, [bx+8]
|
|
||||||
lea di, [part_offset]
|
|
||||||
mov cx, 4
|
|
||||||
rep movsw
|
|
||||||
; read bpb
|
|
||||||
mov dx, [part_offset+2]
|
|
||||||
mov ax, [part_offset]
|
|
||||||
call seek
|
|
||||||
call read
|
|
||||||
pop dx
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Set absolute sector number
|
|
||||||
; IN dx:ax 32-bit sector number
|
|
||||||
seek: push ax
|
|
||||||
or ax, dx
|
|
||||||
pop ax
|
|
||||||
jz seek_zero
|
|
||||||
|
|
||||||
test byte [lba_supported], 1
|
|
||||||
jnz seek_lba
|
|
||||||
|
|
||||||
; dx:ax = lba
|
|
||||||
div word [disk_spc]
|
|
||||||
xchg ax, dx
|
|
||||||
; dx = cylinder, ax = head * spt + sector
|
|
||||||
div byte [disk_spt]
|
|
||||||
; dx = cylinder, al = head, ah = sector
|
|
||||||
xchg dl, dh
|
|
||||||
ror dl, 1
|
|
||||||
ror dl, 1
|
|
||||||
or dl, ah
|
|
||||||
inc dx
|
|
||||||
; dh bit 0-7: cylinder 0-7
|
|
||||||
; dl bit 0-5: sector number 0-5
|
|
||||||
; dl bit 6-7: cylinder 8-9
|
|
||||||
; store
|
|
||||||
mov byte [disk_chs+1], al
|
|
||||||
mov word [disk_chs+2], dx
|
|
||||||
ret
|
|
||||||
|
|
||||||
seek_zero:
|
|
||||||
; set chs data to first sector
|
|
||||||
mov byte [disk_chs+1], 0
|
|
||||||
mov word [disk_chs+2], 1
|
|
||||||
; set lba data to first sector
|
|
||||||
xor ax, ax
|
|
||||||
xor dx, dx
|
|
||||||
seek_lba:
|
|
||||||
mov word [dap], 0x10
|
|
||||||
mov word [dap_sectors], 1
|
|
||||||
mov word [dap_buffer], disk_buffer
|
|
||||||
mov [dap_buffer+2], cs
|
|
||||||
lea di, [dap_sector]
|
|
||||||
stosw
|
|
||||||
mov ax, dx
|
|
||||||
stosw
|
|
||||||
xor ax, ax
|
|
||||||
stosw
|
|
||||||
stosw
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Read a sector into buffer
|
|
||||||
read: test byte [lba_supported], 1
|
|
||||||
jnz read_lba
|
|
||||||
mov ax, 0x0201
|
|
||||||
mov dx, [disk_chs]
|
|
||||||
mov cx, [disk_chs+2]
|
|
||||||
lea bx, [disk_buffer]
|
|
||||||
push cs
|
|
||||||
pop es
|
|
||||||
int 0x13
|
|
||||||
ret
|
|
||||||
|
|
||||||
read_lba:
|
|
||||||
mov ah, 0x42
|
|
||||||
mov dl, [disk_chs]
|
|
||||||
lea si, [dap]
|
|
||||||
int 0x13
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Write a sector into buffer
|
|
||||||
write: stc
|
|
||||||
ret
|
|
@ -16,6 +16,13 @@ drive_ptr: resw 1
|
|||||||
|
|
||||||
drive_table: resb (drives * drive_size)
|
drive_table: resb (drives * drive_size)
|
||||||
|
|
||||||
|
; DX and CX for int 13 CHS access
|
||||||
|
chs_dx: resw 1
|
||||||
|
chs_cx: resw 1
|
||||||
|
|
||||||
|
; disk buffer for I/O operations
|
||||||
|
diskbuf: resb 1024
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
drives_init: ; CX = number of floppy drives in the system
|
drives_init: ; CX = number of floppy drives in the system
|
||||||
@ -32,6 +39,7 @@ drives_init: ; CX = number of floppy drives in the system
|
|||||||
.loop: push cx
|
.loop: push cx
|
||||||
push dx
|
push dx
|
||||||
mov [bx+drive.biosnum], dl
|
mov [bx+drive.biosnum], dl
|
||||||
|
mov byte [bx+drive.flag], 1 ; 1 = drive letter used
|
||||||
; query bios for floppy format
|
; query bios for floppy format
|
||||||
mov ah, 8
|
mov ah, 8
|
||||||
push bx
|
push bx
|
||||||
@ -82,3 +90,79 @@ drives_init: ; CX = number of floppy drives in the system
|
|||||||
add bx, drive_size
|
add bx, drive_size
|
||||||
loop .loop
|
loop .loop
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; select drive
|
||||||
|
; IN dl drive number
|
||||||
|
drive_select: xor dh, dh
|
||||||
|
mov ax, drive_size
|
||||||
|
mul dx
|
||||||
|
add ax, drive_table
|
||||||
|
mov word [drive_ptr], ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; reset currently selected drive
|
||||||
|
drive_reset: mov bx, [drive_ptr]
|
||||||
|
mov dl, [bx+drive.biosnum]
|
||||||
|
; our ptr = CX:BX
|
||||||
|
lea bx, [bx+drive.dpt]
|
||||||
|
mov cx, ds
|
||||||
|
; toggle in our ptr
|
||||||
|
mov si, [0x1E*4]
|
||||||
|
xchg bx, [si]
|
||||||
|
xchg cx, [si+2]
|
||||||
|
; do the call
|
||||||
|
xor ax, ax
|
||||||
|
int 0x13
|
||||||
|
pushf
|
||||||
|
; restore original ptr
|
||||||
|
xchg bx, [si]
|
||||||
|
xchg cx, [si+2]
|
||||||
|
; pass int 13 flags
|
||||||
|
popf
|
||||||
|
ret
|
||||||
|
|
||||||
|
; query status of selected drive
|
||||||
|
; OUT ah
|
||||||
|
drive_status: mov bx, [drive_ptr]
|
||||||
|
mov dl, [bx+drive.biosnum]
|
||||||
|
mov ah, 1
|
||||||
|
int 0x13
|
||||||
|
ret
|
||||||
|
|
||||||
|
; set sector for read/write operation
|
||||||
|
; IN dx:ax 32-bit sector number
|
||||||
|
drive_seek: mov bx, [drive_ptr]
|
||||||
|
div word [bx+drive.spc]
|
||||||
|
xchg ax, dx
|
||||||
|
; dx = cylinder, ax = head * spt + sector
|
||||||
|
div byte [bx+drive.dpt+dpt.lastsector]
|
||||||
|
; dx = cylinder, al = head, ah = sector
|
||||||
|
xchg dl, dh
|
||||||
|
ror dl, 1
|
||||||
|
ror dl, 1
|
||||||
|
or dl, ah
|
||||||
|
inc dx
|
||||||
|
; al: head number
|
||||||
|
; dh bit 0-7: cylinder bits 0-7
|
||||||
|
; dl bit 0-5: sector bits 0-5
|
||||||
|
; dl bit 6-7: cylinder bits 8-9
|
||||||
|
xchg al, ah
|
||||||
|
mov al, [bx+drive.biosnum]
|
||||||
|
; store
|
||||||
|
mov word [chs_dx], ax
|
||||||
|
mov word [chs_cx], dx
|
||||||
|
ret
|
||||||
|
|
||||||
|
drive_read: mov ax, 0x0201
|
||||||
|
mov cx, [chs_cx]
|
||||||
|
mov dx, [chs_dx]
|
||||||
|
mov bx, diskbuf
|
||||||
|
int 0x13
|
||||||
|
ret
|
||||||
|
|
||||||
|
drive_write: mov ah, 0x0301
|
||||||
|
mov cx, [chs_cx]
|
||||||
|
mov dx, [chs_dx]
|
||||||
|
mov bx, diskbuf
|
||||||
|
int 0x13
|
||||||
|
ret
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
%define fd_num 32
|
|
||||||
|
|
||||||
section .bss
|
|
||||||
|
|
||||||
fd_table: resb (0x10 * fd_num)
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
fd_to_ptr: push cx
|
|
||||||
mov cl, 4
|
|
||||||
sal bx, cl
|
|
||||||
add bx, fd_table
|
|
||||||
pop cx
|
|
||||||
ret
|
|
||||||
|
|
||||||
fd_read: cmp bx, fd_num
|
|
||||||
jnc fd_inv_hnd
|
|
||||||
call fd_to_ptr
|
|
||||||
; read ptr to ftab
|
|
||||||
mov bx, [bx]
|
|
||||||
; jmp to addr in ftab[0]
|
|
||||||
jmp [bx]
|
|
||||||
|
|
||||||
fd_write: cmp bx, fd_num
|
|
||||||
jnc fd_inv_hnd
|
|
||||||
call fd_to_ptr
|
|
||||||
mov bx, [bx]
|
|
||||||
jmp [bx+2]
|
|
||||||
|
|
||||||
fd_inv_hnd: mov ax, 6
|
|
||||||
stc
|
|
||||||
ret
|
|
Loading…
Reference in New Issue
Block a user