From 6ba3e0c07103cc286911e9200b64a10cfd20cadc Mon Sep 17 00:00:00 2001 From: Nero <41307858+nero@users.noreply.github.com> Date: Fri, 10 Apr 2020 15:00:26 +0000 Subject: [PATCH] Implement stack switching for dos syscall entry point --- boot/kernel.asm | 109 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/boot/kernel.asm b/boot/kernel.asm index 2036007..a2873b4 100644 --- a/boot/kernel.asm +++ b/boot/kernel.asm @@ -1,4 +1,111 @@ -org 0x7C00 + cpu 8086 + org 0x7C00 +stack: equ 0x7C00 + +framsz: equ 0x300 + + jmp init + + ; Data on user stack while in kernel (5 words): + ; AX BP IP CS flags + + ; Kernel stack: + ; [frame] SP SS + ; BP-^ + ; The start of the frame is available via BP. + ; The frame is followed by a long ptr to the user stack. + + ; Main entry point +int20h: xor ah, ah +int21h: push bp + push ax + ; Test if SS=0, if it is, we assume we are already on kernel stack + mov ax, ss + test ax, ax + jz rentry + + ; Save user stack + mov ax, ss + mov [stack-2], ax + mov [stack-4], sp + + ; Set up kernel stack + xor ax, ax + mov ss, ax + mov sp, (stack-4) + + jmp scall + + ; This is like the above, except that it doesnt switch stacks. + ; The 'user' stack data is after (below on stack) the kernel frame. + ; [frame] SP SS AX BP IP CS flags + ; \-\--^ +rentry: mov ax, sp + push ss + push ax + +scall: sub sp, framsz + mov bp, sp + + call getax + int 3 + + ; Restore user stack + mov sp, [bp+framsz] + mov ax, [bp+framsz+2] + mov ss, ax + + pop ax + pop bp + iret + + ; Get AX from the user stack +getax: push ds + push si + lds si, [bp+framsz] + lodsw + pop ds + pop si + ret + +sftab: dw 0, 0, 0, 0 ; 00-03 + dw 0, 0, 0, 0 ; 04-07 + dw 0, 0, 0, 0 ; 08-0b + dw 0, 0, 0, 0 ; 0c-0f + dw 0, 0, 0, 0 ; 10-13 + dw 0, 0, 0, 0 ; 14-17 + dw 0, 0, 0, 0 ; 18-1b + dw 0, 0, 0, 0 ; 1c-1f + dw 0, 0, 0, 0 ; 20-23 + dw 0, dos25, 0, 0 ; 24-27 + dw 0, 0, 0, 0 ; 28-2b + dw 0, 0, 0, 0 ; 2c-2f + + ; DOSINT 25h: Set interrupt vector + ; IN al interrupt number + ; ds:dx entry point +dos25: + ret + +; ===== end of resident, begin of transient startup code + +init: xor ax, ax + mov ds, ax + mov es, ax + mov ax, 0x1000 + mov ss, ax + xor sp, sp + + mov ax, 0x2521 + mov dx, int21h + pushf + push cs + call int21h + mov ax, 0x2520 + mov dx, int20h + pushf + push cs + call int21h main: push cs pop ds