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
|
||||
|
||||
%.o: %.nasm
|
||||
|
@ -47,7 +47,7 @@ out 0x92, al
|
||||
after:
|
||||
mov esi, 0x8000
|
||||
mov edi, 0x100000
|
||||
mov ecx, 17000
|
||||
mov ecx, 0x10000
|
||||
rep movsb
|
||||
jmp 08h:0x100000
|
||||
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
|
||||
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
|
||||
oldscancodesToAscii: db 0, 0 ; 0x00 - 0x01
|
||||
db "1234567890" ; 0x02 - 0x0B
|
||||
db "-=" ; 0x0C - 0x0D
|
||||
db 0, 0 ; 0x0E - 0x0F
|
||||
@ -71,8 +14,8 @@ db ' ' ; 0x39
|
||||
db 'C'
|
||||
scancodesToAsciiEnd:
|
||||
cursorCurrent: dd 0xb8000 + (80*6*2)
|
||||
global keyboardHandler
|
||||
keyboardHandler:
|
||||
global oldkeyboardHandler
|
||||
oldkeyboardHandler:
|
||||
push eax
|
||||
push ebx
|
||||
push ds
|
||||
@ -82,7 +25,7 @@ xor eax, eax
|
||||
in al, 0x60
|
||||
cmp eax, 0x3A
|
||||
jg .done
|
||||
mov al, [scancodesToAscii+eax]
|
||||
mov al, [oldscancodesToAscii+eax]
|
||||
test al, al
|
||||
jz .done
|
||||
mov ebx, [cursorCurrent]
|
||||
@ -98,8 +41,7 @@ pop eax
|
||||
iret
|
||||
|
||||
KBDWAIT: db 0
|
||||
global kbd_wait
|
||||
kbd_wait:
|
||||
oldkbd_wait:
|
||||
mov byte [KBDWAIT], 0
|
||||
.loop:
|
||||
hlt
|
||||
@ -108,13 +50,15 @@ test eax, eax
|
||||
jz .loop
|
||||
ret
|
||||
|
||||
TIMERVAL: dd 0
|
||||
global timerHandler
|
||||
timerHandler:
|
||||
push eax
|
||||
push ds
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
inc byte [(0xb8000 + (80*8*2))]
|
||||
;inc byte [(0xb8000 + (80*8*2))]
|
||||
inc dword [TIMERVAL]
|
||||
mov al, 0x20
|
||||
out 0x20, al
|
||||
pop ds
|
||||
@ -159,103 +103,3 @@ jmp $+2
|
||||
jmp $+2
|
||||
out 0xA1, al
|
||||
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;
|
||||
extern uint16_t *ivt;
|
||||
extern void real_test();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern void kbd_wait();
|
||||
extern void jmp_usermode_test();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
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;
|
||||
}
|
||||
|
||||
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 keyboardHandler();
|
||||
//extern void keyboardHandler();
|
||||
extern void gpfHandler();
|
||||
extern void pageFaultHandler();
|
||||
extern void unhandled_handler();
|
||||
|
@ -28,6 +28,11 @@ typedef uint32_t FARPTR;
|
||||
|
||||
FARPTR i386LinearToFp(void *ptr);
|
||||
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
void kbd_wait();
|
||||
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
uint8_t get_key();
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
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 v86DiskRead();
|
||||
extern char *jmp_usermode_test();
|
||||
__attribute((__no_caller_saved_registers__))
|
||||
extern void kbd_wait();
|
||||
|
||||
extern char _edata, _v86code, _ev86code, _bstart, _bend, _loadusercode, _usercode, _eusercode;
|
||||
void setup_binary() {
|
||||
// Put V86 code in proper place based on linker
|
||||
char *s = &_edata;
|
||||
char *d = &_v86code;
|
||||
//while (d < &_ev86code)
|
||||
// *d++ = *s++;
|
||||
while (d < &_ev86code)
|
||||
*d++ = *s++;
|
||||
|
||||
// Put Usermode code in proper place based on linker
|
||||
s = &_loadusercode;
|
||||
@ -91,6 +89,42 @@ void setup_binary() {
|
||||
*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)
|
||||
00000 - 00400 IVT (1kB)
|
||||
@ -260,14 +294,30 @@ void start() {
|
||||
//print_cr4();
|
||||
|
||||
vga_text += printStr("V86 Test... ", vga_text);
|
||||
//asm ("xchgw %bx, %bx");
|
||||
TestV86(); // has int 3 wait in v86
|
||||
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();
|
||||
kbd_wait();
|
||||
TestDiskRead();
|
||||
kbd_wait();
|
||||
TestFAT();
|
||||
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 = .;
|
||||
}
|
||||
|
||||
.realmode (0x8000 + ADDR(.data) + SIZEOF(.data) - 0x100000) :
|
||||
.realmode 0x8000 :
|
||||
AT ( ADDR(.data) + SIZEOF(.data) )
|
||||
{ _v86code = .; *(.v86); _ev86code = .; }
|
||||
|
||||
|
@ -16,5 +16,7 @@ cmp eax, 200
|
||||
jl .loop
|
||||
mov eax, 0xA0000
|
||||
int 0x30 ; Exit
|
||||
mov edx, 0x105000 ; somewhere in kernel mem
|
||||
mov edx, [edx] ; should page fault
|
||||
xor ebx, ebx
|
||||
div bl ; Unhandled DIV0 exception
|
||||
|
Loading…
Reference in New Issue
Block a user