More advanced Fault handling (recovers to text mode), Keyboard handler converted to C and improved (shifting, simple get_key added)
This commit is contained in:
parent
0faa2eb553
commit
679eb8cf57
2
Makefile
2
Makefile
@ -1,4 +1,4 @@
|
|||||||
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o
|
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o fault.o
|
||||||
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c
|
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c
|
||||||
|
|
||||||
%.o: %.nasm
|
%.o: %.nasm
|
||||||
|
@ -47,7 +47,7 @@ out 0x92, al
|
|||||||
after:
|
after:
|
||||||
mov esi, 0x8000
|
mov esi, 0x8000
|
||||||
mov edi, 0x100000
|
mov edi, 0x100000
|
||||||
mov ecx, 17000
|
mov ecx, 0x10000
|
||||||
rep movsb
|
rep movsb
|
||||||
jmp 08h:0x100000
|
jmp 08h:0x100000
|
||||||
gdt_desc:
|
gdt_desc:
|
||||||
|
146
fault.nasm
Normal file
146
fault.nasm
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
extern error_screen ; 80x50 words
|
||||||
|
|
||||||
|
; Switches to text mode and shit
|
||||||
|
extern error_environment
|
||||||
|
_fault_coda:
|
||||||
|
xchg bx,bx
|
||||||
|
mov ax, 0x10
|
||||||
|
mov es, ax
|
||||||
|
; move to TOP OF kernel stack
|
||||||
|
mov ebp, 0x400000
|
||||||
|
mov esp, ebp
|
||||||
|
call error_environment
|
||||||
|
.hlt:
|
||||||
|
hlt
|
||||||
|
jmp .hlt
|
||||||
|
|
||||||
|
global unhandled_handler
|
||||||
|
unhandled_handler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | 'E' | 'R' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'R' | 'O' << 16
|
||||||
|
mov dword [error_screen+0x08], 0x0f000f00 | 'R' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
|
||||||
|
global pageFaultHandler
|
||||||
|
pageFaultHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
pop eax ; error code
|
||||||
|
mov ebx, 0x0f000f00 | '0' | '!' << 16
|
||||||
|
and eax, 0x7 ; U/S,R/W,P
|
||||||
|
add ebx, eax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | 'P' | 'G' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | 'L' << 16
|
||||||
|
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:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'D' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'E' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global boundRangeHandler
|
||||||
|
boundRangeHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'B' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'R' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global invalidOpcodeHandler
|
||||||
|
invalidOpcodeHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'U' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'D' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global deviceNotAvailableHandler
|
||||||
|
deviceNotAvailableHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'N' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'D' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global doubleFaultHandler
|
||||||
|
doubleFaultHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [0xb8000+0x00], 0x0f000f00 | '#' | 'D' << 16
|
||||||
|
mov dword [0xb8000+0x04], 0x0f000f00 | 'F' | '!' << 16
|
||||||
|
; double faults simply abort right then
|
||||||
|
.hlt: hlt
|
||||||
|
jmp .hlt
|
||||||
|
global invalidTSSHandler
|
||||||
|
invalidTSSHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'T' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'S' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global segmentNotPresentHandler
|
||||||
|
segmentNotPresentHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'N' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'P' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global stackSegmentHandler
|
||||||
|
stackSegmentHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'S' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'S' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global x87FloatingHandler
|
||||||
|
x87FloatingHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'M' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global alignmentCheckHandler
|
||||||
|
alignmentCheckHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'A' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'C' | '!' << 16
|
||||||
|
jmp _fault_coda
|
||||||
|
global controlProtectionHandler
|
||||||
|
controlProtectionHandler:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'C' << 16
|
||||||
|
mov dword [error_screen+0x04], 0x0f000f00 | 'P' | '!' << 16
|
||||||
|
jmp _fault_coda
|
172
handler.nasm
172
handler.nasm
@ -1,61 +1,4 @@
|
|||||||
extern unhandled_handler
|
oldscancodesToAscii: db 0, 0 ; 0x00 - 0x01
|
||||||
unhandled_handler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | 'E' | 'R' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'R' | 'O' << 16
|
|
||||||
mov dword [0xb8008], 0x0f000f00 | 'R' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
|
|
||||||
global pageFaultHandler
|
|
||||||
pageFaultHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
pop eax ; error code
|
|
||||||
mov ebx, 0x0f000f00 | '0' | '!' << 16
|
|
||||||
and eax, 0x7 ; U/S,R/W,P
|
|
||||||
add ebx, eax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | 'P' | 'G' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'F' | 'L' << 16
|
|
||||||
mov dword [0xb8008], 0x0f000f00 | 'T' | ':' << 16
|
|
||||||
mov dword [0xb800C], ebx
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
|
|
||||||
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 [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
|
|
||||||
jmp return_prev_task
|
|
||||||
|
|
||||||
extern return_prev_task
|
|
||||||
|
|
||||||
scancodesToAscii: db 0, 0 ; 0x00 - 0x01
|
|
||||||
db "1234567890" ; 0x02 - 0x0B
|
db "1234567890" ; 0x02 - 0x0B
|
||||||
db "-=" ; 0x0C - 0x0D
|
db "-=" ; 0x0C - 0x0D
|
||||||
db 0, 0 ; 0x0E - 0x0F
|
db 0, 0 ; 0x0E - 0x0F
|
||||||
@ -71,8 +14,8 @@ db ' ' ; 0x39
|
|||||||
db 'C'
|
db 'C'
|
||||||
scancodesToAsciiEnd:
|
scancodesToAsciiEnd:
|
||||||
cursorCurrent: dd 0xb8000 + (80*6*2)
|
cursorCurrent: dd 0xb8000 + (80*6*2)
|
||||||
global keyboardHandler
|
global oldkeyboardHandler
|
||||||
keyboardHandler:
|
oldkeyboardHandler:
|
||||||
push eax
|
push eax
|
||||||
push ebx
|
push ebx
|
||||||
push ds
|
push ds
|
||||||
@ -82,7 +25,7 @@ xor eax, eax
|
|||||||
in al, 0x60
|
in al, 0x60
|
||||||
cmp eax, 0x3A
|
cmp eax, 0x3A
|
||||||
jg .done
|
jg .done
|
||||||
mov al, [scancodesToAscii+eax]
|
mov al, [oldscancodesToAscii+eax]
|
||||||
test al, al
|
test al, al
|
||||||
jz .done
|
jz .done
|
||||||
mov ebx, [cursorCurrent]
|
mov ebx, [cursorCurrent]
|
||||||
@ -98,8 +41,7 @@ pop eax
|
|||||||
iret
|
iret
|
||||||
|
|
||||||
KBDWAIT: db 0
|
KBDWAIT: db 0
|
||||||
global kbd_wait
|
oldkbd_wait:
|
||||||
kbd_wait:
|
|
||||||
mov byte [KBDWAIT], 0
|
mov byte [KBDWAIT], 0
|
||||||
.loop:
|
.loop:
|
||||||
hlt
|
hlt
|
||||||
@ -108,13 +50,15 @@ test eax, eax
|
|||||||
jz .loop
|
jz .loop
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
TIMERVAL: dd 0
|
||||||
global timerHandler
|
global timerHandler
|
||||||
timerHandler:
|
timerHandler:
|
||||||
push eax
|
push eax
|
||||||
push ds
|
push ds
|
||||||
mov ax, 0x10
|
mov ax, 0x10
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
inc byte [(0xb8000 + (80*8*2))]
|
;inc byte [(0xb8000 + (80*8*2))]
|
||||||
|
inc dword [TIMERVAL]
|
||||||
mov al, 0x20
|
mov al, 0x20
|
||||||
out 0x20, al
|
out 0x20, al
|
||||||
pop ds
|
pop ds
|
||||||
@ -159,103 +103,3 @@ jmp $+2
|
|||||||
jmp $+2
|
jmp $+2
|
||||||
out 0xA1, al
|
out 0xA1, al
|
||||||
ret
|
ret
|
||||||
|
|
||||||
global divisionErrorHandler
|
|
||||||
divisionErrorHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'D' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'E' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global boundRangeHandler
|
|
||||||
boundRangeHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'B' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'R' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global invalidOpcodeHandler
|
|
||||||
invalidOpcodeHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'U' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'D' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global deviceNotAvailableHandler
|
|
||||||
deviceNotAvailableHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'N' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'D' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global doubleFaultHandler
|
|
||||||
doubleFaultHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'D' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'F' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global invalidTSSHandler
|
|
||||||
invalidTSSHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'T' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'S' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global segmentNotPresentHandler
|
|
||||||
segmentNotPresentHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'N' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'P' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global stackSegmentHandler
|
|
||||||
stackSegmentHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'S' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'S' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global x87FloatingHandler
|
|
||||||
x87FloatingHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'M' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'F' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global alignmentCheckHandler
|
|
||||||
alignmentCheckHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'A' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'C' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
global controlProtectionHandler
|
|
||||||
controlProtectionHandler:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov dword [0xb8000], 0x0f000f00 | '#' | 'C' << 16
|
|
||||||
mov dword [0xb8004], 0x0f000f00 | 'P' | '!' << 16
|
|
||||||
.hlt:
|
|
||||||
hlt
|
|
||||||
jmp .hlt
|
|
||||||
|
77
interrupt.c
77
interrupt.c
@ -84,8 +84,6 @@ void IRQ_clear_mask(char IRQline) {
|
|||||||
char v86_if = 0;
|
char v86_if = 0;
|
||||||
extern uint16_t *ivt;
|
extern uint16_t *ivt;
|
||||||
extern void real_test();
|
extern void real_test();
|
||||||
__attribute((__no_caller_saved_registers__))
|
|
||||||
extern void kbd_wait();
|
|
||||||
extern void jmp_usermode_test();
|
extern void jmp_usermode_test();
|
||||||
__attribute((__no_caller_saved_registers__))
|
__attribute((__no_caller_saved_registers__))
|
||||||
extern void return_prev_task();
|
extern void return_prev_task();
|
||||||
@ -236,8 +234,81 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
|
|||||||
vga[0] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14;
|
vga[0] = 'G'; vga[2] = 'S'; int_printWord(frame->gs, (uint16_t*)&vga[4]); vga += 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t scancodesToAscii[0x3B] =
|
||||||
|
"\0\0" // 0x00 - 0x01
|
||||||
|
"1234567890" // 0x02 - 0x0B
|
||||||
|
"-=" // 0x0C - 0x0D
|
||||||
|
"\0\0" // 0x0E - 0x0F
|
||||||
|
"qwertyuiop[]" // 0x10 - 0x1B
|
||||||
|
"\0\0" // 0x1C - 0x1D
|
||||||
|
"asdfghjkl;'`" // 0x1E - 0x29
|
||||||
|
"\0" // 0x2A
|
||||||
|
"\\zxcvbnm,./" // 0x2B - 0x35
|
||||||
|
"\0" // 0x36
|
||||||
|
"*" // 0x37
|
||||||
|
"\0" // 0x38
|
||||||
|
" " // 0x39
|
||||||
|
"\0"; // 0x3A
|
||||||
|
uint8_t scancodesToAsciiShift[0x3B] =
|
||||||
|
"\0\0" // 0x00 - 0x01
|
||||||
|
"!@#$%^&*()" // 0x02 - 0x0B
|
||||||
|
"_+" // 0x0C - 0x0D
|
||||||
|
"\0\0" // 0x0E - 0x0F
|
||||||
|
"QWERTYUIOP{}" // 0x10 - 0x1B
|
||||||
|
"\0\0" // 0x1C - 0x1D
|
||||||
|
"ASDFGHJKL:\"~" // 0x1E - 0x29
|
||||||
|
"\0" // 0x2A
|
||||||
|
"|ZXCVBNM<>?" // 0x2B - 0x35
|
||||||
|
"\0" // 0x36
|
||||||
|
"*" // 0x37
|
||||||
|
"\0" // 0x38
|
||||||
|
" " // 0x39
|
||||||
|
"\0"; // 0x3A
|
||||||
|
uint8_t _KBDWAIT;
|
||||||
|
uint8_t _KEYCAPS = 0, _KEYSHIFT = 0;
|
||||||
|
uint8_t _LSTKEY = 0;
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void keyboardHandler(struct interrupt_frame *frame) {
|
||||||
|
uint8_t key;
|
||||||
|
asm volatile("inb $0x60, %%al":"=a"(key));
|
||||||
|
if (key == 0x3A) { // caps lock press
|
||||||
|
_KEYCAPS = !_KEYCAPS;
|
||||||
|
} else if (key == 0x2A || key == 0x36) { // left and right shift press
|
||||||
|
_KEYSHIFT = 1;
|
||||||
|
} else if (key == 0xAA || key == 0xB6) { // left and right shift release
|
||||||
|
_KEYSHIFT = 0;
|
||||||
|
} else if (key < 0x3B) {
|
||||||
|
uint8_t ascii = _KEYCAPS != _KEYSHIFT ?
|
||||||
|
scancodesToAsciiShift[key] :
|
||||||
|
scancodesToAscii[key];
|
||||||
|
if (ascii) {
|
||||||
|
_LSTKEY = ascii;
|
||||||
|
_KBDWAIT = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asm volatile("outb %%al, $0x20"::"a"(0x20));
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute((__no_caller_saved_registers__))
|
||||||
|
void kbd_wait() {
|
||||||
|
_KBDWAIT = 0;
|
||||||
|
while(!_KBDWAIT) {
|
||||||
|
asm volatile("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute((__no_caller_saved_registers__))
|
||||||
|
uint8_t get_key() {
|
||||||
|
while(!_LSTKEY) {
|
||||||
|
asm volatile("hlt");
|
||||||
|
}
|
||||||
|
uint8_t k = _LSTKEY;
|
||||||
|
_LSTKEY = 0;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
extern void timerHandler();
|
extern void timerHandler();
|
||||||
extern void keyboardHandler();
|
//extern void keyboardHandler();
|
||||||
extern void gpfHandler();
|
extern void gpfHandler();
|
||||||
extern void pageFaultHandler();
|
extern void pageFaultHandler();
|
||||||
extern void unhandled_handler();
|
extern void unhandled_handler();
|
||||||
|
@ -28,6 +28,11 @@ typedef uint32_t FARPTR;
|
|||||||
|
|
||||||
FARPTR i386LinearToFp(void *ptr);
|
FARPTR i386LinearToFp(void *ptr);
|
||||||
|
|
||||||
|
__attribute((__no_caller_saved_registers__))
|
||||||
|
void kbd_wait();
|
||||||
|
|
||||||
|
__attribute((__no_caller_saved_registers__))
|
||||||
|
uint8_t get_key();
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
__attribute__ ((interrupt))
|
||||||
void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code);
|
void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code);
|
||||||
|
60
kernel.c
60
kernel.c
@ -69,16 +69,14 @@ extern void v86GfxMode();
|
|||||||
extern void v86TextMode();
|
extern void v86TextMode();
|
||||||
extern void v86DiskRead();
|
extern void v86DiskRead();
|
||||||
extern char *jmp_usermode_test();
|
extern char *jmp_usermode_test();
|
||||||
__attribute((__no_caller_saved_registers__))
|
|
||||||
extern void kbd_wait();
|
|
||||||
|
|
||||||
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
|
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
|
||||||
void setup_binary() {
|
void setup_binary() {
|
||||||
// Put V86 code in proper place based on linker
|
// Put V86 code in proper place based on linker
|
||||||
char *s = &_edata;
|
char *s = &_edata;
|
||||||
char *d = &_v86code;
|
char *d = &_v86code;
|
||||||
//while (d < &_ev86code)
|
while (d < &_ev86code)
|
||||||
// *d++ = *s++;
|
*d++ = *s++;
|
||||||
|
|
||||||
// Put Usermode code in proper place based on linker
|
// Put Usermode code in proper place based on linker
|
||||||
s = &_loadusercode;
|
s = &_loadusercode;
|
||||||
@ -91,6 +89,42 @@ void setup_binary() {
|
|||||||
*d = 0;
|
*d = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t error_screen[80*50]; // 50-line VGA screen of error content
|
||||||
|
|
||||||
|
extern uint16_t *ivt;
|
||||||
|
uint16_t ivt_bkup[0x200];
|
||||||
|
uint8_t bios_bkup[0x40000];
|
||||||
|
void backup_ivtbios() {
|
||||||
|
for (int i = 0; i < 0x200; i++)
|
||||||
|
ivt_bkup[i] = ivt[i];
|
||||||
|
for (int i = 0; i < 0x40000; i++)
|
||||||
|
bios_bkup[i] = ((uint8_t*)0xC0000)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should only be used during fault handling, as it is expensive
|
||||||
|
void ensure_v86env() {
|
||||||
|
for (int i = 0; i < 0x200; i++)
|
||||||
|
ivt[i] = ivt_bkup[i];
|
||||||
|
for (int i = 0; i < 0x40000; i++)
|
||||||
|
((uint8_t*)0xC0000)[i] = bios_bkup[i];
|
||||||
|
char *s = &_edata;
|
||||||
|
char *d = &_v86code;
|
||||||
|
while (d < &_ev86code)
|
||||||
|
*d++ = *s++;
|
||||||
|
for (int i = 0; i < 80*50; i++)
|
||||||
|
if (!error_screen[i]) error_screen[i] = 0x0f00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void error_environment() {
|
||||||
|
ensure_v86env();
|
||||||
|
FARPTR v86_entry = i386LinearToFp(v86TextMode);
|
||||||
|
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry));
|
||||||
|
printStr("Oh noes!!! System error! ;c", &error_screen[80]);
|
||||||
|
uint16_t *vga_text = ((uint16_t*)0xB8000);
|
||||||
|
for (int i = 0; i < 80*50; i++)
|
||||||
|
vga_text[i] = error_screen[i];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Real Mode Accessible (First MB)
|
Real Mode Accessible (First MB)
|
||||||
00000 - 00400 IVT (1kB)
|
00000 - 00400 IVT (1kB)
|
||||||
@ -260,14 +294,30 @@ void start() {
|
|||||||
//print_cr4();
|
//print_cr4();
|
||||||
|
|
||||||
vga_text += printStr("V86 Test... ", vga_text);
|
vga_text += printStr("V86 Test... ", vga_text);
|
||||||
|
//asm ("xchgw %bx, %bx");
|
||||||
TestV86(); // has int 3 wait in v86
|
TestV86(); // has int 3 wait in v86
|
||||||
vga_text = (word *)0xb8000 + (80*3);
|
vga_text = (word *)0xb8000 + (80*3);
|
||||||
printStr("Done. Press any key for next test.", vga_text);
|
backup_ivtbios();
|
||||||
|
vga_text += printStr("Done. Press 'N' for next test.", vga_text);
|
||||||
|
uint8_t key;
|
||||||
|
while ((key = get_key()) != 'N') {
|
||||||
|
*vga_text = (*vga_text & 0xFF00) | key;
|
||||||
|
vga_text++;
|
||||||
|
}
|
||||||
TestGfx();
|
TestGfx();
|
||||||
kbd_wait();
|
kbd_wait();
|
||||||
TestDiskRead();
|
TestDiskRead();
|
||||||
kbd_wait();
|
kbd_wait();
|
||||||
TestFAT();
|
TestFAT();
|
||||||
kbd_wait();
|
kbd_wait();
|
||||||
|
|
||||||
|
vga_text = &((uint16_t*)0xB8000)[80*16];
|
||||||
|
vga_text += printStr("Press ` for a flagrant system error... ", vga_text);
|
||||||
|
while ((key = get_key()) != '`') {
|
||||||
|
*vga_text = (*vga_text & 0xFF00) | key;
|
||||||
|
vga_text++;
|
||||||
|
}
|
||||||
|
// flagrant system error
|
||||||
|
*((uint8_t*)0x1000000) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
link.ld
2
link.ld
@ -15,7 +15,7 @@ SECTIONS {
|
|||||||
_edata = .;
|
_edata = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
.realmode (0x8000 + ADDR(.data) + SIZEOF(.data) - 0x100000) :
|
.realmode 0x8000 :
|
||||||
AT ( ADDR(.data) + SIZEOF(.data) )
|
AT ( ADDR(.data) + SIZEOF(.data) )
|
||||||
{ _v86code = .; *(.v86); _ev86code = .; }
|
{ _v86code = .; *(.v86); _ev86code = .; }
|
||||||
|
|
||||||
|
@ -16,5 +16,7 @@ cmp eax, 200
|
|||||||
jl .loop
|
jl .loop
|
||||||
mov eax, 0xA0000
|
mov eax, 0xA0000
|
||||||
int 0x30 ; Exit
|
int 0x30 ; Exit
|
||||||
|
mov edx, 0x105000 ; somewhere in kernel mem
|
||||||
|
mov edx, [edx] ; should page fault
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
div bl ; Unhandled DIV0 exception
|
div bl ; Unhandled DIV0 exception
|
||||||
|
Loading…
Reference in New Issue
Block a user