Usermode can return to caller, ret value in EAX.

This commit is contained in:
Lucia Ceionia 2022-09-18 00:30:24 -05:00
parent 1545a9a790
commit c80a420da0
4 changed files with 38 additions and 4 deletions

View File

@ -1,5 +1,5 @@
objects = entry.o kernel.o handler.o interrupt.o v86.o print.o
CFLAGS = -target "i686-elf" -m32 -ffreestanding -march=pentium-m -fno-stack-protector -nostdlib -c
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -nostdlib -c
%.o: %.nasm
nasm -f elf32 -o $@ $<

View File

@ -62,16 +62,30 @@ mov word [0xb8010], 0x0f00 | '!'
mov edi, 0xA0000
xor eax, eax
.loop:
mov cx, 320
mov ecx, 320
rep stosb
inc al
cmp eax, 200
jl .loop
mov eax, 0xA0000
int 0x30 ; Exit
xor ebx, ebx
div bl ; Unhandled DIV0 exception
global jmp_usermode_test
jmp_usermode_test:
pop eax ; return address
mov ebp, esp ; return stack
push ss
push ebp
pushfd
push cs
push eax ; return address
push ds ; other segs, pop
push es ; before iret
push fs ; in exit handler
push gs
mov dword [0x20004], esp ; tss ESP0
mov ax, 0x20 | 3
mov ds, ax
mov es, ax

View File

@ -20,12 +20,28 @@ and eax, 1 << 17 ; VM flag
test eax, eax
pop eax
jnz gpf_handler_v86
jmp gpf_handler_32
gpf_unhandled:
mov dword [0xb8000], 0x0f000f00 | 'G' | 'P' << 16
mov dword [0xb8004], 0x0f000f00 | 'F' | '!' << 16
.hlt:
hlt
jmp .hlt
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
mov esp, dword [0x20004] ; return info
pop gs
pop fs
pop es
pop ds
iret ; return to original caller
scancodesToAscii: db 0, 0 ; 0x00 - 0x01
db "1234567890" ; 0x02 - 0x0B
db "-=" ; 0x0C - 0x0D

View File

@ -56,7 +56,7 @@ __attribute((__no_caller_saved_registers__))
extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip);
extern void v86Code();
__attribute((__no_caller_saved_registers__))
extern void jmp_usermode_test();
extern char *jmp_usermode_test();
/*
Real Mode Accessible (First MB)
@ -109,6 +109,10 @@ void start() {
print_cr4();
FARPTR v86_entry = i386LinearToFp(v86Code);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
jmp_usermode_test();
char *vga = jmp_usermode_test();
for (int i = 0; i < 320; i++) {
vga[i] = i;
}
}