From 0faa2eb553c28cffccd51b0c14634df052eeb5d0 Mon Sep 17 00:00:00 2001 From: Lucia Ceionia Date: Wed, 1 Feb 2023 14:18:27 -0600 Subject: [PATCH] Adds more fault 'hanlders', Sets A20 for some hardware, Fixes some other minor stuff --- boot.nasm | 14 ++++++-- entry.nasm | 2 +- handler.nasm | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ interrupt.c | 25 +++++++++++++ kernel.c | 51 ++++++++++++++++---------- link.ld | 2 +- v86.nasm | 3 -- 7 files changed, 171 insertions(+), 26 deletions(-) diff --git a/boot.nasm b/boot.nasm index fd9b104..eeef474 100644 --- a/boot.nasm +++ b/boot.nasm @@ -32,12 +32,22 @@ mov cr0, eax jmp 08h:Pmode [BITS 32] Pmode: -mov ax, 0x10 +mov eax, 0x10 mov ds, ax mov es, ax +mov fs, ax +mov gs, ax +mov ss, ax +in al, 0x92 +test al, 2 +jnz after +or al, 2 +and al, 0xFE +out 0x92, al +after: mov esi, 0x8000 mov edi, 0x100000 -mov ecx, 0x10000 +mov ecx, 17000 rep movsb jmp 08h:0x100000 gdt_desc: diff --git a/entry.nasm b/entry.nasm index 4897fd5..e7d439c 100644 --- a/entry.nasm +++ b/entry.nasm @@ -1,7 +1,7 @@ global entry entry: lgdt [gdt_desc] ; load gdt register -jmp Pmodecode +jmp 08h:Pmodecode extern gdt_desc diff --git a/handler.nasm b/handler.nasm index 2745e99..73b62f6 100644 --- a/handler.nasm +++ b/handler.nasm @@ -159,3 +159,103 @@ 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 diff --git a/interrupt.c b/interrupt.c index 83028a3..dc850dc 100644 --- a/interrupt.c +++ b/interrupt.c @@ -182,6 +182,8 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) { for(;;); case 0x3: kbd_wait(); + frame->eip = (uint16_t) (frame->eip + 2); + break; default: stack = &stack[-3]; frame->esp = ((frame->esp & 0xffff) - 6) & 0xffff; @@ -239,6 +241,17 @@ extern void keyboardHandler(); extern void gpfHandler(); extern void pageFaultHandler(); extern void unhandled_handler(); +extern void divisionErrorHandler(); +extern void boundRangeHandler(); +extern void invalidOpcodeHandler(); +extern void deviceNotAvailableHandler(); +extern void doubleFaultHandler(); +extern void invalidTSSHandler(); +extern void segmentNotPresentHandler(); +extern void stackSegmentHandler(); +extern void x87FloatingHandler(); +extern void alignmentCheckHandler(); +extern void controlProtectionHandler(); extern void picInit(); void set_system_gate(uint8_t gate, void (*handler)()) { IDT[gate].offset_1 = (uint32_t)(size_t)handler & 0xFFFF; @@ -275,6 +288,18 @@ void setup_interrupts() { set_trap_gate(13, gpfHandler); set_trap_gate(14, pageFaultHandler); + set_trap_gate(0, divisionErrorHandler); + set_trap_gate(5, boundRangeHandler); + set_trap_gate(6, invalidOpcodeHandler); + set_trap_gate(7, deviceNotAvailableHandler); + set_trap_gate(8, doubleFaultHandler); + set_trap_gate(10, invalidTSSHandler); + set_trap_gate(11, segmentNotPresentHandler); + set_trap_gate(12, stackSegmentHandler); + set_trap_gate(16, x87FloatingHandler); + set_trap_gate(17, alignmentCheckHandler); + set_trap_gate(21, controlProtectionHandler); + asm volatile("lidt %0": : "m"(IDTR)); picInit(); IRQ_clear_mask(0); diff --git a/kernel.c b/kernel.c index 5c93734..079d3db 100644 --- a/kernel.c +++ b/kernel.c @@ -32,25 +32,25 @@ void enable_sse() { ); } -void print_flags() { +uint32_t get_flags() { uint32_t flags; asm volatile("pushfd\npop %%eax":"=a"(flags)); - printDword(flags, 0xB8000 + (160*4) + 50); + return flags; } -void print_cr0() { +uint32_t get_cr0() { uint32_t reg; asm volatile("mov %%cr0, %%eax":"=a"(reg)); - printDword(reg, 0xB8000 + (160*5) + 50); + return reg; } -void print_cr3() { +uint32_t get_cr3() { uint32_t reg; asm volatile("mov %%cr3, %%eax":"=a"(reg)); - printDword(reg, 0xB8000 + (160*5) + 50 + 8*2 + 2); + return reg; } -void print_cr4() { +uint32_t get_cr4() { uint32_t reg; asm volatile("mov %%cr4, %%eax":"=a"(reg)); - printDword(reg, 0xB8000 + (160*5) + 50 + 8*4 + 4); + return reg; } struct __attribute((__packed__)) Int13DiskPacket_t { @@ -77,8 +77,8 @@ 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; @@ -130,11 +130,14 @@ void TestGfx() { } } void TestDiskRead() { + word *vga_text = (word *)0xb8000 + (80*5); + vga_text += printStr("Setting Text Mode... ", vga_text); FARPTR v86_entry = i386LinearToFp(v86TextMode); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry)); + vga_text += printStr("Done. Starting Disk Read... ", vga_text); v86_entry = i386LinearToFp(v86DiskRead); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry)); - word *vga_text = (word *)0xb8000; + vga_text = (word *)0xb8000; char *diskReadBuf = (char *)0x23000; for (int i = 0; i < (80*25)/2; i++) { printByte(diskReadBuf[i], &vga_text[i*2]); @@ -216,12 +219,15 @@ void start() { char h[] = "LuciaOS"; for (int i = 0; i < sizeof(h); i++) *(char *)&vga_text[i] = h[i]; + vga_text = &vga_text[80]; uint32_t o; asm("mov %%esp, %%eax" : "=a"(o) : :); - printDword(o, (uint16_t *)&vga_text[80]); + vga_text += printDword(o, vga_text); + vga_text++; asm("mov %%ebp, %%eax" : "=a"(o) : :); - printDword(o, (uint16_t *)&vga_text[160]); + vga_text += printDword(o, vga_text); + vga_text++; //char c[] = "APIC support: "; //char apic; @@ -231,11 +237,13 @@ void start() { //if (!apic) return; char sse_str[] = "SSE support: "; - char sse; - printByte(sse = check_sse(), (uint16_t*)&vga_text[80*4 + sizeof(sse_str) - 1]); - for (int i = 0; i < sizeof(sse_str); i++) - *(char *)&vga_text[i+(80*4)] = sse_str[i]; - if (!sse) return; + vga_text += printStr("SSE: ", vga_text); + char sse = check_sse(); + if (!sse) { + *vga_text = 'N'; + return; + } + vga_text += printStr("Y ", vga_text); enable_sse(); setup_binary(); @@ -245,11 +253,16 @@ void start() { setup_tss(); init_paging(); //print_flags(); - print_cr0(); + vga_text += printStr("CR0:", vga_text); + vga_text += printDword(get_cr0(), vga_text); + vga_text++; //print_cr3(); //print_cr4(); + vga_text += printStr("V86 Test... ", vga_text); TestV86(); // has int 3 wait in v86 + vga_text = (word *)0xb8000 + (80*3); + printStr("Done. Press any key for next test.", vga_text); TestGfx(); kbd_wait(); TestDiskRead(); diff --git a/link.ld b/link.ld index 480846f..cb9c64b 100644 --- a/link.ld +++ b/link.ld @@ -15,7 +15,7 @@ SECTIONS { _edata = .; } - .realmode 0x8000 : + .realmode (0x8000 + ADDR(.data) + SIZEOF(.data) - 0x100000) : AT ( ADDR(.data) + SIZEOF(.data) ) { _v86code = .; *(.v86); _ev86code = .; } diff --git a/v86.nasm b/v86.nasm index a149c08..7a0e801 100644 --- a/v86.nasm +++ b/v86.nasm @@ -41,9 +41,6 @@ call real_printword add di, 2 mov ax, cs call real_printword -.loop: -inc byte [0] -int 3 int 3 int 0x30 ; exit jmp $