Adds more fault 'hanlders', Sets A20 for some hardware, Fixes some other minor stuff

This commit is contained in:
Lucia Ceionia 2023-02-01 14:18:27 -06:00
parent afaf5e1a03
commit 0faa2eb553
7 changed files with 171 additions and 26 deletions

View File

@ -32,12 +32,22 @@ mov cr0, eax
jmp 08h:Pmode jmp 08h:Pmode
[BITS 32] [BITS 32]
Pmode: Pmode:
mov ax, 0x10 mov eax, 0x10
mov ds, ax mov ds, ax
mov es, 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 esi, 0x8000
mov edi, 0x100000 mov edi, 0x100000
mov ecx, 0x10000 mov ecx, 17000
rep movsb rep movsb
jmp 08h:0x100000 jmp 08h:0x100000
gdt_desc: gdt_desc:

View File

@ -1,7 +1,7 @@
global entry global entry
entry: entry:
lgdt [gdt_desc] ; load gdt register lgdt [gdt_desc] ; load gdt register
jmp Pmodecode jmp 08h:Pmodecode
extern gdt_desc extern gdt_desc

View File

@ -159,3 +159,103 @@ 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

View File

@ -182,6 +182,8 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) {
for(;;); for(;;);
case 0x3: case 0x3:
kbd_wait(); kbd_wait();
frame->eip = (uint16_t) (frame->eip + 2);
break;
default: default:
stack = &stack[-3]; stack = &stack[-3];
frame->esp = ((frame->esp & 0xffff) - 6) & 0xffff; frame->esp = ((frame->esp & 0xffff) - 6) & 0xffff;
@ -239,6 +241,17 @@ extern void keyboardHandler();
extern void gpfHandler(); extern void gpfHandler();
extern void pageFaultHandler(); extern void pageFaultHandler();
extern void unhandled_handler(); 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(); extern void picInit();
void set_system_gate(uint8_t gate, void (*handler)()) { void set_system_gate(uint8_t gate, void (*handler)()) {
IDT[gate].offset_1 = (uint32_t)(size_t)handler & 0xFFFF; 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(13, gpfHandler);
set_trap_gate(14, pageFaultHandler); 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)); asm volatile("lidt %0": : "m"(IDTR));
picInit(); picInit();
IRQ_clear_mask(0); IRQ_clear_mask(0);

View File

@ -32,25 +32,25 @@ void enable_sse() {
); );
} }
void print_flags() { uint32_t get_flags() {
uint32_t flags; uint32_t flags;
asm volatile("pushfd\npop %%eax":"=a"(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; uint32_t reg;
asm volatile("mov %%cr0, %%eax":"=a"(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; uint32_t reg;
asm volatile("mov %%cr3, %%eax":"=a"(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; uint32_t reg;
asm volatile("mov %%cr4, %%eax":"=a"(reg)); asm volatile("mov %%cr4, %%eax":"=a"(reg));
printDword(reg, 0xB8000 + (160*5) + 50 + 8*4 + 4); return reg;
} }
struct __attribute((__packed__)) Int13DiskPacket_t { struct __attribute((__packed__)) Int13DiskPacket_t {
@ -77,8 +77,8 @@ 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;
@ -130,11 +130,14 @@ void TestGfx() {
} }
} }
void TestDiskRead() { void TestDiskRead() {
word *vga_text = (word *)0xb8000 + (80*5);
vga_text += printStr("Setting Text Mode... ", vga_text);
FARPTR v86_entry = i386LinearToFp(v86TextMode); FARPTR v86_entry = i386LinearToFp(v86TextMode);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry)); 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); v86_entry = i386LinearToFp(v86DiskRead);
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry)); 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; char *diskReadBuf = (char *)0x23000;
for (int i = 0; i < (80*25)/2; i++) { for (int i = 0; i < (80*25)/2; i++) {
printByte(diskReadBuf[i], &vga_text[i*2]); printByte(diskReadBuf[i], &vga_text[i*2]);
@ -216,12 +219,15 @@ void start() {
char h[] = "LuciaOS"; char h[] = "LuciaOS";
for (int i = 0; i < sizeof(h); i++) for (int i = 0; i < sizeof(h); i++)
*(char *)&vga_text[i] = h[i]; *(char *)&vga_text[i] = h[i];
vga_text = &vga_text[80];
uint32_t o; uint32_t o;
asm("mov %%esp, %%eax" : "=a"(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) : :); 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 c[] = "APIC support: ";
//char apic; //char apic;
@ -231,11 +237,13 @@ void start() {
//if (!apic) return; //if (!apic) return;
char sse_str[] = "SSE support: "; char sse_str[] = "SSE support: ";
char sse; vga_text += printStr("SSE: ", vga_text);
printByte(sse = check_sse(), (uint16_t*)&vga_text[80*4 + sizeof(sse_str) - 1]); char sse = check_sse();
for (int i = 0; i < sizeof(sse_str); i++) if (!sse) {
*(char *)&vga_text[i+(80*4)] = sse_str[i]; *vga_text = 'N';
if (!sse) return; return;
}
vga_text += printStr("Y ", vga_text);
enable_sse(); enable_sse();
setup_binary(); setup_binary();
@ -245,11 +253,16 @@ void start() {
setup_tss(); setup_tss();
init_paging(); init_paging();
//print_flags(); //print_flags();
print_cr0(); vga_text += printStr("CR0:", vga_text);
vga_text += printDword(get_cr0(), vga_text);
vga_text++;
//print_cr3(); //print_cr3();
//print_cr4(); //print_cr4();
vga_text += printStr("V86 Test... ", vga_text);
TestV86(); // has int 3 wait in v86 TestV86(); // has int 3 wait in v86
vga_text = (word *)0xb8000 + (80*3);
printStr("Done. Press any key for next test.", vga_text);
TestGfx(); TestGfx();
kbd_wait(); kbd_wait();
TestDiskRead(); TestDiskRead();

View File

@ -15,7 +15,7 @@ SECTIONS {
_edata = .; _edata = .;
} }
.realmode 0x8000 : .realmode (0x8000 + ADDR(.data) + SIZEOF(.data) - 0x100000) :
AT ( ADDR(.data) + SIZEOF(.data) ) AT ( ADDR(.data) + SIZEOF(.data) )
{ _v86code = .; *(.v86); _ev86code = .; } { _v86code = .; *(.v86); _ev86code = .; }

View File

@ -41,9 +41,6 @@ call real_printword
add di, 2 add di, 2
mov ax, cs mov ax, cs
call real_printword call real_printword
.loop:
inc byte [0]
int 3
int 3 int 3
int 0x30 ; exit int 0x30 ; exit
jmp $ jmp $