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
|
hlt
|
||||||
jmp .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
|
global unhandled_handler
|
||||||
unhandled_handler:
|
unhandled_handler:
|
||||||
mov ax, 0x10
|
mov ax, 0x10
|
||||||
@ -37,33 +137,6 @@ mov dword [error_screen+0x08], 0x0f000f00 | 'T' | ':' << 16
|
|||||||
mov dword [error_screen+0x0C], ebx
|
mov dword [error_screen+0x0C], ebx
|
||||||
jmp _fault_coda
|
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
|
global divisionErrorHandler
|
||||||
divisionErrorHandler:
|
divisionErrorHandler:
|
||||||
|
9
kernel.c
9
kernel.c
@ -112,7 +112,8 @@ void ensure_v86env() {
|
|||||||
while (d < &_ev86code)
|
while (d < &_ev86code)
|
||||||
*d++ = *s++;
|
*d++ = *s++;
|
||||||
for (int i = 0; i < 80*50; i++)
|
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() {
|
void error_environment() {
|
||||||
@ -155,9 +156,7 @@ void TestV86() {
|
|||||||
FARPTR v86_entry = i386LinearToFp(v86Test);
|
FARPTR v86_entry = i386LinearToFp(v86Test);
|
||||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
||||||
}
|
}
|
||||||
void TestGfx() {
|
void TestUser() {
|
||||||
FARPTR v86_entry = i386LinearToFp(v86GfxMode);
|
|
||||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
|
||||||
char *vga = jmp_usermode_test();
|
char *vga = jmp_usermode_test();
|
||||||
for (int i = 0; i < 320; i++) {
|
for (int i = 0; i < 320; i++) {
|
||||||
vga[i] = i;
|
vga[i] = i;
|
||||||
@ -304,7 +303,7 @@ void start() {
|
|||||||
*vga_text = (*vga_text & 0xFF00) | key;
|
*vga_text = (*vga_text & 0xFF00) | key;
|
||||||
vga_text++;
|
vga_text++;
|
||||||
}
|
}
|
||||||
TestGfx();
|
TestUser();
|
||||||
kbd_wait();
|
kbd_wait();
|
||||||
TestDiskRead();
|
TestDiskRead();
|
||||||
kbd_wait();
|
kbd_wait();
|
||||||
|
28
task.nasm
28
task.nasm
@ -4,6 +4,7 @@ mov ax, 0x28
|
|||||||
ltr ax
|
ltr ax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
global task_ptr
|
||||||
task_ptr: equ (0x310000-4)
|
task_ptr: equ (0x310000-4)
|
||||||
|
|
||||||
; return address in EAX
|
; return address in EAX
|
||||||
@ -49,6 +50,16 @@ mov fs, ax
|
|||||||
mov eax, [edx+8+16] ; es
|
mov eax, [edx+8+16] ; es
|
||||||
mov es, ax
|
mov es, ax
|
||||||
; SS:ESP <- return stack
|
; 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 esp, [edx+28+16] ; esp
|
||||||
mov eax, [edx+32+16] ; ss
|
mov eax, [edx+32+16] ; ss
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
@ -62,13 +73,30 @@ mov eax, [edx+12+16] ; ds
|
|||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov eax, ecx ; restore return value
|
mov eax, ecx ; restore return value
|
||||||
iret
|
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);
|
; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
|
||||||
global enter_v86
|
global enter_v86
|
||||||
|
global _enter_v86_internal_no_task
|
||||||
enter_v86:
|
enter_v86:
|
||||||
pop eax ; return address
|
pop eax ; return address
|
||||||
mov ecx, esp ; return stack
|
mov ecx, esp ; return stack
|
||||||
call save_current_task
|
call save_current_task
|
||||||
|
_enter_v86_internal_no_task:
|
||||||
mov ebp, esp ; save stack pointer
|
mov ebp, esp ; save stack pointer
|
||||||
push dword [ebp+0] ; ss
|
push dword [ebp+0] ; ss
|
||||||
push dword [ebp+4] ; esp
|
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 [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
|
||||||
mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
|
mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
|
||||||
mov word [0xb8010], 0x0f00 | '!'
|
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
|
mov edi, 0xA0000
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
.loop:
|
.loop:
|
||||||
|
Loading…
Reference in New Issue
Block a user