Usermode can now call system functions (currently get key, gfx mode) with INT 21H, Test switch to graphics mode is done from Usermode
This commit is contained in:
parent
679eb8cf57
commit
02f03d2224
127
fault.nasm
127
fault.nasm
@ -14,6 +14,106 @@ call error_environment
|
||||
hlt
|
||||
jmp .hlt
|
||||
|
||||
extern gpf_handler_v86
|
||||
global gpfHandler
|
||||
gpfHandler:
|
||||
push eax
|
||||
push ebx
|
||||
mov bx, ds
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov word [_gpf_old_ds], bx
|
||||
pop ebx
|
||||
mov eax, dword [esp+16] ; EFLAGS
|
||||
and eax, 1 << 17 ; VM flag
|
||||
test eax, eax
|
||||
pop eax
|
||||
jnz gpf_handler_v86
|
||||
jmp gpf_handler_32
|
||||
gpf_unhandled:
|
||||
mov dword [error_screen+0x00], 0x0f000f00 | 'G' | 'P' << 16
|
||||
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16
|
||||
jmp _fault_coda
|
||||
|
||||
_gpf_old_ds: dw 0
|
||||
extern get_key
|
||||
extern task_ptr
|
||||
extern _enter_v86_internal_no_task
|
||||
extern return_prev_task
|
||||
extern v86GfxMode
|
||||
gpf_handler_32:
|
||||
push eax
|
||||
mov eax, dword [esp+8] ; EIP
|
||||
movzx eax, word [eax]
|
||||
cmp eax, 0x30CD ; int 0x30
|
||||
je .int30
|
||||
cmp eax, 0x21CD ; int 0x21
|
||||
je .int21
|
||||
jmp gpf_unhandled
|
||||
.int21:
|
||||
pop eax ; command
|
||||
cmp al, 0x00 ; get key
|
||||
jne .s1
|
||||
call get_key
|
||||
jmp .return_to_offender
|
||||
.s1: cmp al, 0x10 ; set video mode
|
||||
jne .return_to_offender
|
||||
add dword [esp+4], 2
|
||||
; add a new task
|
||||
call _gpf_create_return_task
|
||||
; now enter v86 mode
|
||||
; push args
|
||||
mov eax, v86GfxMode
|
||||
and eax, 0xffff
|
||||
push eax ; ip
|
||||
mov eax, v86GfxMode
|
||||
shr eax, 16
|
||||
push eax ; cs
|
||||
push 0xFF00 ; sp
|
||||
push 0x8000 ; ss
|
||||
jmp _enter_v86_internal_no_task ; NOT a function call
|
||||
.int30:
|
||||
pop eax ; return value
|
||||
jmp return_prev_task
|
||||
.return_to_offender:
|
||||
add dword [esp+4], 2
|
||||
push eax
|
||||
mov ax, word [_gpf_old_ds]
|
||||
mov ds, ax
|
||||
pop eax
|
||||
add esp, 4 ; error code
|
||||
iret
|
||||
|
||||
_gpf_create_return_task:
|
||||
; handler stack stored in edx
|
||||
mov edx, esp
|
||||
mov esp, dword [task_ptr]
|
||||
mov eax, [edx+20] ; ss
|
||||
push eax
|
||||
mov eax, [edx+16] ; esp
|
||||
push eax
|
||||
mov eax, [edx+12] ; eflags
|
||||
push eax
|
||||
mov eax, [edx+8] ; cs
|
||||
push eax
|
||||
mov eax, [edx+4] ; eip
|
||||
push eax
|
||||
mov ax, word [_gpf_old_ds] ; restore old ds
|
||||
mov ds, ax
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
push ebp
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov dword [task_ptr], esp ; save new task pointer
|
||||
mov esp, edx ; restore handler stack
|
||||
ret
|
||||
|
||||
global unhandled_handler
|
||||
unhandled_handler:
|
||||
mov ax, 0x10
|
||||
@ -37,33 +137,6 @@ mov dword [error_screen+0x08], 0x0f000f00 | 'T' | ':' << 16
|
||||
mov dword [error_screen+0x0C], ebx
|
||||
jmp _fault_coda
|
||||
|
||||
extern gpf_handler_v86
|
||||
global gpfHandler
|
||||
gpfHandler:
|
||||
push eax
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov eax, dword [esp+16] ; EFLAGS
|
||||
and eax, 1 << 17 ; VM flag
|
||||
test eax, eax
|
||||
pop eax
|
||||
jnz gpf_handler_v86
|
||||
jmp gpf_handler_32
|
||||
gpf_unhandled:
|
||||
mov dword [error_screen+0x00], 0x0f000f00 | 'G' | 'P' << 16
|
||||
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16
|
||||
jmp _fault_coda
|
||||
|
||||
gpf_handler_32:
|
||||
push eax
|
||||
mov eax, dword [esp+8] ; EIP
|
||||
movzx eax, word [eax]
|
||||
cmp eax, 0x30CD ; int 0x30
|
||||
jne gpf_unhandled
|
||||
pop eax ; return value
|
||||
jmp return_prev_task
|
||||
|
||||
extern return_prev_task
|
||||
|
||||
global divisionErrorHandler
|
||||
divisionErrorHandler:
|
||||
|
9
kernel.c
9
kernel.c
@ -112,7 +112,8 @@ void ensure_v86env() {
|
||||
while (d < &_ev86code)
|
||||
*d++ = *s++;
|
||||
for (int i = 0; i < 80*50; i++)
|
||||
if (!error_screen[i]) error_screen[i] = 0x0f00;
|
||||
if (!(error_screen[i] & 0xFF00))
|
||||
error_screen[i] = 0x0f00 | (error_screen[i] & 0x00FF);
|
||||
}
|
||||
|
||||
void error_environment() {
|
||||
@ -155,9 +156,7 @@ void TestV86() {
|
||||
FARPTR v86_entry = i386LinearToFp(v86Test);
|
||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
||||
}
|
||||
void TestGfx() {
|
||||
FARPTR v86_entry = i386LinearToFp(v86GfxMode);
|
||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
||||
void TestUser() {
|
||||
char *vga = jmp_usermode_test();
|
||||
for (int i = 0; i < 320; i++) {
|
||||
vga[i] = i;
|
||||
@ -304,7 +303,7 @@ void start() {
|
||||
*vga_text = (*vga_text & 0xFF00) | key;
|
||||
vga_text++;
|
||||
}
|
||||
TestGfx();
|
||||
TestUser();
|
||||
kbd_wait();
|
||||
TestDiskRead();
|
||||
kbd_wait();
|
||||
|
28
task.nasm
28
task.nasm
@ -4,6 +4,7 @@ mov ax, 0x28
|
||||
ltr ax
|
||||
ret
|
||||
|
||||
global task_ptr
|
||||
task_ptr: equ (0x310000-4)
|
||||
|
||||
; return address in EAX
|
||||
@ -49,6 +50,16 @@ mov fs, ax
|
||||
mov eax, [edx+8+16] ; es
|
||||
mov es, ax
|
||||
; SS:ESP <- return stack
|
||||
push ecx
|
||||
mov eax, [edx+32+16] ; ss
|
||||
mov ecx, [edx+20+16] ; cs
|
||||
and eax, 3
|
||||
and ecx, 3
|
||||
or eax, ecx
|
||||
pop ecx
|
||||
cmp eax, 3
|
||||
je .ret_stack
|
||||
.ret_no_stack:
|
||||
mov esp, [edx+28+16] ; esp
|
||||
mov eax, [edx+32+16] ; ss
|
||||
mov ss, ax
|
||||
@ -62,13 +73,30 @@ mov eax, [edx+12+16] ; ds
|
||||
mov ds, ax
|
||||
mov eax, ecx ; restore return value
|
||||
iret
|
||||
.ret_stack:
|
||||
mov eax, [edx+32+16] ; ss
|
||||
push eax
|
||||
mov eax, [edx+28+16] ; esp
|
||||
push eax
|
||||
mov eax, [edx+24+16] ; eflags
|
||||
push eax
|
||||
mov eax, [edx+20+16] ; cs
|
||||
push eax
|
||||
mov eax, [edx+16+16] ; eip
|
||||
push eax
|
||||
mov eax, [edx+12+16] ; ds
|
||||
mov ds, ax
|
||||
mov eax, ecx ; restore return value
|
||||
iret
|
||||
|
||||
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
|
||||
global enter_v86
|
||||
global _enter_v86_internal_no_task
|
||||
enter_v86:
|
||||
pop eax ; return address
|
||||
mov ecx, esp ; return stack
|
||||
call save_current_task
|
||||
_enter_v86_internal_no_task:
|
||||
mov ebp, esp ; save stack pointer
|
||||
push dword [ebp+0] ; ss
|
||||
push dword [ebp+4] ; esp
|
||||
|
@ -6,6 +6,10 @@ mov dword [0xb8004], 0x0f000f00 | 'e' | 'r' << 16
|
||||
mov dword [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
|
||||
mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
|
||||
mov word [0xb8010], 0x0f00 | '!'
|
||||
mov eax, 0 ; command = 00, get key
|
||||
int 0x21 ; OS call
|
||||
mov eax, 0x00030010 ; command = 10, set video mode 3
|
||||
int 0x21 ; OS call
|
||||
mov edi, 0xA0000
|
||||
xor eax, eax
|
||||
.loop:
|
||||
|
Loading…
Reference in New Issue
Block a user