forked from PoliEcho-holding-org/kern
[ BIG CHANGE ] Properly Implemented IDT
- New include files: idt.h, pic.h, syscall.h and exceptions.h - Proper exception handling (still could be improved - PIC properly initiated and irqs all masked - BREAKS Keyboard - The keyboard IRQ is not handled anymore - convertColor() is kinda broken :/ (More in README.md)
This commit is contained in:
@@ -3,7 +3,7 @@ CC = i386-elf-gcc
|
||||
LD = i386-elf-ld
|
||||
AS = nasm
|
||||
|
||||
CFLAGS = -ffreestanding -m32 -Iinclude -Wall -Wextra
|
||||
CFLAGS = -ffreestanding -fno-builtin -fno-stack-protector -nostdinc -mgeneral-regs-only -m32 -march=i386 -Iinclude -Wall
|
||||
|
||||
SRC = ./src
|
||||
BUILD = ./build
|
||||
|
||||
@@ -55,6 +55,7 @@ _These images may be outdated, Idk_
|
||||
## Known issues
|
||||
- If you run kernel.bin from shell, it will clear the memory map so when you load anything it will override the kernel code
|
||||
- fillCircle() in graphics.h is broken. No idea why, so no filled circles for you (i commented out the boundaryFill call in the function)
|
||||
- convertColor() doesn't work right, because i should be using floating point, but -mgeneral-regs-only doesn't let me :(
|
||||
|
||||
## [Old Version](https://github.com/Tom-on64/old-kern)
|
||||
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
#ifndef ISRS_H
|
||||
#define ISRS_H
|
||||
|
||||
#include "idt.h"
|
||||
#include "screen.h"
|
||||
|
||||
/*
|
||||
Alignment Check
|
||||
Machine Check
|
||||
Reserved
|
||||
...
|
||||
Reserved
|
||||
*/
|
||||
|
||||
// TODO: Make proper handlers
|
||||
__attribute__ ((naked)) // Temporary handler
|
||||
void excpHandler(void) {
|
||||
__asm__ volatile (
|
||||
".intel_syntax\n"
|
||||
"iretd\n"
|
||||
".att_syntax"
|
||||
);
|
||||
}
|
||||
|
||||
// Exception handlers
|
||||
__attribute__ ((interrupt))
|
||||
void excp_divideErr(intFrame_t* iframe) { // ISR 0
|
||||
fgColor = RED;
|
||||
print("[ Division Error ]\n");
|
||||
__asm__ volatile ("cli; hlt"); // Halt system
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_debugErr(intFrame_t* iframe) { // ISR 1
|
||||
fgColor = RED;
|
||||
print("[ Debug Exception ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_nmiInterrupt(intFrame_t* iframe) { // ISR 2
|
||||
fgColor = RED;
|
||||
print("[ Non-maskable Interrupt ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_breakpoint(intFrame_t* iframe) { // ISR 3
|
||||
fgColor = RED;
|
||||
print("[ Breakpoint ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_overflow(intFrame_t* iframe) { // ISR 4
|
||||
fgColor = RED;
|
||||
print("[ Overflow Error ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_boundRangeExceed(intFrame_t* iframe) { // ISR 5
|
||||
fgColor = RED;
|
||||
print("[ Bound Range Exceeded ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_invalidOpcode(intFrame_t* iframe) { // ISR 6
|
||||
fgColor = RED;
|
||||
print("[ Invalid OpCode ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_deviceNA(intFrame_t* iframe) { // ISR 7
|
||||
fgColor = RED;
|
||||
print("[ Device Not Available ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_doubleFault(intFrame_t* iframe, uint32_t errCode) { // ISR 8
|
||||
fgColor = RED;
|
||||
print("[ Double Fault : 0x");
|
||||
print(itoa(errCode, 16));
|
||||
print(" ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_coprocOverrun(intFrame_t* iframe) { // ISR 9
|
||||
fgColor = RED;
|
||||
print("[ Coprocessor Segment Overrun ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_invalidTss(intFrame_t* iframe, uint32_t errCode) { // ISR 10
|
||||
fgColor = RED;
|
||||
print("[ Invalid TSS : 0x");
|
||||
print(itoa(errCode, 16));
|
||||
print(" ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_noSegment(intFrame_t* iframe, uint32_t errCode) { // ISR 11
|
||||
fgColor = RED;
|
||||
print("[ Segment Not Present : 0x");
|
||||
print(itoa(errCode, 16));
|
||||
print(" ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_stackSegmentFault(intFrame_t* iframe, uint32_t errCode) { // ISR 12
|
||||
fgColor = RED;
|
||||
print("[ Stack-Segment Fault : 0x");
|
||||
print(itoa(errCode, 16));
|
||||
print(" ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_generalProtectionFault(intFrame_t* iframe, uint32_t errCode) { // ISR 13
|
||||
fgColor = RED;
|
||||
print("[ General Protection Fault : 0x");
|
||||
print(itoa(errCode, 16));
|
||||
print(" ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_pageFault(intFrame_t* iframe, uint32_t errCode) { // ISR 14
|
||||
fgColor = RED;
|
||||
print("[ Page Fault : 0x");
|
||||
print(itoa(errCode, 16));
|
||||
print(" ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_reserved(intFrame_t* iframe) { // ISR 15
|
||||
fgColor = RED;
|
||||
print("[ Reserved Exception ]\n"); // Shouldn't get this one
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_floatingPointErr(intFrame_t* iframe) { // ISR 16
|
||||
fgColor = RED;
|
||||
print("[ x87 FPU Floating-Point Error ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_alignCheck(intFrame_t* iframe, uint32_t errCode) { // ISR 17
|
||||
fgColor = RED;
|
||||
print("[ Alignment Check : 0x");
|
||||
print(itoa(errCode, 16));
|
||||
print(" ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void excp_machineCheck(intFrame_t* iframe) { // ISR 18
|
||||
fgColor = RED;
|
||||
print("[ Machine Check ]\n");
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
|
||||
// TODO: Add more (because there's always more)
|
||||
|
||||
// Repetative isr definitions
|
||||
void setupExceptions() {
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
idtSetGate(i, excp_reserved, TRAP_GATE_FLAGS);
|
||||
}
|
||||
|
||||
idtSetGate(0, excp_divideErr, TRAP_GATE_FLAGS);
|
||||
idtSetGate(1, excp_debugErr, TRAP_GATE_FLAGS);
|
||||
idtSetGate(2, excp_nmiInterrupt, TRAP_GATE_FLAGS);
|
||||
idtSetGate(3, excp_breakpoint, TRAP_GATE_FLAGS);
|
||||
idtSetGate(4, excp_overflow, TRAP_GATE_FLAGS);
|
||||
idtSetGate(5, excp_boundRangeExceed, TRAP_GATE_FLAGS);
|
||||
idtSetGate(6, excp_invalidOpcode, TRAP_GATE_FLAGS);
|
||||
idtSetGate(7, excp_deviceNA, TRAP_GATE_FLAGS);
|
||||
idtSetGate(8, excp_doubleFault, TRAP_GATE_FLAGS);
|
||||
idtSetGate(9, excp_coprocOverrun, TRAP_GATE_FLAGS);
|
||||
idtSetGate(10, excp_invalidTss, TRAP_GATE_FLAGS);
|
||||
idtSetGate(11, excp_noSegment, TRAP_GATE_FLAGS);
|
||||
idtSetGate(12, excp_stackSegmentFault, TRAP_GATE_FLAGS);
|
||||
idtSetGate(13, excp_generalProtectionFault, TRAP_GATE_FLAGS);
|
||||
idtSetGate(14, excp_pageFault, TRAP_GATE_FLAGS);
|
||||
idtSetGate(15, excp_reserved, TRAP_GATE_FLAGS);
|
||||
idtSetGate(16, excp_floatingPointErr, TRAP_GATE_FLAGS);
|
||||
idtSetGate(17, excp_alignCheck, TRAP_GATE_FLAGS);
|
||||
idtSetGate(18, excp_machineCheck, TRAP_GATE_FLAGS);
|
||||
// Other are reserved
|
||||
}
|
||||
|
||||
#endif
|
||||
+30
-24
@@ -2,48 +2,54 @@
|
||||
#define IDT_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "system.h"
|
||||
#include "screen.h"
|
||||
|
||||
struct idtEntry {
|
||||
#define TRAP_GATE_FLAGS 0x8f // P = 1, DPL = 00, S = 0, Type = 1111 (32-bit Trap gate)
|
||||
#define INT_GATE_FLAGS 0x8e // P = 1, DPL = 00, S = 0, Type = 1110 (32-bit Int gate)
|
||||
#define USR_INT_GAME_FLAGS 0xee // P = 1, DPL = 11, S = 0, Type = 1110 (32-bit Int gate)
|
||||
|
||||
typedef struct {
|
||||
uint16_t offsetLow;
|
||||
uint16_t selector;
|
||||
uint8_t zero;
|
||||
uint8_t typeAttr;
|
||||
uint16_t offsetHigh;
|
||||
} __attribute__((packed));
|
||||
} __attribute__ ((packed)) idtEntry_t;
|
||||
|
||||
struct idtPointer {
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint32_t base;
|
||||
} __attribute__((packed));
|
||||
} __attribute__ ((packed)) idtp_t;
|
||||
|
||||
struct idtEntry idt[256] = { 0 };
|
||||
struct idtPointer idtp;
|
||||
typedef struct {
|
||||
uint32_t eip;
|
||||
uint32_t cs;
|
||||
uint32_t eflags;
|
||||
uint32_t esp;
|
||||
uint32_t ss;
|
||||
} __attribute__ ((packed)) intFrame_t;
|
||||
|
||||
extern void idtLoad();
|
||||
__attribute__ ((aligned(0x10))) // For performance
|
||||
idtEntry_t idt[256] = { 0 };
|
||||
idtp_t idtp;
|
||||
|
||||
void idtSetGate(uint8_t i, uint32_t offset, uint16_t selector, uint8_t typeAttr) {
|
||||
idt[i].offsetLow = (uint16_t)offset;
|
||||
idt[i].selector = selector;
|
||||
idt[i].zero = 0;
|
||||
idt[i].typeAttr = typeAttr;
|
||||
idt[i].offsetHigh = (uint16_t)(offset >> 16);
|
||||
void idtSetGate(uint8_t i, void* handler, uint8_t flags) {
|
||||
uint32_t offset = (uint32_t)handler;
|
||||
idtEntry_t* entry = &idt[i];
|
||||
|
||||
entry->offsetLow = (uint16_t)offset;
|
||||
entry->selector = 0x08;
|
||||
entry->zero = 0;
|
||||
entry->typeAttr = flags;
|
||||
entry->offsetHigh = (uint16_t)(offset >> 16);
|
||||
}
|
||||
|
||||
void setupIdt() {
|
||||
idtp.limit = sizeof(struct idtEntry) * 256;
|
||||
idtp.limit = sizeof(idtEntry_t) * 256;
|
||||
idtp.base = (uint32_t)&idt;
|
||||
|
||||
idtLoad();
|
||||
__asm__ volatile ("lidt %0" : : "m"(idtp));
|
||||
}
|
||||
|
||||
// Contains values of registers and exception info from isrs
|
||||
struct regs {
|
||||
unsigned int gs, fs, es, ds;
|
||||
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||
unsigned int intNo, errCode;
|
||||
unsigned int eip, cs, eflags, useresp, ss;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
#ifndef IRQ_H
|
||||
#define IRQ_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "idt.h"
|
||||
|
||||
void* irqRoutines[16] = { 0 };
|
||||
|
||||
extern void irq0();
|
||||
extern void irq1();
|
||||
extern void irq2();
|
||||
extern void irq3();
|
||||
extern void irq4();
|
||||
extern void irq5();
|
||||
extern void irq6();
|
||||
extern void irq7();
|
||||
extern void irq8();
|
||||
extern void irq9();
|
||||
extern void irq10();
|
||||
extern void irq11();
|
||||
extern void irq12();
|
||||
extern void irq13();
|
||||
extern void irq14();
|
||||
extern void irq15();
|
||||
|
||||
void installIrqHandler(uint32_t irq, void (*handler)(struct regs* r)) {
|
||||
irqRoutines[irq] = handler;
|
||||
}
|
||||
|
||||
void uninstallIrqHandler(uint32_t irq) {
|
||||
irqRoutines[irq] = 0;
|
||||
}
|
||||
|
||||
void irqHandler(struct regs* r) {
|
||||
void (*handler)(struct regs* r);
|
||||
|
||||
handler = irqRoutines[r->intNo - 32]; // Offset by 32 because of isrs
|
||||
if (handler) handler(r);
|
||||
|
||||
// Something about master and slave handlers
|
||||
if (r->intNo >= 40) outb(0xa0, 0x20);
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
|
||||
void irqRemap(void) {
|
||||
outb(0xa0, 0x11);
|
||||
outb(0x20, 0x11);
|
||||
outb(0x21, 0x20);
|
||||
outb(0xa1, 0x28);
|
||||
outb(0x21, 0x04);
|
||||
outb(0xa1, 0x02);
|
||||
outb(0x21, 0x01);
|
||||
outb(0xa1, 0x01);
|
||||
outb(0x21, 0x0);
|
||||
outb(0xa1, 0x0);
|
||||
}
|
||||
|
||||
void setupIrqs() {
|
||||
irqRemap();
|
||||
|
||||
// Same as isrs, but differnet handlers :o
|
||||
idtSetGate(32, (unsigned)irq0, 0x08, 0x8e);
|
||||
idtSetGate(33, (unsigned)irq1, 0x08, 0x8e);
|
||||
idtSetGate(34, (unsigned)irq2, 0x08, 0x8e);
|
||||
idtSetGate(35, (unsigned)irq3, 0x08, 0x8e);
|
||||
idtSetGate(36, (unsigned)irq4, 0x08, 0x8e);
|
||||
idtSetGate(37, (unsigned)irq5, 0x08, 0x8e);
|
||||
idtSetGate(38, (unsigned)irq6, 0x08, 0x8e);
|
||||
idtSetGate(39, (unsigned)irq7, 0x08, 0x8e);
|
||||
idtSetGate(40, (unsigned)irq8, 0x08, 0x8e);
|
||||
idtSetGate(41, (unsigned)irq9, 0x08, 0x8e);
|
||||
idtSetGate(42, (unsigned)irq10, 0x08, 0x8e);
|
||||
idtSetGate(43, (unsigned)irq11, 0x08, 0x8e);
|
||||
idtSetGate(44, (unsigned)irq12, 0x08, 0x8e);
|
||||
idtSetGate(45, (unsigned)irq13, 0x08, 0x8e);
|
||||
idtSetGate(46, (unsigned)irq14, 0x08, 0x8e);
|
||||
idtSetGate(47, (unsigned)irq15, 0x08, 0x8e);
|
||||
}
|
||||
|
||||
#endif
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
#ifndef ISRS_H
|
||||
#define ISRS_H
|
||||
|
||||
#include "idt.h"
|
||||
#include "screen.h"
|
||||
#include "system.h"
|
||||
#include "string.h"
|
||||
|
||||
char* exceptionMessages[] = {
|
||||
"Divide By Zero Error",
|
||||
"Debug Exception",
|
||||
"NMI Interrupt",
|
||||
"Breakpoint",
|
||||
"Overflow",
|
||||
"BOUND Range Exceeded",
|
||||
"Invalid Opcode",
|
||||
"Device Not Available",
|
||||
"Double Fault",
|
||||
"Coprocessor Segment Overrun",
|
||||
"Invalid TSS",
|
||||
"Segment Not Present",
|
||||
"Stack-Segment Fault",
|
||||
"General Protection Fault",
|
||||
"Page Fault",
|
||||
"Reserved",
|
||||
"x87 FPU Floating-Point Error",
|
||||
"Alignment Check",
|
||||
"Machine Check",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
};
|
||||
|
||||
|
||||
// Repetative isr definitions
|
||||
extern void isr0();
|
||||
extern void isr1();
|
||||
extern void isr2();
|
||||
extern void isr3();
|
||||
extern void isr4();
|
||||
extern void isr5();
|
||||
extern void isr6();
|
||||
extern void isr7();
|
||||
extern void isr8();
|
||||
extern void isr9();
|
||||
extern void isr10();
|
||||
extern void isr11();
|
||||
extern void isr12();
|
||||
extern void isr13();
|
||||
extern void isr14();
|
||||
extern void isr15();
|
||||
extern void isr16();
|
||||
extern void isr17();
|
||||
extern void isr18();
|
||||
extern void isr19();
|
||||
extern void isr20();
|
||||
extern void isr21();
|
||||
extern void isr22();
|
||||
extern void isr23();
|
||||
extern void isr24();
|
||||
extern void isr25();
|
||||
extern void isr26();
|
||||
extern void isr27();
|
||||
extern void isr28();
|
||||
extern void isr29();
|
||||
extern void isr30();
|
||||
extern void isr31();
|
||||
|
||||
void setupIsrs() {
|
||||
idtSetGate(0, (unsigned)isr0, 0x08, 0x8e);
|
||||
idtSetGate(1, (unsigned)isr1, 0x08, 0x8e);
|
||||
idtSetGate(2, (unsigned)isr2, 0x08, 0x8e);
|
||||
idtSetGate(3, (unsigned)isr3, 0x08, 0x8e);
|
||||
idtSetGate(4, (unsigned)isr4, 0x08, 0x8e);
|
||||
idtSetGate(5, (unsigned)isr5, 0x08, 0x8e);
|
||||
idtSetGate(6, (unsigned)isr6, 0x08, 0x8e);
|
||||
idtSetGate(7, (unsigned)isr7, 0x08, 0x8e);
|
||||
idtSetGate(8, (unsigned)isr8, 0x08, 0x8e);
|
||||
idtSetGate(9, (unsigned)isr9, 0x08, 0x8e);
|
||||
idtSetGate(10, (unsigned)isr10, 0x08, 0x8e);
|
||||
idtSetGate(11, (unsigned)isr11, 0x08, 0x8e);
|
||||
idtSetGate(12, (unsigned)isr12, 0x08, 0x8e);
|
||||
idtSetGate(13, (unsigned)isr13, 0x08, 0x8e);
|
||||
idtSetGate(14, (unsigned)isr14, 0x08, 0x8e);
|
||||
idtSetGate(15, (unsigned)isr15, 0x08, 0x8e);
|
||||
idtSetGate(16, (unsigned)isr16, 0x08, 0x8e);
|
||||
idtSetGate(17, (unsigned)isr17, 0x08, 0x8e);
|
||||
idtSetGate(18, (unsigned)isr18, 0x08, 0x8e);
|
||||
idtSetGate(19, (unsigned)isr19, 0x08, 0x8e);
|
||||
idtSetGate(20, (unsigned)isr20, 0x08, 0x8e);
|
||||
idtSetGate(21, (unsigned)isr21, 0x08, 0x8e);
|
||||
idtSetGate(22, (unsigned)isr22, 0x08, 0x8e);
|
||||
idtSetGate(23, (unsigned)isr23, 0x08, 0x8e);
|
||||
idtSetGate(24, (unsigned)isr24, 0x08, 0x8e);
|
||||
idtSetGate(25, (unsigned)isr25, 0x08, 0x8e);
|
||||
idtSetGate(26, (unsigned)isr26, 0x08, 0x8e);
|
||||
idtSetGate(27, (unsigned)isr27, 0x08, 0x8e);
|
||||
idtSetGate(28, (unsigned)isr28, 0x08, 0x8e);
|
||||
idtSetGate(29, (unsigned)isr29, 0x08, 0x8e);
|
||||
idtSetGate(30, (unsigned)isr30, 0x08, 0x8e);
|
||||
idtSetGate(31, (unsigned)isr31, 0x08, 0x8e);
|
||||
}
|
||||
|
||||
void faultHandler(struct regs* r) {
|
||||
if (r->intNo < 32) {
|
||||
print(exceptionMessages[r->intNo]);
|
||||
|
||||
if (r->errCode) {
|
||||
print(": 0x");
|
||||
print(itoa(r->errCode, 16));
|
||||
}
|
||||
|
||||
cli();
|
||||
hlt();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+3
-2
@@ -1,8 +1,8 @@
|
||||
#ifndef KEYBOARD_H
|
||||
#define KEYBOARD_H
|
||||
|
||||
#include "irq.h"
|
||||
#include "idt.h"
|
||||
#include "pic.h"
|
||||
#include "system.h"
|
||||
#include "screen.h"
|
||||
#include "stdint.h"
|
||||
@@ -92,7 +92,8 @@ char* read(char terminator) {
|
||||
}
|
||||
|
||||
void setupKeyboard() {
|
||||
installIrqHandler(1, keyboardHandler);
|
||||
idtSetGate(33, keyboardHandler, INT_GATE_FLAGS);
|
||||
setIrqMask(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#ifndef PIC_H
|
||||
#define PIC_H
|
||||
|
||||
#include "system.h"
|
||||
|
||||
// PIC I/O Ports
|
||||
#define PIC_1_CMD 0x20
|
||||
#define PIC_1_DATA 0x21
|
||||
#define PIC_2_CMD 0xA0
|
||||
#define PIC_2_DATA 0xA1
|
||||
|
||||
// IRQs
|
||||
#define NEW_IRQ_0 0x20 // IRQ 0 : int 32
|
||||
#define NEW_IRQ_8 0x28 // IRQ 8 : int 40
|
||||
|
||||
// Commands
|
||||
#define PIC_EOI 0x20 // End Of Interrupt
|
||||
#define PIC_DISABLE 0xff
|
||||
|
||||
void sendPicEOI(uint8_t irq) {
|
||||
if (irq >= 8) {
|
||||
outb(PIC_2_CMD, PIC_EOI);
|
||||
}
|
||||
outb(PIC_1_CMD, PIC_EOI);
|
||||
}
|
||||
|
||||
void disableIrqs() {
|
||||
outb(PIC_2_DATA, PIC_DISABLE);
|
||||
outb(PIC_1_DATA, PIC_DISABLE);
|
||||
}
|
||||
|
||||
void setIrqMask(uint8_t irq) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (irq < 8) {
|
||||
port = PIC_1_DATA;
|
||||
} else {
|
||||
irq -= 8;
|
||||
port = PIC_2_DATA;
|
||||
}
|
||||
|
||||
value = inb(port) | (1 << irq);
|
||||
outb(port, value);
|
||||
}
|
||||
|
||||
void unsetIrqMask(uint8_t irq) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (irq < 8) {
|
||||
port = PIC_1_DATA;
|
||||
} else {
|
||||
irq -= 8;
|
||||
port = PIC_2_DATA;
|
||||
}
|
||||
|
||||
value = inb(port) & ~(1 << irq);
|
||||
outb(port, value);
|
||||
}
|
||||
|
||||
void remapPic() {
|
||||
uint8_t pic1Mask = inb(PIC_1_DATA);
|
||||
uint8_t pic2Mask = inb(PIC_2_DATA);
|
||||
|
||||
// Send Init Control Word 1-4 to both PICs
|
||||
// ICW 1: bit 0 - send up to 4 ICWs, bit 4 - Init PIC
|
||||
outb(PIC_1_CMD, 0x11);
|
||||
ioWait(); // For slower machines
|
||||
outb(PIC_2_CMD, 0x11);
|
||||
ioWait();
|
||||
|
||||
// ICW 2: Where to map IRW bases in IDT
|
||||
outb(PIC_1_DATA, NEW_IRQ_0);
|
||||
ioWait();
|
||||
outb(PIC_2_DATA, NEW_IRQ_8);
|
||||
ioWait();
|
||||
|
||||
// ICW 3: Which IRQ in PIC1 is PIC2; Mapping PIC2 to IRQ 2
|
||||
outb(PIC_1_DATA, 0x04);
|
||||
ioWait();
|
||||
outb(PIC_2_DATA, 0x02);
|
||||
ioWait();
|
||||
|
||||
// ICW 4 - Set x86 mode
|
||||
outb(PIC_1_DATA, 0x01);
|
||||
ioWait();
|
||||
outb(PIC_2_DATA, 0x01);
|
||||
ioWait();
|
||||
|
||||
outb(PIC_1_DATA, pic1Mask);
|
||||
outb(PIC_2_DATA, pic2Mask);
|
||||
}
|
||||
|
||||
#endif
|
||||
+5
-3
@@ -93,9 +93,11 @@ uint32_t convertColor(uint32_t color) {
|
||||
return color & 0xff;
|
||||
}
|
||||
|
||||
uint8_t red = ((color >> 16) & 0xff) * (((1 << gfxMode->linearRedMaskSize) - 1) / 255.0);
|
||||
uint8_t green = ((color >> 8 ) & 0xff) * (((1 << gfxMode->linearGreenMaskSize) - 1) / 255.0);
|
||||
uint8_t blue = ((color ) & 0xff) * (((1 << gfxMode->linearBlueMaskSize) - 1) / 255.0);
|
||||
// TODO: !! Important !! - Is should be divided by 255.0 (for floats), but using '-mgeneral-regs-only' removes fp-registers and
|
||||
// wants to use some dumb functions for converting fp numbers in the stdlib (that we don't have)
|
||||
uint8_t red = ((color >> 16) & 0xff) * (((1 << gfxMode->linearRedMaskSize) - 1) / 255);
|
||||
uint8_t green = ((color >> 8 ) & 0xff) * (((1 << gfxMode->linearGreenMaskSize) - 1) / 255);
|
||||
uint8_t blue = ((color ) & 0xff) * (((1 << gfxMode->linearBlueMaskSize) - 1) / 255);
|
||||
|
||||
return (red << gfxMode->redFieldPos) | (green << gfxMode->greenFieldPos) | (blue << gfxMode->blueFieldPos);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef SYSCALL_H
|
||||
#define SYSCALL_H
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
// System call count
|
||||
#define MAX_SYSCALLS 2
|
||||
|
||||
void sys_test0() {
|
||||
fgColor = YELLOW;
|
||||
print("Syscall 0 - Test\n");
|
||||
fgColor = FG_COLOR;
|
||||
}
|
||||
|
||||
void sys_test1() {
|
||||
fgColor = CYAN;
|
||||
print("Syscall 1 - Test\n");
|
||||
fgColor = FG_COLOR;
|
||||
}
|
||||
|
||||
// System call table
|
||||
void* syscalls[MAX_SYSCALLS] = {
|
||||
sys_test0,
|
||||
sys_test1,
|
||||
};
|
||||
|
||||
// int 0x80 - Syscall interrupt, handled by this function
|
||||
// eax : Syscall number
|
||||
__attribute__ ((naked)) // No prologue or epilogue, just assembly
|
||||
void syscallHandler(void) {
|
||||
// Interrupt - Stack should contain: ss, esp, eflags, cs, eip
|
||||
// We should also push these regs: ax, gs, fs, es, ds, bp, di, si, dx, cx, bx
|
||||
__asm__ volatile (
|
||||
".intel_syntax noprefix\n" // We use intel syntax
|
||||
".equ MAX_SYSCALLS, 2\n" // Define MAX_SYSCALLS again
|
||||
|
||||
// Check if syscall exists
|
||||
"cmp eax, MAX_SYSCALLS - 1\n"
|
||||
"ja invalidSyscall\n"
|
||||
|
||||
// Call the syscall
|
||||
"push eax\n" // Push required values
|
||||
"push gs\n"
|
||||
"push fs\n"
|
||||
"push es\n"
|
||||
"push ds\n"
|
||||
"push ebp\n"
|
||||
"push edi\n"
|
||||
"push esi\n"
|
||||
"push edx\n"
|
||||
"push ecx\n"
|
||||
"push ebx\n"
|
||||
"push esp\n" // Push stack pointer again (for variables and such idk)
|
||||
"call [syscalls + eax * 4]\n" // Call syscall from table. Syscall number should be in eax
|
||||
"add esp, 4\n"
|
||||
"pop ebx\n" // Pop pushed values
|
||||
"pop ecx\n"
|
||||
"pop edx\n"
|
||||
"pop esi\n"
|
||||
"pop edi\n"
|
||||
"pop ebp\n"
|
||||
"pop ds\n"
|
||||
"pop es\n"
|
||||
"pop fs\n"
|
||||
"pop gs\n"
|
||||
"add esp, 4\n" // Save eax value
|
||||
"iretd\n" // Return from interrupt
|
||||
|
||||
// TODO: Send an error or something here
|
||||
"invalidSyscall:\n"
|
||||
"iretd\n"
|
||||
|
||||
".att_syntax" // Switch back to Att Syntax (Just in case)
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
+3
-12
@@ -24,18 +24,9 @@ void outw(uint16_t port, uint16_t data) {
|
||||
asm volatile("outw %0, %1" :: "a"(data), "Nd"(port));
|
||||
}
|
||||
|
||||
|
||||
// Assembly stuff
|
||||
void cli() {
|
||||
asm volatile("cli");
|
||||
}
|
||||
|
||||
void sti() {
|
||||
asm volatile("sti");
|
||||
}
|
||||
|
||||
void hlt() {
|
||||
asm volatile("hlt");
|
||||
void ioWait() {
|
||||
// Waits ~1 I/O Cycle (Linux uses this so it should be good)
|
||||
asm volatile("outb %%al, $0x80" : : "a"(0));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
-345
@@ -3,9 +3,6 @@
|
||||
[global driveNum]
|
||||
|
||||
[extern main]
|
||||
[extern idtp]
|
||||
[extern faultHandler]
|
||||
[extern irqHandler]
|
||||
|
||||
;; Calls the main function in 'main.c'
|
||||
_start:
|
||||
@@ -23,345 +20,3 @@ _start:
|
||||
|
||||
driveNum: db 0
|
||||
|
||||
;;
|
||||
;; --- IDT ---
|
||||
;;
|
||||
[global idtLoad]
|
||||
idtLoad:
|
||||
lidt [idtp]
|
||||
ret
|
||||
|
||||
;; Isrs (exceptions)
|
||||
[global isr0]
|
||||
isr0:
|
||||
cli
|
||||
push 0
|
||||
push 0
|
||||
jmp isrCommon
|
||||
[global isr1]
|
||||
isr1:
|
||||
cli
|
||||
push 0
|
||||
push 1
|
||||
jmp isrCommon
|
||||
[global isr2]
|
||||
isr2:
|
||||
cli
|
||||
push 0
|
||||
push 2
|
||||
jmp isrCommon
|
||||
[global isr3]
|
||||
isr3:
|
||||
cli
|
||||
push 0
|
||||
push 3
|
||||
jmp isrCommon
|
||||
[global isr4]
|
||||
isr4:
|
||||
cli
|
||||
push 0
|
||||
push 4
|
||||
jmp isrCommon
|
||||
[global isr5]
|
||||
isr5:
|
||||
cli
|
||||
push 0
|
||||
push 5
|
||||
jmp isrCommon
|
||||
[global isr6]
|
||||
isr6:
|
||||
cli
|
||||
push 0
|
||||
push 6
|
||||
jmp isrCommon
|
||||
[global isr7]
|
||||
isr7:
|
||||
cli
|
||||
push 0
|
||||
push 7
|
||||
jmp isrCommon
|
||||
[global isr8]
|
||||
isr8:
|
||||
cli
|
||||
push 8
|
||||
jmp isrCommon
|
||||
[global isr9]
|
||||
isr9:
|
||||
cli
|
||||
push 0
|
||||
push 9
|
||||
jmp isrCommon
|
||||
[global isr10]
|
||||
isr10:
|
||||
cli
|
||||
push 10
|
||||
jmp isrCommon
|
||||
[global isr11]
|
||||
isr11:
|
||||
cli
|
||||
push 11
|
||||
jmp isrCommon
|
||||
[global isr12]
|
||||
isr12:
|
||||
cli
|
||||
push 12
|
||||
jmp isrCommon
|
||||
[global isr13]
|
||||
isr13:
|
||||
cli
|
||||
push 13
|
||||
jmp isrCommon
|
||||
[global isr14]
|
||||
isr14:
|
||||
cli
|
||||
push 14
|
||||
jmp isrCommon
|
||||
[global isr15]
|
||||
isr15:
|
||||
cli
|
||||
push 0
|
||||
push 15
|
||||
jmp isrCommon
|
||||
[global isr16]
|
||||
isr16:
|
||||
cli
|
||||
push 0
|
||||
push 16
|
||||
jmp isrCommon
|
||||
[global isr17]
|
||||
isr17:
|
||||
cli
|
||||
push 0
|
||||
push 17
|
||||
jmp isrCommon
|
||||
[global isr18]
|
||||
isr18:
|
||||
cli
|
||||
push 0
|
||||
push 18
|
||||
jmp isrCommon
|
||||
[global isr19]
|
||||
isr19:
|
||||
cli
|
||||
push 0
|
||||
push 19
|
||||
jmp isrCommon
|
||||
[global isr20]
|
||||
isr20:
|
||||
cli
|
||||
push 0
|
||||
push 20
|
||||
jmp isrCommon
|
||||
[global isr21]
|
||||
isr21:
|
||||
cli
|
||||
push 0
|
||||
push 21
|
||||
jmp isrCommon
|
||||
[global isr22]
|
||||
isr22:
|
||||
cli
|
||||
push 0
|
||||
push 22
|
||||
jmp isrCommon
|
||||
[global isr23]
|
||||
isr23:
|
||||
cli
|
||||
push 0
|
||||
push 23
|
||||
jmp isrCommon
|
||||
[global isr24]
|
||||
isr24:
|
||||
cli
|
||||
push 0
|
||||
push 24
|
||||
jmp isrCommon
|
||||
[global isr25]
|
||||
isr25:
|
||||
cli
|
||||
push 0
|
||||
push 25
|
||||
jmp isrCommon
|
||||
[global isr26]
|
||||
isr26:
|
||||
cli
|
||||
push 0
|
||||
push 26
|
||||
jmp isrCommon
|
||||
[global isr27]
|
||||
isr27:
|
||||
cli
|
||||
push 0
|
||||
push 27
|
||||
jmp isrCommon
|
||||
[global isr28]
|
||||
isr28:
|
||||
cli
|
||||
push 0
|
||||
push 28
|
||||
jmp isrCommon
|
||||
[global isr29]
|
||||
isr29:
|
||||
cli
|
||||
push 0
|
||||
push 29
|
||||
jmp isrCommon
|
||||
[global isr30]
|
||||
isr30:
|
||||
cli
|
||||
push 0
|
||||
push 30
|
||||
jmp isrCommon
|
||||
[global isr31]
|
||||
isr31:
|
||||
cli
|
||||
push 0
|
||||
push 31
|
||||
jmp isrCommon
|
||||
|
||||
isrCommon: ; No clue how this works, i'm pretty sure it calls the C function and has to push the registers or something idk
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp
|
||||
push eax
|
||||
mov eax, faultHandler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
||||
|
||||
;; IRQs
|
||||
[global irq0]
|
||||
irq0:
|
||||
cli
|
||||
push 0
|
||||
push 32
|
||||
jmp irqCommon
|
||||
[global irq1]
|
||||
irq1:
|
||||
cli
|
||||
push 0
|
||||
push 33
|
||||
jmp irqCommon
|
||||
[global irq2]
|
||||
irq2:
|
||||
cli
|
||||
push 0
|
||||
push 34
|
||||
jmp irqCommon
|
||||
[global irq3]
|
||||
irq3:
|
||||
cli
|
||||
push 0
|
||||
push 35
|
||||
jmp irqCommon
|
||||
[global irq4]
|
||||
irq4:
|
||||
cli
|
||||
push 0
|
||||
push 36
|
||||
jmp irqCommon
|
||||
[global irq5]
|
||||
irq5:
|
||||
cli
|
||||
push 0
|
||||
push 37
|
||||
jmp irqCommon
|
||||
[global irq6]
|
||||
irq6:
|
||||
cli
|
||||
push 0
|
||||
push 38
|
||||
jmp irqCommon
|
||||
[global irq7]
|
||||
irq7:
|
||||
cli
|
||||
push 0
|
||||
push 39
|
||||
jmp irqCommon
|
||||
[global irq8]
|
||||
irq8:
|
||||
cli
|
||||
push 0
|
||||
push 40
|
||||
jmp irqCommon
|
||||
[global irq9]
|
||||
irq9:
|
||||
cli
|
||||
push 0
|
||||
push 41
|
||||
jmp irqCommon
|
||||
[global irq10]
|
||||
irq10:
|
||||
cli
|
||||
push 0
|
||||
push 42
|
||||
jmp irqCommon
|
||||
[global irq11]
|
||||
irq11:
|
||||
cli
|
||||
push 0
|
||||
push 43
|
||||
jmp irqCommon
|
||||
[global irq12]
|
||||
irq12:
|
||||
cli
|
||||
push 0
|
||||
push 44
|
||||
jmp irqCommon
|
||||
[global irq13]
|
||||
irq13:
|
||||
cli
|
||||
push 0
|
||||
push 45
|
||||
jmp irqCommon
|
||||
[global irq14]
|
||||
irq14:
|
||||
cli
|
||||
push 0
|
||||
push 46
|
||||
jmp irqCommon
|
||||
[global irq15]
|
||||
irq15:
|
||||
cli
|
||||
push 0
|
||||
push 47
|
||||
jmp irqCommon
|
||||
|
||||
irqCommon: ; Simular to isrCommon, probaly calls the C function
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp
|
||||
push eax
|
||||
mov eax, irqHandler
|
||||
call eax
|
||||
pop eax
|
||||
pop gs
|
||||
pop fs
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
add esp, 8
|
||||
iret
|
||||
|
||||
|
||||
+22
-19
@@ -1,14 +1,14 @@
|
||||
#include "physicalMemManager.h" // TODO: Name this better
|
||||
#include "disk.h"
|
||||
#include "screen.h"
|
||||
#include "idt.h"
|
||||
#include "isrs.h"
|
||||
#include "irq.h"
|
||||
#include "keyboard.h"
|
||||
#include "timer.h"
|
||||
#include "exceptions.h"
|
||||
#include "syscall.h"
|
||||
#include "pic.h"
|
||||
#include "system.h"
|
||||
#include "disk.h"
|
||||
#include "string.h"
|
||||
#include "graphics.h"
|
||||
#include "physicalMemManager.h" // TODO: Name this better
|
||||
#include "keyboard.h"
|
||||
|
||||
#define PROMPT "#> "
|
||||
|
||||
@@ -20,16 +20,6 @@ void printFiletable(char* ft);
|
||||
void printPhysicalMemmap();
|
||||
|
||||
void main() {
|
||||
// Interrupts
|
||||
setupIdt();
|
||||
setupIsrs();
|
||||
setupIrqs();
|
||||
sti();
|
||||
|
||||
setupKeyboard();
|
||||
setupTimer();
|
||||
timerPhase(1000); // 1 tick per ~1ms
|
||||
|
||||
// Memory manager setup
|
||||
uint32_t smapEntryCount = *(uint32_t*)0x8500;
|
||||
smapEntry_t* smapEntries = (smapEntry_t*)0x8504;
|
||||
@@ -46,14 +36,27 @@ void main() {
|
||||
deinitMemoryRegion(0x1000, 0x9000); // Reserve kernel memory (under 0xa000)
|
||||
deinitMemoryRegion(memmapAddr, maxBlocks / BLOCKS_PER_BYTE);
|
||||
|
||||
// Screen setup
|
||||
// TODO: Find font in filetable
|
||||
diskRead(36, 4, font); // Read font from disk
|
||||
|
||||
|
||||
clear();
|
||||
print("kern.\n\n");
|
||||
|
||||
diskRead(5, 1, filetable); // Read the filetable and store it in memory
|
||||
|
||||
// Interrupts
|
||||
setupIdt();
|
||||
setupExceptions();
|
||||
idtSetGate(0x80, syscallHandler, USR_INT_GAME_FLAGS); // Setup Syscall handler in IDT for int 0x80
|
||||
disableIrqs();
|
||||
remapPic();
|
||||
__asm__ volatile ("sti");
|
||||
|
||||
// Syscall Test!
|
||||
__asm__ volatile ("movl $0, %eax; int $0x80"); // Syscall(0);
|
||||
__asm__ volatile ("movl $1, %eax; int $0x80"); // Syscall(1);
|
||||
|
||||
//setupKeyboard();
|
||||
|
||||
// Run Interactive Shell Program
|
||||
// TODO: Make it in another file
|
||||
@@ -164,7 +167,7 @@ void main() {
|
||||
drawCircle(1500, 600, 300, WHITE);
|
||||
fillCircle(950, 750, 75, rgb(0xa2, 0xd6, 0xf9));
|
||||
|
||||
read('q'); // Wait until we get a 'q'
|
||||
//read('q'); // Wait until we get a 'q'
|
||||
clear();
|
||||
} else if (strcmp(input, "help") == 0) {
|
||||
print("Available Commands:\n");
|
||||
|
||||
+3
-3
@@ -372,9 +372,9 @@ DATA_SEG equ GDT.dataDescriptor - GDT.start
|
||||
|
||||
;; VBE Stuff
|
||||
;; !! IF YOU WANT TO SELECT ANY VALUE IN THE SETUP, SET THESE TO ZERO !!
|
||||
width: dw 0
|
||||
height: dw 0
|
||||
bpp: db 0
|
||||
width: dw 1920
|
||||
height: dw 1080
|
||||
bpp: db 32
|
||||
|
||||
offset: dw 0
|
||||
_segment: dw 0 ; segment is a keyword
|
||||
|
||||
Reference in New Issue
Block a user