From f0a000b7d1b6cb9f266de6afa4929dabc477fa32 Mon Sep 17 00:00:00 2001 From: Nero <41307858+nero@users.noreply.github.com> Date: Thu, 27 Aug 2020 20:52:16 +0000 Subject: [PATCH] kernel: implement diskio using drive table --- boot/kernel.asm | 22 +++--- kernel/con.asm | 22 ------ kernel/diskio.asm | 192 ---------------------------------------------- kernel/drive.asm | 84 ++++++++++++++++++++ kernel/fd.asm | 32 -------- 5 files changed, 93 insertions(+), 259 deletions(-) delete mode 100644 kernel/con.asm delete mode 100644 kernel/diskio.asm delete mode 100644 kernel/fd.asm diff --git a/boot/kernel.asm b/boot/kernel.asm index bf7b869..3404979 100644 --- a/boot/kernel.asm +++ b/boot/kernel.asm @@ -39,17 +39,18 @@ intlp: movsw stosw 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 + 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 jmp loop @@ -235,12 +236,7 @@ fputc: push ax pop ax iret - %include "kernel/fd.asm" - %include "kernel/con.asm" - %include "kernel/drive.asm" - %include "kernel/diskio.asm" - %include "kernel/fat.asm" zero: dw 0 diff --git a/kernel/con.asm b/kernel/con.asm deleted file mode 100644 index 488174b..0000000 --- a/kernel/con.asm +++ /dev/null @@ -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 - diff --git a/kernel/diskio.asm b/kernel/diskio.asm deleted file mode 100644 index 3f344a4..0000000 --- a/kernel/diskio.asm +++ /dev/null @@ -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 diff --git a/kernel/drive.asm b/kernel/drive.asm index 947e931..bd8dd0a 100644 --- a/kernel/drive.asm +++ b/kernel/drive.asm @@ -16,6 +16,13 @@ drive_ptr: resw 1 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 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 push dx mov [bx+drive.biosnum], dl + mov byte [bx+drive.flag], 1 ; 1 = drive letter used ; query bios for floppy format mov ah, 8 push bx @@ -82,3 +90,79 @@ drives_init: ; CX = number of floppy drives in the system add bx, drive_size loop .loop 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 diff --git a/kernel/fd.asm b/kernel/fd.asm deleted file mode 100644 index b3860f1..0000000 --- a/kernel/fd.asm +++ /dev/null @@ -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