diff --git a/boot/kernel.asm b/boot/kernel.asm index 8d05b5a..1b37760 100644 --- a/boot/kernel.asm +++ b/boot/kernel.asm @@ -1,32 +1,18 @@ cpu 8086 - org 0x500 + org 0x7C00 %include "inc/bpb.asm" -%include "inc/dpt.asm" - -; drive table entry -struc drive -.biosnum: resb 1 -.flag: resb 1 -.spc: resw 1 -.cylinders: resw 1 -.dpt: resb dpt_size -.type: resb 1 ; 12 or 16, depending on FAT type -.fat_offset: resd 1 ; offset of fat table -.fat_num: resw 1 ; number of fat tables -.fat_size: resw 1 ; sectors per fat table - -.dir_offset: resd 1 ; offset of root directory -.dir_size: resw 1 ; size of root directory in sectors - -.clus_offset: resd 1 ; offset of clusters -.clus_num: resw 1 ; number of clusters -.clus_size: resw 1 ; sectors per cluster -endstruc +%include "inc/mbr.asm" ; kernel stack size in words %define stacksize 512 + jmp init + + times ( 0x0B - ($-$$) ) db " " + + times bpb_size db 0 + init: cli xor ax, ax mov ds, ax @@ -34,243 +20,11 @@ init: cli mov ss, ax mov sp, ( stack+stacksize ) - ; relocate - mov si, 0x7C00 - mov di, $$ - mov cx, (_end-$$) - rep movsb - - jmp 0:main - -main: ; zero out first 64kb except our code - ; bss and boot sector area gets cleared by this - mov cx, di - neg cx - xor ax, ax - rep stosb - - ; install interrupt vectors - mov si, vects - mov di, (0x20*4) - mov cx, 0x0A -intlp: movsw - mov ax, cs - stosw - loop intlp - - mov dx, banner - call puts - - 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 - -section .data - -banner: db "rdos loaded", 0xA, 0xD, '$' - -section .text - - ; Alias for Int 21h,AH=0h -int20h: xor ah, ah - jmp far [cs:0x21*4] - -int21h: ; inside of kernel, direction always goes up - ; the iret will restore it to the user value later - cld - ; set sfptr from ah - push bx - xor bx, bx - mov bl, ah - add bl, bl - add bx, sftab - mov bx, [cs:bx] - mov [cs:sfptr], bx - pop bx - ; do the actual subfunction call - call [cs:sfptr] - ; inherit the lower 8 flag bits to userspace -iretfl: push ax - push bp - mov bp, sp - lahf - mov [bp+8], ah - pop bp - pop ax - ; iret frame: IP CS FLAGS -iret: iret -retf: retf - -section .data - - ; Subfunction ptr - ; this is used as extra register in int21h -sfptr: dw 0 - - ; Subfunction table -sftab: dw sferr, getc, putc, sferr - dw sferr, sferr, conout, conin - dw sferr, puts, sferr, sferr - dw sferr, sferr, sferr, sferr - ; 10 - dw sferr, sferr, sferr, sferr - dw sferr, sferr, sferr, sferr - dw sferr, sferr, sferr, sferr - dw sferr, sferr, sferr, sferr - ; 20 - dw sferr, sferr, sferr, sferr - dw sferr, setint, sferr, sferr - dw sferr, sferr, sferr, sferr - dw sferr, sferr, sferr, sferr - ; 30 - dw sferr, sferr, sferr, sferr - dw sferr, getint, sferr, sferr - dw sferr, sferr, sferr, sferr - dw sferr, sferr, sferr, sferr - -section .text - - ; OUT al character read -getc: xor ax, ax - int 0x16 - push ax - jmp putc.2 - - ; IN dl character to write -putc: push ax - mov al, dl -.2: int 0x29 - pop ax - ret - - ; console output - ; IN dl character -conout: cmp dl, 0xFF - je conine - push ax - mov al, dl - int 0x29 - pop ax - ret - - ; console input with echo - ; OUT al character - ; zf clear when character available -conine: mov ah, 1 - int 0x16 - jnz .has - xor al, al - ret -.has: xor ax, ax - int 0x16 - test al, al - jz conine - int 0x29 - test ax, ax - ret - - ; console input without echo - ; OUT al character - ; zf clear when character available -conin: mov ah, 1 - int 0x16 - jnz .has - xor al, al - ret -.has: xor ax, ax - int 0x16 - test al, al - jz conin - test ax, ax - ret - - ; DOS 1+ 9h - WRITE STRING TO STANDARD OUTPUT - ; IN ds:dx '$'-terminated string -puts: push si - mov si, dx -.loop: lodsb - cmp al, '$' - je .end - int 0x29 - jmp .loop -.end: pop si - ret - - ; DOS 1+ 25h - SET INTERRUPT VECTOR - ; IN al interrupt number - ; ds:dx entry point -setint: push bx - xor bx, bx - ; BX=AL*4 - mov bl, al - add bl, bl - add bl, bl - ; save DS:DX into vector - mov [cs:bx], dx - mov [cs:bx+2], ds - pop bx - ret - - ; DOS 2+ 35h - GET INTERRUPT VECTOR - ; IN al interrupt number - ; OUT es:bx current interrupt handler -getint: xor bx, bx - ; BX=AL*4 - mov bl, al - add bl, bl - add bl, bl - ; load vector into ES:BX - les bx, [cs:bx] - ret - - ; Fallback for non-existant subfunctions - ; The carry flag is inherited to user -sferr: stc - ret - - ; DOS IDLE INTERRUPT - ; Usually hooked by TSRs -idle: sti - ; sti takes one instruction to take effect - nop - ; Wait until next interrupt - hlt - iret - - ; FAST CONSOLE OUTPUT - ; IN al character to print -fputc: push ax - push bx - mov ah, 0x0E - xor bx, bx - int 0x10 - pop bx - pop ax - iret - - %include "kernel/drive.asm" - %include "kernel/fat.asm" - -zero: dw 0 - -section .data - -vects: dw int20h, int21h, retf, retf - dw retf, retf, retf, int20h - dw idle, fputc - -_end: dw 0x55AA, 0x55AA +hlt: hlt + jmp hlt section .bss - ; stack to be used during init and disk i/o -stack: resw stacksize + +stack: resb stacksize diff --git a/kernel/main.asm b/kernel/main.asm new file mode 100644 index 0000000..5ab8421 --- /dev/null +++ b/kernel/main.asm @@ -0,0 +1,36 @@ + cpu 8086 + org 0x7C00 + + jmp init + +%include "kernel/fd.asm" +%include "kernel/con.asm" + +entry_int21: iret + +init: ; install int 21h handler + mov ax, cs + mov ds, ax + mov es, ax + mov word [4*0x21], entry_int21 + mov word [4*0x21+2], cs + + mov word [fd_table], con_ftab + + ; print banner + mov dx, .banner + mov cx, 13 + mov bx, 0 + call con_write + + ; execute shell + mov ax, 0x4B00 + mov dx, .shellfn + int 0x21 + +.hlt: hlt + jmp .hlt + +.banner: db "rdos kernel", 0x0A, 0x0D + +.shellfn: db "SHELL.COM", 0