diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/.gitignore | 1 | ||||
| -rw-r--r-- | kernel/acpi.c | 169 | ||||
| -rw-r--r-- | kernel/acpi.h | 125 | ||||
| -rw-r--r-- | kernel/asm_inline.h | 207 | ||||
| -rw-r--r-- | kernel/cpu_info.c | 98 | ||||
| -rw-r--r-- | kernel/cpu_info.h | 23 | ||||
| -rw-r--r-- | kernel/gdt.c | 285 | ||||
| -rw-r--r-- | kernel/gdt.h | 93 | ||||
| -rw-r--r-- | kernel/generate_vectors.py | 19 | ||||
| -rw-r--r-- | kernel/idt.c | 131 | ||||
| -rw-r--r-- | kernel/idt.h | 287 | ||||
| -rw-r--r-- | kernel/interrupts/common.s | 94 | ||||
| -rw-r--r-- | kernel/interrupts/generic.c | 95 | ||||
| -rw-r--r-- | kernel/interrupts/generic.h | 33 | ||||
| -rw-r--r-- | kernel/interrupts/vectors.s | 1543 | ||||
| -rw-r--r-- | kernel/kernel.c | 131 | ||||
| -rw-r--r-- | kernel/kprintf.c | 259 | ||||
| -rw-r--r-- | kernel/kprintf.h | 3 | ||||
| -rw-r--r-- | kernel/linker.ld | 51 | ||||
| -rw-r--r-- | kernel/loader.s | 32 | ||||
| -rw-r--r-- | kernel/makefile | 25 | ||||
| -rw-r--r-- | kernel/memops.c | 36 | ||||
| -rw-r--r-- | kernel/memops.h | 8 | ||||
| -rw-r--r-- | kernel/segments.s | 21 | ||||
| -rw-r--r-- | kernel/uefi.h | 104 |
25 files changed, 3873 insertions, 0 deletions
diff --git a/kernel/.gitignore b/kernel/.gitignore new file mode 100644 index 0000000..a8a0dce --- /dev/null +++ b/kernel/.gitignore @@ -0,0 +1 @@ +*.bin diff --git a/kernel/acpi.c b/kernel/acpi.c new file mode 100644 index 0000000..5879d05 --- /dev/null +++ b/kernel/acpi.c @@ -0,0 +1,169 @@ +#include "acpi.h" +#include "memops.h" +#include "kprintf.h" +#include "asm_inline.h" + +#include <stddef.h> + +void* getPointerToOtherSDT(ACPISDTHeader* header) +{ + uint8_t* base = (uint8_t*)header; + return &(base[36]); +} + +void* getACPITablesPointer(APICHeader* header) +{ + uint8_t* base = (uint8_t*)header; + return &(base[44]); +} + +#define IS_TABLE(x, header) kmemcmp(x, header->signature, 4*sizeof(uint8_t)) + +enum ACPI_TABLES getTableType(ACPISDTHeader* header) +{ + if(IS_TABLE("APIC", header)) return APIC; + if(IS_TABLE("BGRT", header)) return BGRT; + if(IS_TABLE("BERT", header)) return BERT; + if(IS_TABLE("CPEP", header)) return CPEP; + if(IS_TABLE("DSDT", header)) return DSDT; + if(IS_TABLE("ECDT", header)) return ECDT; + if(IS_TABLE("EINJ", header)) return EINJ; + if(IS_TABLE("ERST", header)) return ERST; + if(IS_TABLE("FACP", header)) return FACP; + if(IS_TABLE("FACS", header)) return FACS; + if(IS_TABLE("HEST", header)) return HEST; + if(IS_TABLE("MSCT", header)) return MSCT; + if(IS_TABLE("MPST", header)) return MPST; + if(IS_TABLE("OEMx", header)) return OEMx; + if(IS_TABLE("PMTT", header)) return PMTT; + if(IS_TABLE("PSDT", header)) return PSDT; + if(IS_TABLE("RASF", header)) return RASF; + if(IS_TABLE("RSDT", header)) return RSDT; + if(IS_TABLE("SBST", header)) return SBST; + if(IS_TABLE("SLIT", header)) return SLIT; + if(IS_TABLE("SRAT", header)) return SRAT; + if(IS_TABLE("SSDT", header)) return SSDT; + if(IS_TABLE("XSDT", header)) return XSDT; + if(IS_TABLE("HPET", header)) return HPET; + + return NONE; +} + +void* getTable(void* xsdt, enum ACPI_TABLES table) +{ + ACPISDTHeader* header = (ACPISDTHeader*)xsdt; + uint64_t* tables = (uint64_t*)getPointerToOtherSDT(xsdt); + uint64_t entries = (header->length - sizeof(ACPISDTHeader)) / 8; + + for(int i = 0; i < entries; i++) + { + uint64_t table_ptr = tables[i]; + + if(getTableType((ACPISDTHeader*)table_ptr) == table) + { + return (ACPISDTHeader*)table_ptr; + } + } + + return NULL; +} + +void* getAPIC(APICHeader* header, enum APIC_TYPE apic) +{ + header->length; + uint8_t* apic_tables = (uint8_t*)getACPITablesPointer(header); + APICEntry* entry = (APICEntry*)apic_tables; + uint8_t offset = 0; + + while(offset < (header->length - sizeof(APICHeader))) + { + APICEntry* entry = (APICEntry*)&(apic_tables[offset]); + if(entry->type == apic) + { + return entry; + } + + offset += entry->length; + } + + return NULL; +} + +uint64_t numberTables(APICHeader* header) +{ + header->length; + uint8_t* apic_tables = (uint8_t*)getACPITablesPointer(header); + APICEntry* entry = (APICEntry*)apic_tables; + uint8_t offset = 0; + uint64_t tables = 0; + + while(offset < (header->length - sizeof(APICHeader))) + { + /* + APICEntry* entry = (APICEntry*)&(apic_tables[offset]); + if(entry->type == apic) + { + return entry; + } + */ + + tables++; + offset += entry->length; + } + + return tables; +} + +void init_acpi(XSDP* xsdp) +{ + kprintf("=> Initializing ACPI\n"); + + uint64_t pic_master = inb(0x21); + uint64_t pic_slave = inb(0xA1); + + if((pic_master == 0xFF) && (pic_slave == 0xFF)) + { + kprintf("==> PIC disabled\n"); + } + + if(xsdp != NULL) + { + kprintf("==> ACPI 2.0 Found\n"); + } + else + { + kprintf("==X No ACPI 2.0 Found\n"); + return; + } + + ACPISDTHeader* xsdt = (ACPISDTHeader*)xsdp->xsdtaddress; + + APICHeader* apic_table = (APICHeader*)getTable(xsdt, APIC); + if(apic_table == NULL) + { + kprintf("==X Failed To Find APIC Table\n"); + return; + } + + kprintf("==> Found APIC Table\n"); + if(apic_table->flags >= 0) + { + kprintf("==> Dual 8259 PIC Found\n"); + } + + IOAPICTable* ioapic = getAPIC(apic_table, IOAPIC); + if(ioapic == NULL) + { + kprintf("==X Failed to find a valid IOAPIC\n"); + return; + } + + uint64_t n_tables = numberTables(apic_table); + + kprintf("Number of Tables: %ld\n", n_tables); + + kprintf("==> IOAPIC Found\n"); + + + // kprintf("=> ACPI Initialized\n"); +} diff --git a/kernel/acpi.h b/kernel/acpi.h new file mode 100644 index 0000000..ec9eeaa --- /dev/null +++ b/kernel/acpi.h @@ -0,0 +1,125 @@ +#pragma once + +#include <stdint.h> + +typedef struct __attribute__((packed)) +{ + uint8_t signature[8]; + uint8_t checksum; + uint8_t OEMID[6]; + uint8_t revision; + uint32_t deprecated; + uint32_t length; + uint64_t xsdtaddress; + uint8_t extendedchecksum; + uint8_t reserved[3]; +} XSDP; + +typedef struct __attribute__((packed)) +{ + uint8_t signature[4]; + uint32_t length; + uint8_t revision; + uint8_t checksum; + uint8_t OEMID[6]; + uint8_t OEMTableId[8]; + uint32_t OEMRevision; + uint32_t creatorID; + uint32_t creatorrevision; +} ACPISDTHeader; + +typedef struct __attribute__((packed)) +{ + uint8_t siganture[4]; + uint32_t length; + uint8_t revision; + uint8_t checksum; + uint8_t OEMID[6]; + uint8_t OEMTableId[8]; + uint32_t OEMRevision; + uint32_t creatorID; + uint32_t creatorrevision; + + // APIC Fields + uint32_t l_ic_addr; + uint32_t flags; +} APICHeader; // At 44 byte starts the variable part; + +typedef struct __attribute__((packed)) +{ + uint8_t type; + uint8_t length; +} APICEntry; + +typedef struct __attribute__((packed)) +{ + uint8_t type; + uint8_t length; + uint8_t id; + uint8_t rsv; + uint32_t addr; + uint32_t si_base; +} IOAPICTable; + +enum ACPI_TABLES +{ + APIC, // <- MADT + BGRT, + BERT, + CPEP, + DSDT, + ECDT, + EINJ, + ERST, + FACP, // <- FADT + FACS, + HEST, + MSCT, + MPST, + OEMx, + PMTT, + PSDT, + RASF, + RSDT, + SBST, + SLIT, + SRAT, + SSDT, + XSDT, + HPET, + NONE +}; + +enum APIC_TYPE +{ + LAPIC = 0, + IOAPIC = 1, + ISO = 2, + NMI_S = 3, + LAPIC_NMI = 4, + LAPIC_AO = 5, + IOSAPIC = 6, + LSAPIC = 7, + PIS = 8, + PLX2APIC = 9, + LX2APIC_NMI = 0xA, + GICC = 0xB, + GICD = 0xC, + GIC_MSI_FRAME = 0xD, + GICR = 0xE, + GIC_ITS = 0xF, + MP_WAKEUP = 0x10, + CORE_PIC = 0x11, + LIO_PIC = 0x12, + HT_PIC = 0x13, + EIO_PIC = 0x14, + MSI_PIC = 0x15, + BIO_PIC = 0x16, + LPC_PIC = 0x17, + RINTC = 0x18, + IMSIC = 0x19, + APLIC = 0x20, + PLIC = 0x21 +}; + +void init_acpi(XSDP* xsdp); diff --git a/kernel/asm_inline.h b/kernel/asm_inline.h new file mode 100644 index 0000000..7107618 --- /dev/null +++ b/kernel/asm_inline.h @@ -0,0 +1,207 @@ +#pragma once + +#include <stdint.h> + +// intel: +// mov dst, src +// mov eax, 16 +// mov eax, 0ffh +// +// move whats pointed by ebx into eax +// mov eax, [ebx] +// +// no need to use movb +// this already moves a byte +// mov al, 5 + +// registers +// +----------------+-----------------+-----------------+ +// | 8 Bit - No REX | 16 Bit - No REX | 32 Bit - No REX | +// +-------+--------+-----------------+-----------------| +// | AL | AH | AX | EAX | +// | BL | BH | BX | EBX | +// | CL | CH | CX | ECX | +// | DL | DH | DX | EDX | +// +-------+--------+ DI | EDI | +// +////////////////+ SI | EDI | +// +////////////////+ BP | EBP | +// +////////////////+ SP | ESP | +// +----------------+-----------------+-----------------+------------+ +// | 8 Bit - REX | 16 Bit - REX | 32 Bit - REX | 64 Bit | +// +----------------+-----------------+-----------------+------------+ +// | AL | AX | EAX | RAX | +// | BL | BX | EBX | RBX | +// | CL | CX | ECX | RCX | +// | DL | DX | EDX | RDX | +// | DIL | DI | EDI | RDI | +// | SIL | SI | ESI | RSI | +// | BPL | BP | EBP | RBP | +// | SPL | SP | ESP | RSP | +// | R8B | R8W | R8D | R8 | +// | R9B | R9W | R9D | R9 | +// | R10B | R10W | R10D | R10 | +// | R11B | R11W | R11D | R11 | +// | R12B | R12W | R12D | R12 | +// | R13B | R13W | R13D | R13 | +// | R14B | R14W | R14D | R14 | +// | R15B | R15W | R15D | R15 | +// +----------------+-----------------+-----------------+------------+ +// +// Special +// RFLAGS <- lower 32 bits used, upper reserved + +#define COM1 0x3f8 + +static inline void cli() +{ + asm volatile ("cli"); +} + +static inline void sti() +{ + asm volatile ("sti"); +} + +static inline void hlt() +{ + asm volatile("hlt"); +} + +static inline void cpuid_vendor(char* str) +{ + int* casted = (int*)str; + + asm volatile ("mov rax, 0; cpuid;" + : "=b" (casted[0]), "=d" (casted[1]), "=c" (casted[2]) + : // input in empty + : "eax"); // touched registers +} + + +static inline void cpuid(uint64_t leaf, uint64_t subleaf, uint32_t* a, uint32_t* b, uint32_t* c, uint32_t* d) +{ + uint32_t la, lb, lc, ld; + + asm volatile("cpuid;" + : "=a" (la), "=b" (lb), "=c" (lc), "=d" (ld) + : "a" (leaf), "c" (subleaf) + : + ); + + *a = la; + *b = lb; + *c = lc; + *d = ld; +} + +static inline uint64_t xchg(volatile uint64_t *addr, uint64_t newval) +{ + uint64_t result; + + // might need to reorder + asm volatile ("lock; xchgl %0, %1" : + "+m" (*addr), "=a" (result) : + "1" (newval) : + "cc"); + + return result; +} + +static inline void lcr3(uint64_t value) +{ + asm volatile ("mov cr3, %0" + : + : "r" (value) + : ); +} + +static inline void lgdt(void* ptr) +{ + asm volatile ("lgdt [%0];" : : "r" (ptr) ); +} + +static inline void lidt(void* ptr) +{ + asm volatile ("lidt [%0];" : : "r" (ptr)); +} + +static inline void ltr(unsigned short sel) +{ + asm volatile ("ltr %0" : : "r" (sel)); +} + +static inline uint64_t rrsp() +{ + uint64_t r; + + asm volatile ("mov %0, rsp" : "=r" (r) : ); + + return r; +} + +static inline void rdmsr(uint32_t msr, uint64_t* d, uint64_t* a) +{ + uint64_t ld; + uint64_t la; + + asm volatile("rdmsr" + : "=d" (ld), "=a" (la) + : "c" (msr) + ); + + *d = ld; + *a = la; +} + +static inline void fldcw(const uint16_t control) +{ + asm volatile("fldcw %0;"::"m"(control)); +} + +static inline void outb(uint16_t port, uint8_t val) +{ + asm volatile ( "outb %1, %0" + : + : "a"(val), "Nd"(port) ); +} + +static inline void outw(uint16_t port, uint16_t val) +{ + asm volatile ("outw %1, %0" + : + : "a"(val), "Nd"(port) ); +} + +static inline void outl(uint16_t port, uint32_t val) +{ + asm volatile ("outl %1, %0" + : + : "a"(val), "Nd"(port) ); +} + +static inline uint8_t inb(uint16_t port) +{ + uint8_t ret; + asm volatile ( "inb %0, %1" + : "=a"(ret) + : "Nd"(port) ); + return ret; +} + +static inline uint16_t inw(uint16_t port) +{ + uint16_t ret; + asm volatile ( "inb %0, %1" + : "=a"(ret) + : "Nd"(port) ); + return ret; +} + +static inline uint32_t inl(uint16_t port) +{ + uint32_t ret; + asm volatile ( "inb %0, %1" + : "=a"(ret) + : "Nd"(port) ); + return ret; +} diff --git a/kernel/cpu_info.c b/kernel/cpu_info.c new file mode 100644 index 0000000..aeb5a60 --- /dev/null +++ b/kernel/cpu_info.c @@ -0,0 +1,98 @@ +#include "cpu_info.h" +#include "asm_inline.h" + +enum LEAF1_ECX { + SSE3 = 1<<0, + PCLMULQDQ = 1<<1, + DTES64 = 1<<2, + MONITOR = 1<<3, + DS_CPL = 1<<4, + VMX = 1<<5, + SMX = 1<<6, + EIST = 1<<7, // Intel ? + TM2 = 1<<8, + SSSE3 = 1<<9, + L1_CONTEXT_ID = 1<<10, + DEBUG_INTERFACE = 1<<11, + FMA = 1<<12, + CMPXCHG16B = 1<<13, + XTPR_UPDATE_CONTROL = 1<<14, + PERF_CAPABILITIES = 1<<15, + // Reserved + PCID = 1<<17, + DCA = 1<<18, + SSE4_1 = 1<<19, + SSE4_2 = 1<<20, + X2APIC = 1<<21, + MOVBE = 1<<22, + POPCNT = 1<<23, + TSC_DEADLINE = 1<<24, + AESNI = 1<<25, + XSAVE = 1<<26, + OSXSAVE = 1<<27, + AVX = 1<<28, + F16C = 1<<29, + RDRAND = 1<<30 +}; + +enum LEAF1_EDX { + FPU = 1<<0, + VME = 1<<1, + DE = 1<<2, + PSE = 1<<3, + TSC = 1<<4, + MSR = 1<<5, + PAE = 1<<6, + MCE = 1<<7, + CMPXCHG8B = 1<<8, + APIC = 1<<9, + // Reserved + SEP = 1<<11, + MTRR = 1<<12, + PGE = 1<<13, + MCA = 1<<14, + CMOV = 1<<15, + PAT = 1<<16, + PSE_36 = 1<<17, + PSN = 1<<18, + CLFLUSH = 1<<19, + // Reserved + DS = 1<<21, + ACPI = 1<<22, + MMX = 1<<23, + FXSR = 1<<24, + SSE = 1<<25, + SSE2 = 1<<26, + SELF_SNOOP = 1<<27, + HTT = 1<<28, + TM = 1<<29, + // Reserved + PBE = 1<<31, +}; + +cpu_info info; + +void init_cpu_info() +{ + uint32_t rax, rbx, rcx, rdx; + cpuid(1, 0, &rax, &rbx, &rcx, &rdx); + + info.FPU = (rcx & FPU) == 1; + info.ACPI = (rcx & ACPI) == 1; + info.MMX = (rcx & MMX) == 1; + info.SSE = (rcx & SSE) == 1; + info.SSE2 = (rcx & SSE2) == 1; + + info.SSE3 = (rdx & SSE3) == 1; + info.SSSE3 = (rdx & SSSE3) == 1; + info.SSE41 = (rdx & SSE4_1) == 1; + info.SSE42 = (rdx & SSE4_2) == 1; + info.VMX = (rdx & VMX) == 1; + info.FMA = (rdx & FMA) == 1; + info.AVX = (rdx & AVX) == 1; +} + +const cpu_info* get_cpu_info() +{ + return &info; +} diff --git a/kernel/cpu_info.h b/kernel/cpu_info.h new file mode 100644 index 0000000..d2c1a5d --- /dev/null +++ b/kernel/cpu_info.h @@ -0,0 +1,23 @@ +#pragma once + +#include <stdbool.h> + +typedef struct { + bool FPU; + bool MMX; + bool SSE; + bool SSE2; + bool SSE3; + bool SSSE3; + bool SSE41; + bool SSE42; + bool AVX; + bool VMX; + bool FMA; + bool ACPI; + bool APIC; +} cpu_info; + +void init_cpu_info(); +const cpu_info* get_cpu_info(); + diff --git a/kernel/gdt.c b/kernel/gdt.c new file mode 100644 index 0000000..b6d2c3a --- /dev/null +++ b/kernel/gdt.c @@ -0,0 +1,285 @@ + +#include "gdt.h" +#include "kprintf.h" + +#include "asm_inline.h" +#include "memops.h" + +#define NULL_DESCRIPTOR 0 +#define KERNEL_CODE 1 +#define KERNEL_DATA 2 +#define USER_CODE 3 +#define USER_DATA 4 +#define TASK_STATE_SEGMENT_LOW 5 +#define TASK_STATE_SEGMENT_HIGH 6 + +__attribute__((aligned(0x08))) +uint64_t gdt[7]; + +gdt_load gdt_l; +tss tss_g; + +// #define KDEBUG + +extern void asm_reload_segments(); + +int init_gdt() +{ + /* + create_descriptor(NULL_DESCRIPTOR, 0, 0, 0, 0); + create_descriptor(KERNEL_CODE, 0, 0xFFFF, 0x9A, 0xA); + create_descriptor(KERNEL_DATA, 0, 0xFFFF, 0x92, 0xC); + create_descriptor(USER_CODE, 0, 0xFFFF, 0xFA, 0xA); + create_descriptor(USER_DATA, 0, 0xFFFF, 0xF2, 0xC); + */ + + + gdt[NULL_DESCRIPTOR] = 0x0000000000000000; + /* + gdt[KERNEL_CODE] = 0x0020980000000000; // Code, DPL=0, R/X + gdt[KERNEL_DATA] = 0x0000920000000000; // Data, DPL=0, W + gdt[USER_CODE] = 0x0020F80000000000; // Code, DPL=3, R/X + gdt[USER_DATA] = 0x0000F20000000000; // Data, DPL=3, W + */ + + code_segment kernel_code = { + .limit = 0xFFFF, + .base_low = 0x0, + .base_mid = 0x0, + .A = 0x0, + .R = 0x1, + .C = 0x0, // conforming, used for privilege changes, leave it for now + .one0 = 0x1, + .one1 = 0x1, + .DPL = 0x0, // 0 -> kernel code + .P = 0x1, + .limit_high = 0xF, + .AVL = 0x0, + .L = 0x1, + .D = 0x0, + .G = 0x1, + .base_high = 0x0 + }; + + data_segment kernel_data = { + .limit = 0xFFFF, + .base_low = 0x0, + .base_mid = 0x0, + .A = 0x0, + .W = 0x1, + .E = 0x0, + .zero = 0, + .one = 1, + .DPL = 0x0, + .P = 0x1, + .limit_high = 0xF, + .AVL = 0x0, + .L = 0x1, + .D = 0x0, + .G = 0x1, + .base_high = 0x0 + }; + + code_segment user_code = { + .limit = 0xFFFF, + .base_low = 0x0, + .base_mid = 0x0, + .A = 0x0, + .R = 0x1, // ? + .C = 0x0, // conforming, used for privilege changes, leave it for now + .one0 = 0x1, + .one1 = 0x1, + .DPL = 0x3, // 0 -> user code + .P = 0x1, + .limit_high = 0xF, + .AVL = 0x0, + .L = 0x1, + .D = 0x0, + .G = 0x1, + .base_high = 0x0 + }; + data_segment user_data = { + .limit = 0xFFFF, + .base_low = 0x0, + .base_mid = 0x0, + .A = 0x0, + .W = 0x1, + .E = 0x0, + .zero = 0, + .one = 1, + .DPL = 0x3, + .P = 0x1, + .limit_high = 0xF, + .AVL = 0x0, + .L = 0x1, + .D = 0x0, + .G = 0x1, + .base_high = 0x0 + }; + + //uint64_t addr = (uint64_t)tss_a; + //tss_a[16] = 0x00680000; + + tss_g.rsv0 = 0x0; + tss_g.rsp0 = rrsp(); // <- change with ring 0 stack pointer(who knows which one is it, need to allocate or reserve?) + tss_g.rsp1 = 0x0; + tss_g.rsp2 = 0x0; + tss_g.rsv1 = 0x0; + tss_g.ist2 = 0x0; + tss_g.ist3 = 0x0; + tss_g.ist4 = 0x0; + tss_g.ist5 = 0x0; + tss_g.ist6 = 0x0; + tss_g.ist7 = 0x0; + tss_g.rsv2 = 0x0; + tss_g.rsv3 = 0x0; + tss_g.io_base = sizeof(tss); + + uint64_t tss_m; + kmemcpy(&tss_g, &tss_m, sizeof(uint64_t)); + + tss_segment gdt_tss = { + .limit_low = 0xFFFF, + .base_low = tss_m & 0xFFFFFF, + .type = 0x9, // <- available tss ? (busy is 0xB) + .zero0 = 0x0, + .DPL = 0x0, + .P = 0x1, + .limit_high = 0xF, + .AVL = 0x0, + .zero1 = 0x0, + .zero2 = 0x0, + .G = 0x1, // <- maybe? + .base_high = (tss_m >> 24) & 0xFFFFFFFFFF, + .rsv1 = 0x0, + .zero3 = 0x0, + .rsv2 = 0x0, + }; + + /* + kmemcpy(&kernel_code, &gdt[KERNEL_CODE], sizeof(uint64_t)); + kmemcpy(&kernel_data, &gdt[KERNEL_DATA], sizeof(uint64_t)); + kmemcpy(&user_code, &gdt[USER_CODE], sizeof(uint64_t)); + kmemcpy(&user_data, &gdt[USER_DATA], sizeof(uint64_t)); + */ + kmemcpy(&gdt_tss, &gdt[TASK_STATE_SEGMENT_LOW], 2*sizeof(uint64_t)); + + uint64_t kc = convert_code_segment(&kernel_code); + uint64_t kd = convert_data_segment(&kernel_data); + uint64_t uc = convert_code_segment(&user_code); + uint64_t ud = convert_data_segment(&user_data); + + gdt[KERNEL_CODE] = kc; + // gdt[KERNEL_DATA] = kd; + gdt[KERNEL_DATA] = 0x0000920000000000; // maybe my code is wrong <- yes it is, no idea why, discovered, and can be safely hardcoded for 64bit + gdt[USER_CODE] = uc; + gdt[USER_DATA] = 0x0000920000000000; + // gdt[USER_DATA] = ud; + + /* + gdt[TASK_STATE_SEGMENT_LOW] = (0x0067) | ((addr & 0xFFFFFF) << 16) | + (0x00E9LL << 40) | (((addr >> 24) & 0xFF) << 56); + gdt[TASK_STATE_SEGMENT_HIGH] = (addr >> 32); + */ + + #ifdef KDEBUG + kprintf("gdt pointer: %p\n", gdt); + kprintf("KERNEL CODE: %lX\n", gdt[KERNEL_CODE]); + kprintf("KERNEL DATA: %lX\n", gdt[KERNEL_DATA]); + kprintf("USER CODE: %lX\n", gdt[USER_CODE]); + kprintf("USER DATA: %lX\n", gdt[USER_DATA]); + + + + kprintf("FUNCTION\n"); + + kprintf("KERNEL CODE: %lX\n", kc); + kprintf("KERNEL DATA: %lX\n", kd); + kprintf("USER CODE: %lX\n", uc); + kprintf("USER DATA: %lX\n", ud); + #endif + + gdt_l.size = 7 * sizeof(uint64_t) - 1; + gdt_l.ptr = (uint64_t)(gdt); + + lgdt(&gdt_l); + asm_reload_segments(); + + // ltr(TASK_STATE_SEGMENT_LOW << 3); + + create_system_segment_descriptor(); + + return 1; +} + +uint64_t create_descriptor(uint32_t base, uint32_t limit, uint8_t access_byte, uint16_t flag) +{ + // need to redo + uint64_t descriptor; + + descriptor = limit & 0x000F0000; + descriptor |= (flag << 8) & 0x00F0FF00; + descriptor |= (base >> 16) & 0x000000FF; + descriptor |= base & 0xFF000000; + + descriptor <<= 32; + + descriptor |= base << 16; + descriptor |= limit & 0x0000FFFF; + + return descriptor; +} + +void create_system_segment_descriptor() +{ + +} + +uint64_t convert_code_segment(code_segment* segment) +{ + uint64_t s = 0x0; + + s = segment->limit & 0xFFFF; + s |= (uint64_t)(segment->base_low & 0xFFFF) << 16; + s |= (uint64_t)(segment->base_mid & 0xFF) << 32; + s |= (uint64_t)(segment->A & 0x1) << 40; + s |= (uint64_t)(segment->R & 0x1) << 41; + s |= (uint64_t)(segment->C & 0x1) << 42; + s |= (uint64_t)(segment->one0 & 0x1) << 43; + s |= (uint64_t)(segment->one1 & 0x1) << 44; + s |= (uint64_t)(segment->DPL & 0x3) << 45; + s |= (uint64_t)(segment->P & 0x1) << 47; + s |= (uint64_t)(segment->limit_high & 0xF) << 48; + s |= (uint64_t)(segment->AVL & 0x1) << 52; + s |= (uint64_t)(segment->L & 0x1) << 53; + s |= (uint64_t)(segment->D & 0x1) << 54; + s |= (uint64_t)(segment->G & 0x1) << 55; + s |= (uint64_t)(segment->base_high) << 56; + + return s; +} + +uint64_t convert_data_segment(data_segment* segment) +{ + uint64_t s = 0x0; + uint32_t* ss = (uint32_t*)&s; + + s = segment->limit & 0xFFFF; + s |= (uint64_t)(segment->base_low & 0xFFFF) << 16; + s |= (uint64_t)(segment->base_mid & 0xFF) << 32; + s |= (uint64_t)(segment->A & 0x1) << 40; + s |= (uint64_t)(segment->W & 0x1) << 41; + s |= (uint64_t)(segment->E & 0x1) << 42; + s |= (uint64_t)(segment->one & 0x1) << 43; + s |= (uint64_t)(segment->zero & 0x1) << 44; + s |= (uint64_t)(segment->DPL & 0x3) << 45; + s |= (uint64_t)(segment->P & 0x1) << 47; + s |= (uint64_t)(segment->limit_high & 0xF) << 48; + s |= (uint64_t)(segment->AVL & 0x1) << 52; + s |= (uint64_t)(segment->L & 0x1) << 53; + s |= (uint64_t)(segment->D & 0x1) << 54; + s |= (uint64_t)(segment->G & 0x1) << 55; + s |= (uint64_t)(segment->base_high) << 56; + + return s; +} diff --git a/kernel/gdt.h b/kernel/gdt.h new file mode 100644 index 0000000..c0ba677 --- /dev/null +++ b/kernel/gdt.h @@ -0,0 +1,93 @@ +#pragma once + +#include <stdint.h> + +typedef struct __attribute__((packed)) +{ + uint16_t size; + uint64_t ptr; +} gdt_load; + +typedef struct __attribute__((packed)) +{ + uint64_t limit: 16; + uint64_t base_low: 16; + uint64_t base_mid: 8; + uint64_t A: 1; + uint64_t R: 1; + uint64_t C: 1; + uint64_t one0: 1; + uint64_t one1: 1; + uint64_t DPL: 2; + uint64_t P: 1; + uint64_t limit_high: 4; + uint64_t AVL: 1; + uint64_t L: 1; + uint64_t D: 1; + uint64_t G: 1; + uint64_t base_high: 8; +} code_segment; + +typedef struct __attribute__((packed)) +{ + uint64_t limit: 16; + uint64_t base_low: 16; + uint64_t base_mid: 8; + uint64_t A: 1; + uint64_t W: 1; + uint64_t E: 1; + uint64_t zero: 1; + uint64_t one: 1; + uint64_t DPL: 2; + uint64_t P: 1; + uint64_t limit_high: 4; + uint64_t AVL: 1; + uint64_t L: 1; + uint64_t D: 1; + uint64_t G: 1; + uint64_t base_high: 8; +} data_segment; + +typedef struct __attribute__((packed)) +{ + uint64_t limit_low: 16; + uint64_t base_low: 24; + uint64_t type: 4; + uint64_t zero0: 1; + uint64_t DPL: 2; + uint64_t P: 1; + uint64_t limit_high: 4; + uint64_t AVL: 1; + uint64_t zero1: 1; + uint64_t zero2: 1; + uint64_t G: 1; + uint64_t base_high: 40; + uint64_t rsv1: 8; + uint64_t zero3: 5; + uint64_t rsv2: 19; +} tss_segment; + +typedef struct __attribute__((packed)) +{ + uint32_t rsv0; + uint64_t rsp0; + uint64_t rsp1; + uint64_t rsp2; + uint64_t rsv1; + uint64_t ist1; + uint64_t ist2; + uint64_t ist3; + uint64_t ist4; + uint64_t ist5; + uint64_t ist6; + uint64_t ist7; + uint64_t rsv2; + uint16_t rsv3; + uint16_t io_base; +} tss; + +int init_gdt(); +uint64_t create_descriptor(uint32_t base, uint32_t limit, uint8_t access_byte, uint16_t flag); +uint64_t convert_code_segment(code_segment* segment); +uint64_t convert_data_segment(data_segment* segment); +void create_system_segment_descriptor(); diff --git a/kernel/generate_vectors.py b/kernel/generate_vectors.py new file mode 100644 index 0000000..8471ef8 --- /dev/null +++ b/kernel/generate_vectors.py @@ -0,0 +1,19 @@ +if __name__ == "__main__": + with open("interrupts/vectors.s", "w") as f: + for i in range(256): + f.write("global vector" + '{}'.format(i) + "\n") + f.write("extern s_trap_start\n") + f.write("extern s_trap_end\n") + f.write("\n") + f.write("section .text\n") + f.write("align 4\n") + f.write("\n") + for i in range(256): + upper = '{0:02X}'.format((i >> 16) & 0xFF) + lower = '{0:02X}'.format(i & 0xFF) + f.write("vector" + '{}'.format(i) + ":\n") + f.write(" push 0x" + upper + "\n") + f.write(" push 0x" + lower + "\n") + f.write(" jmp s_trap_start\n") + f.write("\n") + f.write("\n") diff --git a/kernel/idt.c b/kernel/idt.c new file mode 100644 index 0000000..01cee06 --- /dev/null +++ b/kernel/idt.c @@ -0,0 +1,131 @@ +#include "idt.h" +#include "memops.h" +#include "interrupts/generic.h" +#include "asm_inline.h" +#include "kprintf.h" + +extern void asm_generic_interrupt(); + +idt_load idt_l; +__attribute__((aligned(0x08))) +uint64_t idt[512] = {0}; + +#define VNM(x) vector##x + +void fill_idt(); + +void init_idt() +{ + /* + for(int i = 0; i < 512; i+=2) + { + gate g = { + // .target_offset = (uint64_t)asm_generic_interrupt, + .target_offset = (uint64_t)vector1, + .target_selector = 0x8, + .ist = 0x0, + .type = INT_INT, + .dpl = 0x0, + .p = true + }; + + uint64_t converted_gate[2]; + + make_int_gate(&g, converted_gate); + + kmemcpy(&converted_gate, &idt[i], 2*sizeof(uint64_t)); + } + */ + + fill_idt(); + + /* + kprintf("IDT ADDR: %p\n", idt); + kprintf("INTERRUPT ADDR: %p\n", asm_generic_interrupt); + */ + + idt_l.size = 256 * 2 * sizeof(uint64_t) - 1; + idt_l.ptr = (uint64_t)(idt); + + lidt(&idt_l); +} + +void make_call_gate(gate* g, uint64_t* rg) +{ + uint32_t* srg = (uint32_t*)rg; + // lower 64 + rg[0] = 0x0; + rg[1] = 0x0; + + srg[0] |= g->target_offset & 0xFFFF; + srg[0] |= (g->target_selector & 0xFFFF) << 16; + + // srg[1] |= (g->ist & 0xFF); + srg[1] |= (g->type & 0xFF ) << 8; + srg[1] |= (g->dpl & 0xFF) << 13; + srg[1] |= (g->p & 0xF) << 15; // <- this +16 (next field side is 61, so I did this wrong) <- this should offset by 47, to end in 48 + srg[1] |= ((g->target_offset >> 16) & 0xFFFF) << 16; + + srg[2] |= ((g->target_offset >> 32) & 0xFFFFFFFF); +} + +void make_int_gate(gate* g, uint64_t* rg) +{ + uint32_t* srg = (uint32_t*)rg; + // lower 64 + rg[0] = 0x0; + rg[1] = 0x0; + + srg[0] |= g->target_offset & 0xFFFF; + srg[0] |= (g->target_selector & 0xFFFF) << 16; + + srg[1] |= (g->ist & 0xFF); + srg[1] |= (g->type & 0xFF ) << 8; + srg[1] |= (g->dpl & 0xFF) << 13; + srg[1] |= (g->p & 0xF) << 15; // <- this +16 (next field side is 61, so I did this wrong) <- this should offset by 47, to end in 48 + // srg[1] |= ((g->target_offset >> 16) & 0xFFFF) << 16; + srg[1] |= g->target_offset & 0xFFFF0000; + + srg[2] |= ((g->target_offset >> 32) & 0xFFFFFFFF); +} + +#define MKI(x) make_gate((uint64_t) vector##x, x) + +void make_gate(uint64_t vector, uint32_t i) +{ + gate g = { + // .target_offset = (uint64_t)asm_generic_interrupt, + .target_offset = vector, + .target_selector = 0x8, + .ist = 0x0, + .type = INT_INT, + .dpl = 0x0, + .p = true + }; + + uint64_t converted_gate[2]; + + make_int_gate(&g, converted_gate); + + kmemcpy(&converted_gate, &idt[2*i], 2*sizeof(uint64_t)); +} + +void fill_idt() +{ + MKI(0); MKI(1); MKI(2); MKI(3); MKI(4); MKI(5); MKI(6); MKI(7); MKI(8); MKI(9); MKI(10); MKI(11); MKI(12); MKI(13); MKI(14); MKI(15); + MKI(16); MKI(17); MKI(18); MKI(19); MKI(20); MKI(21); MKI(22); MKI(23); MKI(24); MKI(25); MKI(26); MKI(27); MKI(28); MKI(29); MKI(30); MKI(31); + MKI(32); MKI(33); MKI(34); MKI(35); MKI(36); MKI(37); MKI(38); MKI(39); MKI(40); MKI(41); MKI(42); MKI(43); MKI(44); MKI(45); MKI(46); MKI(47); + MKI(48); MKI(49); MKI(50); MKI(51); MKI(52); MKI(53); MKI(54); MKI(55); MKI(56); MKI(57); MKI(58); MKI(59); MKI(60); MKI(61); MKI(62); MKI(63); + MKI(64); MKI(65); MKI(66); MKI(67); MKI(68); MKI(69); MKI(70); MKI(71); MKI(72); MKI(73); MKI(74); MKI(75); MKI(76); MKI(77); MKI(78); MKI(79); + MKI(80); MKI(81); MKI(82); MKI(83); MKI(84); MKI(85); MKI(86); MKI(87); MKI(88); MKI(89); MKI(90); MKI(91); MKI(92); MKI(93); MKI(94); MKI(95); + MKI(96); MKI(97); MKI(98); MKI(99); MKI(100); MKI(101); MKI(102); MKI(103); MKI(104); MKI(105); MKI(106); MKI(107); MKI(108); MKI(109); MKI(110); MKI(111); + MKI(112); MKI(113); MKI(114); MKI(115); MKI(116); MKI(117); MKI(118); MKI(119); MKI(120); MKI(121); MKI(122); MKI(123); MKI(124); MKI(125); MKI(126); MKI(127); + MKI(128); MKI(129); MKI(130); MKI(131); MKI(132); MKI(133); MKI(134); MKI(135); MKI(136); MKI(137); MKI(138); MKI(139); MKI(140); MKI(141); MKI(142); MKI(143); + MKI(144); MKI(145); MKI(146); MKI(147); MKI(148); MKI(149); MKI(150); MKI(151); MKI(152); MKI(153); MKI(154); MKI(155); MKI(156); MKI(157); MKI(158); MKI(159); + MKI(160); MKI(161); MKI(162); MKI(163); MKI(164); MKI(165); MKI(166); MKI(167); MKI(168); MKI(169); MKI(170); MKI(171); MKI(172); MKI(173); MKI(174); MKI(175); + MKI(176); MKI(177); MKI(178); MKI(179); MKI(180); MKI(181); MKI(182); MKI(183); MKI(184); MKI(185); MKI(186); MKI(187); MKI(188); MKI(189); MKI(190); MKI(191); + MKI(192); MKI(193); MKI(194); MKI(195); MKI(196); MKI(197); MKI(198); MKI(199); MKI(200); MKI(201); MKI(202); MKI(203); MKI(204); MKI(205); MKI(206); MKI(207); + MKI(208); MKI(209); MKI(210); MKI(211); MKI(212); MKI(213); MKI(214); MKI(215); MKI(216); MKI(217); MKI(218); MKI(219); MKI(220); MKI(221); MKI(222); MKI(223); + MKI(224); MKI(225); MKI(226); MKI(227); MKI(228); MKI(229); MKI(230); MKI(231); MKI(232); MKI(233); MKI(234); MKI(235); MKI(236); MKI(237); MKI(238); MKI(239); + MKI(240); MKI(241); MKI(242); MKI(243); MKI(244); MKI(245); MKI(246); MKI(247); MKI(248); MKI(249); MKI(250); MKI(251); MKI(252); MKI(253); MKI(254); MKI(255); +} diff --git a/kernel/idt.h b/kernel/idt.h new file mode 100644 index 0000000..74ae7f9 --- /dev/null +++ b/kernel/idt.h @@ -0,0 +1,287 @@ +#pragma once + +#include <stdint.h> +#include <stdbool.h> + +#define INT_CALL 0xC +#define INT_INT 0xE +#define INT_TRAP 0xF + +extern void vector0(); +extern void vector1(); +extern void vector2(); +extern void vector3(); +extern void vector4(); +extern void vector5(); +extern void vector6(); +extern void vector7(); +extern void vector8(); +extern void vector9(); +extern void vector10(); +extern void vector11(); +extern void vector12(); +extern void vector13(); +extern void vector14(); +extern void vector15(); +extern void vector16(); +extern void vector17(); +extern void vector18(); +extern void vector19(); +extern void vector20(); +extern void vector21(); +extern void vector22(); +extern void vector23(); +extern void vector24(); +extern void vector25(); +extern void vector26(); +extern void vector27(); +extern void vector28(); +extern void vector29(); +extern void vector30(); +extern void vector31(); +extern void vector32(); +extern void vector33(); +extern void vector34(); +extern void vector35(); +extern void vector36(); +extern void vector37(); +extern void vector38(); +extern void vector39(); +extern void vector40(); +extern void vector41(); +extern void vector42(); +extern void vector43(); +extern void vector44(); +extern void vector45(); +extern void vector46(); +extern void vector47(); +extern void vector48(); +extern void vector49(); +extern void vector50(); +extern void vector51(); +extern void vector52(); +extern void vector53(); +extern void vector54(); +extern void vector55(); +extern void vector56(); +extern void vector57(); +extern void vector58(); +extern void vector59(); +extern void vector60(); +extern void vector61(); +extern void vector62(); +extern void vector63(); +extern void vector64(); +extern void vector65(); +extern void vector66(); +extern void vector67(); +extern void vector68(); +extern void vector69(); +extern void vector70(); +extern void vector71(); +extern void vector72(); +extern void vector73(); +extern void vector74(); +extern void vector75(); +extern void vector76(); +extern void vector77(); +extern void vector78(); +extern void vector79(); +extern void vector80(); +extern void vector81(); +extern void vector82(); +extern void vector83(); +extern void vector84(); +extern void vector85(); +extern void vector86(); +extern void vector87(); +extern void vector88(); +extern void vector89(); +extern void vector90(); +extern void vector91(); +extern void vector92(); +extern void vector93(); +extern void vector94(); +extern void vector95(); +extern void vector96(); +extern void vector97(); +extern void vector98(); +extern void vector99(); +extern void vector100(); +extern void vector101(); +extern void vector102(); +extern void vector103(); +extern void vector104(); +extern void vector105(); +extern void vector106(); +extern void vector107(); +extern void vector108(); +extern void vector109(); +extern void vector110(); +extern void vector111(); +extern void vector112(); +extern void vector113(); +extern void vector114(); +extern void vector115(); +extern void vector116(); +extern void vector117(); +extern void vector118(); +extern void vector119(); +extern void vector120(); +extern void vector121(); +extern void vector122(); +extern void vector123(); +extern void vector124(); +extern void vector125(); +extern void vector126(); +extern void vector127(); +extern void vector128(); +extern void vector129(); +extern void vector130(); +extern void vector131(); +extern void vector132(); +extern void vector133(); +extern void vector134(); +extern void vector135(); +extern void vector136(); +extern void vector137(); +extern void vector138(); +extern void vector139(); +extern void vector140(); +extern void vector141(); +extern void vector142(); +extern void vector143(); +extern void vector144(); +extern void vector145(); +extern void vector146(); +extern void vector147(); +extern void vector148(); +extern void vector149(); +extern void vector150(); +extern void vector151(); +extern void vector152(); +extern void vector153(); +extern void vector154(); +extern void vector155(); +extern void vector156(); +extern void vector157(); +extern void vector158(); +extern void vector159(); +extern void vector160(); +extern void vector161(); +extern void vector162(); +extern void vector163(); +extern void vector164(); +extern void vector165(); +extern void vector166(); +extern void vector167(); +extern void vector168(); +extern void vector169(); +extern void vector170(); +extern void vector171(); +extern void vector172(); +extern void vector173(); +extern void vector174(); +extern void vector175(); +extern void vector176(); +extern void vector177(); +extern void vector178(); +extern void vector179(); +extern void vector180(); +extern void vector181(); +extern void vector182(); +extern void vector183(); +extern void vector184(); +extern void vector185(); +extern void vector186(); +extern void vector187(); +extern void vector188(); +extern void vector189(); +extern void vector190(); +extern void vector191(); +extern void vector192(); +extern void vector193(); +extern void vector194(); +extern void vector195(); +extern void vector196(); +extern void vector197(); +extern void vector198(); +extern void vector199(); +extern void vector200(); +extern void vector201(); +extern void vector202(); +extern void vector203(); +extern void vector204(); +extern void vector205(); +extern void vector206(); +extern void vector207(); +extern void vector208(); +extern void vector209(); +extern void vector210(); +extern void vector211(); +extern void vector212(); +extern void vector213(); +extern void vector214(); +extern void vector215(); +extern void vector216(); +extern void vector217(); +extern void vector218(); +extern void vector219(); +extern void vector220(); +extern void vector221(); +extern void vector222(); +extern void vector223(); +extern void vector224(); +extern void vector225(); +extern void vector226(); +extern void vector227(); +extern void vector228(); +extern void vector229(); +extern void vector230(); +extern void vector231(); +extern void vector232(); +extern void vector233(); +extern void vector234(); +extern void vector235(); +extern void vector236(); +extern void vector237(); +extern void vector238(); +extern void vector239(); +extern void vector240(); +extern void vector241(); +extern void vector242(); +extern void vector243(); +extern void vector244(); +extern void vector245(); +extern void vector246(); +extern void vector247(); +extern void vector248(); +extern void vector249(); +extern void vector250(); +extern void vector251(); +extern void vector252(); +extern void vector253(); +extern void vector254(); +extern void vector255(); + +typedef struct __attribute__((packed)) +{ + uint16_t size; + uint64_t ptr; +} idt_load; + +typedef struct __attribute__((packed)) +{ + uint64_t target_offset; + uint16_t target_selector; + uint8_t ist; // 3 bits + uint8_t type; // 4 bits + uint8_t dpl; + bool p; +} gate; + +void init_idt(); +void make_call_gate(gate* g, uint64_t* rg); +void make_int_gate(gate* g, uint64_t* rg); + + diff --git a/kernel/interrupts/common.s b/kernel/interrupts/common.s new file mode 100644 index 0000000..a03fb1c --- /dev/null +++ b/kernel/interrupts/common.s @@ -0,0 +1,94 @@ +extern generic_interrupt +global asm_generic_interrupt +global s_trap_start +global s_trap_end + +section .text +align 4 + +s_trap_start: + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rdi + push rsi + push rbp + push rdx + push rcx + push rbx + push rax + + mov rdi, rsp + call generic_interrupt + +s_trap_end: + pop rax + pop rbx + pop rcx + pop rdx + pop rbp + pop rsi + pop rdi + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + + add rsp, 16 + + iretq + +asm_generic_interrupt: + ;push 0x0 ; + ;push 0xE ; <- need to create the individual interrupts pushing the specific values to the stack (how to pop them?) + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rdi + push rsi + push rbp + push rdx + push rcx + push rbx + push rax + + ; ?? + ; cld + mov rdi, rsp + call generic_interrupt + + pop rax + pop rbx + pop rcx + pop rdx + pop rbp + pop rsi + pop rdi + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + ;pop + ;pop + + add rsp, 16 + + iretq diff --git a/kernel/interrupts/generic.c b/kernel/interrupts/generic.c new file mode 100644 index 0000000..900c7e3 --- /dev/null +++ b/kernel/interrupts/generic.c @@ -0,0 +1,95 @@ +#include "generic.h" +#include "../kprintf.h" +#include "../asm_inline.h" + +void generic_interrupt(trapframe* f) +{ + + kprintf("!!!! INTERRUPT !!!!\n"); + kprintf("ARG: %p\n", f); + switch(f->trapno) + { + case 0x0: + kprintf("NO: %s | ERR_ %lX\n", "Division Error", f->err); + break; + case 0x1: + kprintf("NO: %s | ERR_ %lX\n", "Debug", f->err); + break; + case 0x2: + kprintf("NO: %s | ERR_ %lX\n", "Non-Maskable", f->err); + break; + case 0x3: + kprintf("NO: %s | ERR_ %lX\n", "Breakpoint", f->err); + break; + case 0x4: + kprintf("NO: %s | ERR_ %lX\n", "Overflow", f->err); + break; + case 0x5: + kprintf("NO: %s | ERR_ %lX\n", "Bound Range Exceeded", f->err); + break; + case 0x6: + kprintf("NO: %s | ERR_ %lX\n", "Invalid Opcode", f->err); + break; + case 0x7: + kprintf("NO: %s | ERR_ %lX\n", "Device Not Available", f->err); + break; + case 0x8: + kprintf("NO: %s | ERR_ %lX\n", "Double Fault", f->err); + break; + case 0xA: + kprintf("NO: %s | ERR_ %lX\n", "Invalid TSS", f->err); + break; + case 0xB: + kprintf("NO: %s | ERR_ %lX\n", "Segment Not Present", f->err); + break; + case 0xC: + kprintf("NO: %s | ERR_ %lX\n", "Stack-Segment fault", f->err); + break; + case 0xD: + kprintf("NO: %s | ERR_ %lX\n", "General Protection Fault", f->err); + break; + case 0xE: + kprintf("NO: %s | ERR_ %lX\n", "Page Fault", f->err); + break; + case 0x10: + kprintf("NO: %s | ERR_ %lX\n", "x87 Floating Point Exception", f->err); + break; + case 0x11: + kprintf("NO: %s | ERR_ %lX\n", "Alignment Check", f->err); + break; + case 0x12: + kprintf("NO: %s | ERR_ %lX\n", "Machine Check", f->err); + break; + case 0x13: + kprintf("NO: %s | ERR_ %lX\n", "SIMD Floating Point Exception", f->err); + break; + case 0x14: + kprintf("NO: %s | ERR_ %lX\n", "Virtualization Exception", f->err); + break; + case 0x15: + kprintf("NO: %s | ERR_ %lX\n", "Control Protection Exception", f->err); + break; + case 0x1C: + kprintf("NO: %s | ERR_ %lX\n", "Hypervisor Injection Exception", f->err); + break; + case 0x1D: + kprintf("NO: %s | ERR_ %lX\n", "VMM Communication Exception", f->err); + break; + case 0x1E: + kprintf("NO: %s | ERR_ %lX\n", "Security Exception", f->err); + break; + default: + kprintf("NO: %lX | ERR: %lX\n", f->trapno, f->err); + } + kprintf("RAX: %lX | RBX: %lX | RCX: %lX | RDX: %lX\n", f->rax, f->rbx, f->rcx, f->rdx); + kprintf("RSI: %lX | RDI: %lX | RBP: %lX\n", f->rsi, f->rdi, f->rbp); + kprintf("R8: %lX | R9: %lX | R10: %lX | R11: %lX\n", f->r8, f->r9, f->r10, f->r11); + kprintf("R12: %lX | R13: %lX | R14: %lX | R15: %lX\n", f->r12, f->r13, f->r14, f->r15); + kprintf("===================\n"); + hlt(); + + //if(f->err == 0xE) + //{ + // hlt(); + //} +} diff --git a/kernel/interrupts/generic.h b/kernel/interrupts/generic.h new file mode 100644 index 0000000..aee4dde --- /dev/null +++ b/kernel/interrupts/generic.h @@ -0,0 +1,33 @@ +#pragma once + +#include <stdint.h> + +typedef struct { + uint64_t rax; // rax + uint64_t rbx; + uint64_t rcx; + uint64_t rdx; + uint64_t rbp; + uint64_t rsi; + uint64_t rdi; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + + uint64_t trapno; + uint64_t err; + + uint64_t rip; // rip + uint64_t cs; + uint64_t eflags; // rflags + uint64_t esp; // rsp + uint64_t ds; // ss +} trapframe; + +void generic_interrupt(trapframe* frame); + diff --git a/kernel/interrupts/vectors.s b/kernel/interrupts/vectors.s new file mode 100644 index 0000000..17f05d7 --- /dev/null +++ b/kernel/interrupts/vectors.s @@ -0,0 +1,1543 @@ +global vector0 +global vector1 +global vector2 +global vector3 +global vector4 +global vector5 +global vector6 +global vector7 +global vector8 +global vector9 +global vector10 +global vector11 +global vector12 +global vector13 +global vector14 +global vector15 +global vector16 +global vector17 +global vector18 +global vector19 +global vector20 +global vector21 +global vector22 +global vector23 +global vector24 +global vector25 +global vector26 +global vector27 +global vector28 +global vector29 +global vector30 +global vector31 +global vector32 +global vector33 +global vector34 +global vector35 +global vector36 +global vector37 +global vector38 +global vector39 +global vector40 +global vector41 +global vector42 +global vector43 +global vector44 +global vector45 +global vector46 +global vector47 +global vector48 +global vector49 +global vector50 +global vector51 +global vector52 +global vector53 +global vector54 +global vector55 +global vector56 +global vector57 +global vector58 +global vector59 +global vector60 +global vector61 +global vector62 +global vector63 +global vector64 +global vector65 +global vector66 +global vector67 +global vector68 +global vector69 +global vector70 +global vector71 +global vector72 +global vector73 +global vector74 +global vector75 +global vector76 +global vector77 +global vector78 +global vector79 +global vector80 +global vector81 +global vector82 +global vector83 +global vector84 +global vector85 +global vector86 +global vector87 +global vector88 +global vector89 +global vector90 +global vector91 +global vector92 +global vector93 +global vector94 +global vector95 +global vector96 +global vector97 +global vector98 +global vector99 +global vector100 +global vector101 +global vector102 +global vector103 +global vector104 +global vector105 +global vector106 +global vector107 +global vector108 +global vector109 +global vector110 +global vector111 +global vector112 +global vector113 +global vector114 +global vector115 +global vector116 +global vector117 +global vector118 +global vector119 +global vector120 +global vector121 +global vector122 +global vector123 +global vector124 +global vector125 +global vector126 +global vector127 +global vector128 +global vector129 +global vector130 +global vector131 +global vector132 +global vector133 +global vector134 +global vector135 +global vector136 +global vector137 +global vector138 +global vector139 +global vector140 +global vector141 +global vector142 +global vector143 +global vector144 +global vector145 +global vector146 +global vector147 +global vector148 +global vector149 +global vector150 +global vector151 +global vector152 +global vector153 +global vector154 +global vector155 +global vector156 +global vector157 +global vector158 +global vector159 +global vector160 +global vector161 +global vector162 +global vector163 +global vector164 +global vector165 +global vector166 +global vector167 +global vector168 +global vector169 +global vector170 +global vector171 +global vector172 +global vector173 +global vector174 +global vector175 +global vector176 +global vector177 +global vector178 +global vector179 +global vector180 +global vector181 +global vector182 +global vector183 +global vector184 +global vector185 +global vector186 +global vector187 +global vector188 +global vector189 +global vector190 +global vector191 +global vector192 +global vector193 +global vector194 +global vector195 +global vector196 +global vector197 +global vector198 +global vector199 +global vector200 +global vector201 +global vector202 +global vector203 +global vector204 +global vector205 +global vector206 +global vector207 +global vector208 +global vector209 +global vector210 +global vector211 +global vector212 +global vector213 +global vector214 +global vector215 +global vector216 +global vector217 +global vector218 +global vector219 +global vector220 +global vector221 +global vector222 +global vector223 +global vector224 +global vector225 +global vector226 +global vector227 +global vector228 +global vector229 +global vector230 +global vector231 +global vector232 +global vector233 +global vector234 +global vector235 +global vector236 +global vector237 +global vector238 +global vector239 +global vector240 +global vector241 +global vector242 +global vector243 +global vector244 +global vector245 +global vector246 +global vector247 +global vector248 +global vector249 +global vector250 +global vector251 +global vector252 +global vector253 +global vector254 +global vector255 +extern s_trap_start +extern s_trap_end + +section .text +align 4 + +vector0: + push 0x00 + push 0x00 + jmp s_trap_start + +vector1: + push 0x00 + push 0x01 + jmp s_trap_start + +vector2: + push 0x00 + push 0x02 + jmp s_trap_start + +vector3: + push 0x00 + push 0x03 + jmp s_trap_start + +vector4: + push 0x00 + push 0x04 + jmp s_trap_start + +vector5: + push 0x00 + push 0x05 + jmp s_trap_start + +vector6: + push 0x00 + push 0x06 + jmp s_trap_start + +vector7: + push 0x00 + push 0x07 + jmp s_trap_start + +vector8: + push 0x00 + push 0x08 + jmp s_trap_start + +vector9: + push 0x00 + push 0x09 + jmp s_trap_start + +vector10: + push 0x00 + push 0x0A + jmp s_trap_start + +vector11: + push 0x00 + push 0x0B + jmp s_trap_start + +vector12: + push 0x00 + push 0x0C + jmp s_trap_start + +vector13: + push 0x00 + push 0x0D + jmp s_trap_start + +vector14: + push 0x00 + push 0x0E + jmp s_trap_start + +vector15: + push 0x00 + push 0x0F + jmp s_trap_start + +vector16: + push 0x00 + push 0x10 + jmp s_trap_start + +vector17: + push 0x00 + push 0x11 + jmp s_trap_start + +vector18: + push 0x00 + push 0x12 + jmp s_trap_start + +vector19: + push 0x00 + push 0x13 + jmp s_trap_start + +vector20: + push 0x00 + push 0x14 + jmp s_trap_start + +vector21: + push 0x00 + push 0x15 + jmp s_trap_start + +vector22: + push 0x00 + push 0x16 + jmp s_trap_start + +vector23: + push 0x00 + push 0x17 + jmp s_trap_start + +vector24: + push 0x00 + push 0x18 + jmp s_trap_start + +vector25: + push 0x00 + push 0x19 + jmp s_trap_start + +vector26: + push 0x00 + push 0x1A + jmp s_trap_start + +vector27: + push 0x00 + push 0x1B + jmp s_trap_start + +vector28: + push 0x00 + push 0x1C + jmp s_trap_start + +vector29: + push 0x00 + push 0x1D + jmp s_trap_start + +vector30: + push 0x00 + push 0x1E + jmp s_trap_start + +vector31: + push 0x00 + push 0x1F + jmp s_trap_start + +vector32: + push 0x00 + push 0x20 + jmp s_trap_start + +vector33: + push 0x00 + push 0x21 + jmp s_trap_start + +vector34: + push 0x00 + push 0x22 + jmp s_trap_start + +vector35: + push 0x00 + push 0x23 + jmp s_trap_start + +vector36: + push 0x00 + push 0x24 + jmp s_trap_start + +vector37: + push 0x00 + push 0x25 + jmp s_trap_start + +vector38: + push 0x00 + push 0x26 + jmp s_trap_start + +vector39: + push 0x00 + push 0x27 + jmp s_trap_start + +vector40: + push 0x00 + push 0x28 + jmp s_trap_start + +vector41: + push 0x00 + push 0x29 + jmp s_trap_start + +vector42: + push 0x00 + push 0x2A + jmp s_trap_start + +vector43: + push 0x00 + push 0x2B + jmp s_trap_start + +vector44: + push 0x00 + push 0x2C + jmp s_trap_start + +vector45: + push 0x00 + push 0x2D + jmp s_trap_start + +vector46: + push 0x00 + push 0x2E + jmp s_trap_start + +vector47: + push 0x00 + push 0x2F + jmp s_trap_start + +vector48: + push 0x00 + push 0x30 + jmp s_trap_start + +vector49: + push 0x00 + push 0x31 + jmp s_trap_start + +vector50: + push 0x00 + push 0x32 + jmp s_trap_start + +vector51: + push 0x00 + push 0x33 + jmp s_trap_start + +vector52: + push 0x00 + push 0x34 + jmp s_trap_start + +vector53: + push 0x00 + push 0x35 + jmp s_trap_start + +vector54: + push 0x00 + push 0x36 + jmp s_trap_start + +vector55: + push 0x00 + push 0x37 + jmp s_trap_start + +vector56: + push 0x00 + push 0x38 + jmp s_trap_start + +vector57: + push 0x00 + push 0x39 + jmp s_trap_start + +vector58: + push 0x00 + push 0x3A + jmp s_trap_start + +vector59: + push 0x00 + push 0x3B + jmp s_trap_start + +vector60: + push 0x00 + push 0x3C + jmp s_trap_start + +vector61: + push 0x00 + push 0x3D + jmp s_trap_start + +vector62: + push 0x00 + push 0x3E + jmp s_trap_start + +vector63: + push 0x00 + push 0x3F + jmp s_trap_start + +vector64: + push 0x00 + push 0x40 + jmp s_trap_start + +vector65: + push 0x00 + push 0x41 + jmp s_trap_start + +vector66: + push 0x00 + push 0x42 + jmp s_trap_start + +vector67: + push 0x00 + push 0x43 + jmp s_trap_start + +vector68: + push 0x00 + push 0x44 + jmp s_trap_start + +vector69: + push 0x00 + push 0x45 + jmp s_trap_start + +vector70: + push 0x00 + push 0x46 + jmp s_trap_start + +vector71: + push 0x00 + push 0x47 + jmp s_trap_start + +vector72: + push 0x00 + push 0x48 + jmp s_trap_start + +vector73: + push 0x00 + push 0x49 + jmp s_trap_start + +vector74: + push 0x00 + push 0x4A + jmp s_trap_start + +vector75: + push 0x00 + push 0x4B + jmp s_trap_start + +vector76: + push 0x00 + push 0x4C + jmp s_trap_start + +vector77: + push 0x00 + push 0x4D + jmp s_trap_start + +vector78: + push 0x00 + push 0x4E + jmp s_trap_start + +vector79: + push 0x00 + push 0x4F + jmp s_trap_start + +vector80: + push 0x00 + push 0x50 + jmp s_trap_start + +vector81: + push 0x00 + push 0x51 + jmp s_trap_start + +vector82: + push 0x00 + push 0x52 + jmp s_trap_start + +vector83: + push 0x00 + push 0x53 + jmp s_trap_start + +vector84: + push 0x00 + push 0x54 + jmp s_trap_start + +vector85: + push 0x00 + push 0x55 + jmp s_trap_start + +vector86: + push 0x00 + push 0x56 + jmp s_trap_start + +vector87: + push 0x00 + push 0x57 + jmp s_trap_start + +vector88: + push 0x00 + push 0x58 + jmp s_trap_start + +vector89: + push 0x00 + push 0x59 + jmp s_trap_start + +vector90: + push 0x00 + push 0x5A + jmp s_trap_start + +vector91: + push 0x00 + push 0x5B + jmp s_trap_start + +vector92: + push 0x00 + push 0x5C + jmp s_trap_start + +vector93: + push 0x00 + push 0x5D + jmp s_trap_start + +vector94: + push 0x00 + push 0x5E + jmp s_trap_start + +vector95: + push 0x00 + push 0x5F + jmp s_trap_start + +vector96: + push 0x00 + push 0x60 + jmp s_trap_start + +vector97: + push 0x00 + push 0x61 + jmp s_trap_start + +vector98: + push 0x00 + push 0x62 + jmp s_trap_start + +vector99: + push 0x00 + push 0x63 + jmp s_trap_start + +vector100: + push 0x00 + push 0x64 + jmp s_trap_start + +vector101: + push 0x00 + push 0x65 + jmp s_trap_start + +vector102: + push 0x00 + push 0x66 + jmp s_trap_start + +vector103: + push 0x00 + push 0x67 + jmp s_trap_start + +vector104: + push 0x00 + push 0x68 + jmp s_trap_start + +vector105: + push 0x00 + push 0x69 + jmp s_trap_start + +vector106: + push 0x00 + push 0x6A + jmp s_trap_start + +vector107: + push 0x00 + push 0x6B + jmp s_trap_start + +vector108: + push 0x00 + push 0x6C + jmp s_trap_start + +vector109: + push 0x00 + push 0x6D + jmp s_trap_start + +vector110: + push 0x00 + push 0x6E + jmp s_trap_start + +vector111: + push 0x00 + push 0x6F + jmp s_trap_start + +vector112: + push 0x00 + push 0x70 + jmp s_trap_start + +vector113: + push 0x00 + push 0x71 + jmp s_trap_start + +vector114: + push 0x00 + push 0x72 + jmp s_trap_start + +vector115: + push 0x00 + push 0x73 + jmp s_trap_start + +vector116: + push 0x00 + push 0x74 + jmp s_trap_start + +vector117: + push 0x00 + push 0x75 + jmp s_trap_start + +vector118: + push 0x00 + push 0x76 + jmp s_trap_start + +vector119: + push 0x00 + push 0x77 + jmp s_trap_start + +vector120: + push 0x00 + push 0x78 + jmp s_trap_start + +vector121: + push 0x00 + push 0x79 + jmp s_trap_start + +vector122: + push 0x00 + push 0x7A + jmp s_trap_start + +vector123: + push 0x00 + push 0x7B + jmp s_trap_start + +vector124: + push 0x00 + push 0x7C + jmp s_trap_start + +vector125: + push 0x00 + push 0x7D + jmp s_trap_start + +vector126: + push 0x00 + push 0x7E + jmp s_trap_start + +vector127: + push 0x00 + push 0x7F + jmp s_trap_start + +vector128: + push 0x00 + push 0x80 + jmp s_trap_start + +vector129: + push 0x00 + push 0x81 + jmp s_trap_start + +vector130: + push 0x00 + push 0x82 + jmp s_trap_start + +vector131: + push 0x00 + push 0x83 + jmp s_trap_start + +vector132: + push 0x00 + push 0x84 + jmp s_trap_start + +vector133: + push 0x00 + push 0x85 + jmp s_trap_start + +vector134: + push 0x00 + push 0x86 + jmp s_trap_start + +vector135: + push 0x00 + push 0x87 + jmp s_trap_start + +vector136: + push 0x00 + push 0x88 + jmp s_trap_start + +vector137: + push 0x00 + push 0x89 + jmp s_trap_start + +vector138: + push 0x00 + push 0x8A + jmp s_trap_start + +vector139: + push 0x00 + push 0x8B + jmp s_trap_start + +vector140: + push 0x00 + push 0x8C + jmp s_trap_start + +vector141: + push 0x00 + push 0x8D + jmp s_trap_start + +vector142: + push 0x00 + push 0x8E + jmp s_trap_start + +vector143: + push 0x00 + push 0x8F + jmp s_trap_start + +vector144: + push 0x00 + push 0x90 + jmp s_trap_start + +vector145: + push 0x00 + push 0x91 + jmp s_trap_start + +vector146: + push 0x00 + push 0x92 + jmp s_trap_start + +vector147: + push 0x00 + push 0x93 + jmp s_trap_start + +vector148: + push 0x00 + push 0x94 + jmp s_trap_start + +vector149: + push 0x00 + push 0x95 + jmp s_trap_start + +vector150: + push 0x00 + push 0x96 + jmp s_trap_start + +vector151: + push 0x00 + push 0x97 + jmp s_trap_start + +vector152: + push 0x00 + push 0x98 + jmp s_trap_start + +vector153: + push 0x00 + push 0x99 + jmp s_trap_start + +vector154: + push 0x00 + push 0x9A + jmp s_trap_start + +vector155: + push 0x00 + push 0x9B + jmp s_trap_start + +vector156: + push 0x00 + push 0x9C + jmp s_trap_start + +vector157: + push 0x00 + push 0x9D + jmp s_trap_start + +vector158: + push 0x00 + push 0x9E + jmp s_trap_start + +vector159: + push 0x00 + push 0x9F + jmp s_trap_start + +vector160: + push 0x00 + push 0xA0 + jmp s_trap_start + +vector161: + push 0x00 + push 0xA1 + jmp s_trap_start + +vector162: + push 0x00 + push 0xA2 + jmp s_trap_start + +vector163: + push 0x00 + push 0xA3 + jmp s_trap_start + +vector164: + push 0x00 + push 0xA4 + jmp s_trap_start + +vector165: + push 0x00 + push 0xA5 + jmp s_trap_start + +vector166: + push 0x00 + push 0xA6 + jmp s_trap_start + +vector167: + push 0x00 + push 0xA7 + jmp s_trap_start + +vector168: + push 0x00 + push 0xA8 + jmp s_trap_start + +vector169: + push 0x00 + push 0xA9 + jmp s_trap_start + +vector170: + push 0x00 + push 0xAA + jmp s_trap_start + +vector171: + push 0x00 + push 0xAB + jmp s_trap_start + +vector172: + push 0x00 + push 0xAC + jmp s_trap_start + +vector173: + push 0x00 + push 0xAD + jmp s_trap_start + +vector174: + push 0x00 + push 0xAE + jmp s_trap_start + +vector175: + push 0x00 + push 0xAF + jmp s_trap_start + +vector176: + push 0x00 + push 0xB0 + jmp s_trap_start + +vector177: + push 0x00 + push 0xB1 + jmp s_trap_start + +vector178: + push 0x00 + push 0xB2 + jmp s_trap_start + +vector179: + push 0x00 + push 0xB3 + jmp s_trap_start + +vector180: + push 0x00 + push 0xB4 + jmp s_trap_start + +vector181: + push 0x00 + push 0xB5 + jmp s_trap_start + +vector182: + push 0x00 + push 0xB6 + jmp s_trap_start + +vector183: + push 0x00 + push 0xB7 + jmp s_trap_start + +vector184: + push 0x00 + push 0xB8 + jmp s_trap_start + +vector185: + push 0x00 + push 0xB9 + jmp s_trap_start + +vector186: + push 0x00 + push 0xBA + jmp s_trap_start + +vector187: + push 0x00 + push 0xBB + jmp s_trap_start + +vector188: + push 0x00 + push 0xBC + jmp s_trap_start + +vector189: + push 0x00 + push 0xBD + jmp s_trap_start + +vector190: + push 0x00 + push 0xBE + jmp s_trap_start + +vector191: + push 0x00 + push 0xBF + jmp s_trap_start + +vector192: + push 0x00 + push 0xC0 + jmp s_trap_start + +vector193: + push 0x00 + push 0xC1 + jmp s_trap_start + +vector194: + push 0x00 + push 0xC2 + jmp s_trap_start + +vector195: + push 0x00 + push 0xC3 + jmp s_trap_start + +vector196: + push 0x00 + push 0xC4 + jmp s_trap_start + +vector197: + push 0x00 + push 0xC5 + jmp s_trap_start + +vector198: + push 0x00 + push 0xC6 + jmp s_trap_start + +vector199: + push 0x00 + push 0xC7 + jmp s_trap_start + +vector200: + push 0x00 + push 0xC8 + jmp s_trap_start + +vector201: + push 0x00 + push 0xC9 + jmp s_trap_start + +vector202: + push 0x00 + push 0xCA + jmp s_trap_start + +vector203: + push 0x00 + push 0xCB + jmp s_trap_start + +vector204: + push 0x00 + push 0xCC + jmp s_trap_start + +vector205: + push 0x00 + push 0xCD + jmp s_trap_start + +vector206: + push 0x00 + push 0xCE + jmp s_trap_start + +vector207: + push 0x00 + push 0xCF + jmp s_trap_start + +vector208: + push 0x00 + push 0xD0 + jmp s_trap_start + +vector209: + push 0x00 + push 0xD1 + jmp s_trap_start + +vector210: + push 0x00 + push 0xD2 + jmp s_trap_start + +vector211: + push 0x00 + push 0xD3 + jmp s_trap_start + +vector212: + push 0x00 + push 0xD4 + jmp s_trap_start + +vector213: + push 0x00 + push 0xD5 + jmp s_trap_start + +vector214: + push 0x00 + push 0xD6 + jmp s_trap_start + +vector215: + push 0x00 + push 0xD7 + jmp s_trap_start + +vector216: + push 0x00 + push 0xD8 + jmp s_trap_start + +vector217: + push 0x00 + push 0xD9 + jmp s_trap_start + +vector218: + push 0x00 + push 0xDA + jmp s_trap_start + +vector219: + push 0x00 + push 0xDB + jmp s_trap_start + +vector220: + push 0x00 + push 0xDC + jmp s_trap_start + +vector221: + push 0x00 + push 0xDD + jmp s_trap_start + +vector222: + push 0x00 + push 0xDE + jmp s_trap_start + +vector223: + push 0x00 + push 0xDF + jmp s_trap_start + +vector224: + push 0x00 + push 0xE0 + jmp s_trap_start + +vector225: + push 0x00 + push 0xE1 + jmp s_trap_start + +vector226: + push 0x00 + push 0xE2 + jmp s_trap_start + +vector227: + push 0x00 + push 0xE3 + jmp s_trap_start + +vector228: + push 0x00 + push 0xE4 + jmp s_trap_start + +vector229: + push 0x00 + push 0xE5 + jmp s_trap_start + +vector230: + push 0x00 + push 0xE6 + jmp s_trap_start + +vector231: + push 0x00 + push 0xE7 + jmp s_trap_start + +vector232: + push 0x00 + push 0xE8 + jmp s_trap_start + +vector233: + push 0x00 + push 0xE9 + jmp s_trap_start + +vector234: + push 0x00 + push 0xEA + jmp s_trap_start + +vector235: + push 0x00 + push 0xEB + jmp s_trap_start + +vector236: + push 0x00 + push 0xEC + jmp s_trap_start + +vector237: + push 0x00 + push 0xED + jmp s_trap_start + +vector238: + push 0x00 + push 0xEE + jmp s_trap_start + +vector239: + push 0x00 + push 0xEF + jmp s_trap_start + +vector240: + push 0x00 + push 0xF0 + jmp s_trap_start + +vector241: + push 0x00 + push 0xF1 + jmp s_trap_start + +vector242: + push 0x00 + push 0xF2 + jmp s_trap_start + +vector243: + push 0x00 + push 0xF3 + jmp s_trap_start + +vector244: + push 0x00 + push 0xF4 + jmp s_trap_start + +vector245: + push 0x00 + push 0xF5 + jmp s_trap_start + +vector246: + push 0x00 + push 0xF6 + jmp s_trap_start + +vector247: + push 0x00 + push 0xF7 + jmp s_trap_start + +vector248: + push 0x00 + push 0xF8 + jmp s_trap_start + +vector249: + push 0x00 + push 0xF9 + jmp s_trap_start + +vector250: + push 0x00 + push 0xFA + jmp s_trap_start + +vector251: + push 0x00 + push 0xFB + jmp s_trap_start + +vector252: + push 0x00 + push 0xFC + jmp s_trap_start + +vector253: + push 0x00 + push 0xFD + jmp s_trap_start + +vector254: + push 0x00 + push 0xFE + jmp s_trap_start + +vector255: + push 0x00 + push 0xFF + jmp s_trap_start + + diff --git a/kernel/kernel.c b/kernel/kernel.c new file mode 100644 index 0000000..335cfe4 --- /dev/null +++ b/kernel/kernel.c @@ -0,0 +1,131 @@ + +#include <stdint.h> +#include "kprintf.h" +#include "gdt.h" +#include "idt.h" +#include "acpi.h" + +#include "asm_inline.h" + +typedef struct _OSDATA +{ + uint32_t Magic; // magic number to check + + uint32_t FBWidth; // with of the framebuffer + uint32_t FBHeight; // height + uint32_t PixelSize; // size of each pixel(an rgb pixel might have a bigger size) + void * FBAddr; // address of the linear framebuffer + + void * MEMMap; // pointer to the system memory map + + void * RAMDisk; // pointer to a ramdisk loaded from the hdd + + void* RSDP; +} OSDATA; + +typedef struct _Pixel +{ + uint8_t B; + uint8_t G; + uint8_t R; + uint8_t Z; +} Pixel; + +void early_serial_init() +{ + outb(COM1 + 1, 0x00); + outb(COM1 + 3, 0x80); + outb(COM1 + 0, 0x03); + outb(COM1 + 1, 0x00); + outb(COM1 + 3, 0x03); + outb(COM1 + 2, 0xC7); + outb(COM1 + 4, 0x0B); +} + +int kmain(void * osdata) +{ + early_serial_init(); + + fldcw(0x37F); + + kprintf("\n\n\n"); + kprintf("=====================\n"); + kprintf(" OrnitorrincOS\n"); + kprintf("=====================\n"); + kprintf("\n\n\n"); + // kprintf("Hello from the kernel\n"); + // kprintf("This is a %d complex %x test: %X\n", 1234, 1234, 1234); + + uint32_t regs[4] = {0}; + char* str = (char*)regs; + uint32_t rax, rbx, rcx, rdx; + cpuid(0, 0, &rax, &rbx, &rcx, &rdx); + regs[0] = rbx; + regs[1] = rdx; + regs[2] = rcx; + kprintf("CPU: %s\n", str); + + OSDATA* data = (OSDATA*)osdata; + + Pixel* fb = data->FBAddr; + + // kprintf("FB Address: %p\n", fb); + + { + int i = 0; + int j = 0; + + for(i = 0; i < 256; ++i) + { + for(j = 0; j < 256; ++j) + { + Pixel p; + p.R = 0; + p.G = 255; + p.B = 0; + p.Z = 255; + fb[j + 800*i] = p; // original: 1024 but 800 seems to work better(maybe we are not setting the display mode correctly + } + } + } + + // kprintf("image finished\n"); + + kprintf("\n"); + kprintf("=> Initializing GDT\n"); + + cli(); + + init_gdt(); + + kprintf("=> GDT initialized\n"); + + kprintf("\n"); + + kprintf("=> Initializing IDT\n"); + + init_idt(); + + kprintf("=> IDT initialized\n"); + + sti(); + + kprintf("=> Interrupts reenabled\n"); + + char* test_value = (char*)0xFFFFFFFF00000000; + // *test_value = 'B'; + + XSDP* xsdt = (XSDP*)data->RSDP; + + kprintf("\n"); + + init_acpi(xsdt); + + while(1) {}; + + kprintf("KERNEL FINISHED\n"); + + hlt(); + + return 0; +} diff --git a/kernel/kprintf.c b/kernel/kprintf.c new file mode 100644 index 0000000..20769ea --- /dev/null +++ b/kernel/kprintf.c @@ -0,0 +1,259 @@ +#include <stdbool.h> + +#include "kprintf.h" + +#include "asm_inline.h" + +// #define KDEBUG + +int check_transmission() { + return inb(COM1 + 5) & 0x20; +} + +void write_serial_char(char a) { + while (check_transmission() == 0); + outb(COM1,a); +} + +void write_serial_string(const char* str) +{ + while(*str != '\0') + { + if(*str == '\n') + { + write_serial_char('\r'); + } + write_serial_char(*str); + str++; + } +} + +char* convert_U_integer(uint64_t n, uint16_t base, bool caps) +{ + static char* format = "0123456789abcdef"; + static char* C_format = "0123456789ABCDEF"; + + static char buffer[50]; + char *ptr; + + ptr = &buffer[49]; + *ptr = '\0'; + + do + { + if(caps) + { + *--ptr = C_format[n%base]; + } + else + { + *--ptr = format[n%base]; + } + n /= base; + } while(n != 0); + + return ptr; +} + +void kprintf(const char* str, ...) +{ + va_list args; + + va_start(args, str); + + while(*str) + { + if(*str == '%') + { + #ifdef KDEBUG + write_serial_string("{stradv}"); + #endif + str++; + if(*str == 'i' || *str == 'd') + { + #ifdef KDEBUG + write_serial_string("[INT]"); + #endif + int32_t n = va_arg(args, int32_t); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'u') + { + #ifdef KDEBUG + write_serial_string("[UINT]"); + #endif + uint32_t n = va_arg(args, uint32_t); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'x') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint32_t n = va_arg(args, uint32_t); + char* s = convert_U_integer(n, 16, false); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'X') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint32_t n = va_arg(args, uint32_t); + char* s = convert_U_integer(n, 16, true); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'l') + { + #ifdef KDEBUG + write_serial_string("[LONG]"); + write_serial_string("{ladv}"); + #endif + str++; + if(*str == 'i' || *str == 'd') + { + #ifdef KDEBUG + write_serial_string("[INT]"); + #endif + int64_t n = va_arg(args, int64_t); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'u') + { + #ifdef KDEBUG + write_serial_string("[UINT]"); + #endif + uint64_t n = va_arg(args, uint64_t); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'x') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint64_t n = va_arg(args, uint64_t); + char* s = convert_U_integer(n, 16, false); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'X') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint64_t n = va_arg(args, uint64_t); + char* s = convert_U_integer(n, 16, true); + write_serial_string("0x"); + write_serial_string(s); + } + } + else if(*str == 'h') + { + #ifdef KDEBUG + write_serial_string("[SHORT]"); + write_serial_string("{ladv}"); + #endif + str++; + if(*str == 'i' || *str == 'd') + { + #ifdef KDEBUG + write_serial_string("[INT]"); + #endif + int16_t n = va_arg(args, int); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'u') + { + #ifdef KDEBUG + write_serial_string("[UINT]"); + #endif + uint16_t n = va_arg(args, int); + char* s = convert_U_integer(n, 10, false); + write_serial_string(s); + } + else if(*str == 'x') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint16_t n = va_arg(args, int); + char* s = convert_U_integer(n, 16, false); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'X') + { + #ifdef KDEBUG + write_serial_string("[HEX]"); + #endif + uint16_t n = va_arg(args, int); + char* s = convert_U_integer(n, 16, true); + write_serial_string("0x"); + write_serial_string(s); + } + } + else if(*str == 'p') + { + #ifdef KDEBUG + write_serial_string("[PTR]"); + #endif + void* p = va_arg(args, void*); + uint64_t n = (uint64_t)p; + char* s = convert_U_integer(n, 16, true); + write_serial_string("0x"); + write_serial_string(s); + } + else if(*str == 'c') + { + #ifdef KDEBUG + write_serial_string("[CHAR]"); + #endif + char c = va_arg(args, int); + write_serial_char(c); + } + else if(*str == 's') + { + #ifdef KDEBUG + write_serial_string("[STR]"); + #endif + char* s = va_arg(args, char*); + write_serial_string(s); + } + else + { + write_serial_string("\nFailed to write malformed kprintf: "); + write_serial_char(*str); + write_serial_string("\n"); + va_end(args); + return; + } + #ifdef KDEBUG + write_serial_string("{pend}"); + #endif + } + else if(*str == '\n') + { + write_serial_char('\r'); + write_serial_char('\n'); + } + else + { + write_serial_char(*str); + } + #ifdef KDEBUG + write_serial_string("{oadv}"); + #endif + str++; + } + + //write_serial_string(str); + + va_end(args); +} diff --git a/kernel/kprintf.h b/kernel/kprintf.h new file mode 100644 index 0000000..f646e60 --- /dev/null +++ b/kernel/kprintf.h @@ -0,0 +1,3 @@ +#include <stdarg.h> + +void kprintf(const char* str, ...); diff --git a/kernel/linker.ld b/kernel/linker.ld new file mode 100644 index 0000000..43f8a15 --- /dev/null +++ b/kernel/linker.ld @@ -0,0 +1,51 @@ +ENTRY(loader) +/* ENTRY(kmain) */ + +SECTIONS +{ + /* 0xffffffff80000000 is the kernel virtual memory load address */ + . = 0xffffffff80000000; + + .text : AT(ADDR(.text) - 0xffffffff80000000) + { + _code = .; + *(.text) + *(.rodata*) + . = ALIGN(4096); + } + + .data : AT(ADDR(.data) - 0xffffffff80000000) + { + _data = .; + *(.data) + . = ALIGN(4096); + } + + .eh_frame : AT(ADDR(.eh_frame) - 0xffffffff80000000) + { + _ehframe = .; + *(.eh_frame) + . = ALIGN(4096); + } + + .bss : AT(ADDR(.bss) - 0xffffffff80000000) + { + _bss = .; + *(.bss) + + /* + * You usually need to include generated COMMON symbols + * under kernel BSS section or use gcc's -fno-common + */ + + *(COMMON) + . = ALIGN(4096); + } + + _end = .; + + /DISCARD/ : + { + *(.comment) + } +} diff --git a/kernel/loader.s b/kernel/loader.s new file mode 100644 index 0000000..791c231 --- /dev/null +++ b/kernel/loader.s @@ -0,0 +1,32 @@ +global loader +extern kmain + +section .text +align 4 +STACKSIZE equ 0x4000 + + +loader: + ;setup the stack and call the kernel entry point + ; shouldn't really use it this way, but take the loading address and move that to rsp to get a working stack + mov rsp, stack+STACKSIZE + mov rbp, rsp + + ; enable FPU, SSE + mov rax, cr0 + and ax, 0xFFFB + or ax, 0x2 + mov cr0, rax + mov rax, cr4 + or ax, 3 << 9 ; OSFXSR OSXMMEXCPT + mov cr4, rax + + ; pass arguments we receiver, or maybe have to get them first fropm the stack + call kmain + hlt + + +section .bss +align 32 +stack: + resb STACKSIZE diff --git a/kernel/makefile b/kernel/makefile new file mode 100644 index 0000000..387fc4d --- /dev/null +++ b/kernel/makefile @@ -0,0 +1,25 @@ +CC = x86_64-elf-gcc + +.PHONY: all clean + +#CFLAGS = -ffreestanding -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -masm=intel +CFLAGS = -ffreestanding -mcmodel=kernel -mno-red-zone -masm=intel + +all: + nasm loader.s -f elf64 -o loader.o + nasm segments.s -f elf64 -o segments.o + nasm interrupts/common.s -f elf64 -o interrupts/common.o + nasm interrupts/vectors.s -f elf64 -o interrupts/vectors.o + $(CC) $(CFLAGS) -c kernel.c -o kernel.o + $(CC) $(CFLAGS) -c kprintf.c -o kprintf.o + $(CC) $(CFLAGS) -c memops.c -o memops.o + $(CC) $(CFLAGS) -c gdt.c -o gdt.o + $(CC) $(CFLAGS) -c idt.c -o idt.o + $(CC) $(CFLAGS) -c interrupts/generic.c -o interrupts/generic.o + $(CC) $(CFLAGS) -c cpu_info.c -o cpu_info.o + $(CC) $(CFLAGS) -c acpi.c -o acpi.o + $(CC) -T linker.ld -o kernel.bin -ffreestanding -O0 -nostdlib kernel.o kprintf.o memops.o gdt.o loader.o segments.o idt.o interrupts/common.o interrupts/generic.o interrupts/vectors.o cpu_info.o acpi.o -lgcc + +clean: + rm *.o + rm kernel.bin diff --git a/kernel/memops.c b/kernel/memops.c new file mode 100644 index 0000000..12fae8b --- /dev/null +++ b/kernel/memops.c @@ -0,0 +1,36 @@ +#include "memops.h" + +void kmemset(void* dst, uint8_t value) +{ + +} + +void kmemcpy(void* src, void* dst, uint64_t size) +{ + uint64_t counter = 0; + + uint8_t* c_src = src; + uint8_t* c_dst = dst; + + while(counter < size) + { + c_dst[counter] = c_src[counter]; + counter++; + } +} + +bool kmemcmp(void* lhs, void* rhs, uint64_t size) +{ + uint8_t* clhs = (uint8_t*)lhs; + uint8_t* crhs = (uint8_t*)rhs; + + for(int i = 0; i < size; i++) + { + if(clhs[i] != crhs[i]) + { + return false; + } + } + + return true; +} diff --git a/kernel/memops.h b/kernel/memops.h new file mode 100644 index 0000000..e42ac29 --- /dev/null +++ b/kernel/memops.h @@ -0,0 +1,8 @@ +#pragma once + +#include <stdint.h> +#include <stdbool.h> + +void kmemset(void* dst, uint8_t value); +void kmemcpy(void* src, void* dst, uint64_t size); +bool kmemcmp(void* lhs, void* rhs, uint64_t size); diff --git a/kernel/segments.s b/kernel/segments.s new file mode 100644 index 0000000..77e6502 --- /dev/null +++ b/kernel/segments.s @@ -0,0 +1,21 @@ + +global asm_reload_segments + +section .text +align 4 + +asm_reload_segments: + push 0x08 + lea rax, [rel .reload_cs] + push rax + retfq + +; 0z10 is 16 bytes in decimal, so this should reload the segment correctly +.reload_cs: + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + ret
\ No newline at end of file diff --git a/kernel/uefi.h b/kernel/uefi.h new file mode 100644 index 0000000..722dfac --- /dev/null +++ b/kernel/uefi.h @@ -0,0 +1,104 @@ +#pragma once + +#include <stdint.h> + +typedef enum +{ + /// + /// Not used. + /// + EfiReservedMemoryType, + /// + /// The code portions of a loaded application. + /// (Note that UEFI OS loaders are UEFI applications.) + /// + EfiLoaderCode, + /// + /// The data portions of a loaded application and the default data allocation + /// type used by an application to allocate pool memory. + /// + EfiLoaderData, + /// + /// The code portions of a loaded Boot Services Driver. + /// + EfiBootServicesCode, + /// + /// The data portions of a loaded Boot Serves Driver, and the default data + /// allocation type used by a Boot Services Driver to allocate pool memory. + /// + EfiBootServicesData, + /// + /// The code portions of a loaded Runtime Services Driver. + /// + EfiRuntimeServicesCode, + /// + /// The data portions of a loaded Runtime Services Driver and the default + /// data allocation type used by a Runtime Services Driver to allocate pool memory. + /// + EfiRuntimeServicesData, + /// + /// Free (unallocated) memory. + /// + EfiConventionalMemory, + /// + /// Memory in which errors have been detected. + /// + EfiUnusableMemory, + /// + /// Memory that holds the ACPI tables. + /// + EfiACPIReclaimMemory, + /// + /// Address space reserved for use by the firmware. + /// + EfiACPIMemoryNVS, + /// + /// Used by system firmware to request that a memory-mapped IO region + /// be mapped by the OS to a virtual address so it can be accessed by EFI runtime services. + /// + EfiMemoryMappedIO, + /// + /// System memory-mapped IO region that is used to translate memory + /// cycles to IO cycles by the processor. + /// + EfiMemoryMappedIOPortSpace, + /// + /// Address space reserved by the firmware for code that is part of the processor. + /// + EfiPalCode, + /// + /// A memory region that operates as EfiConventionalMemory, + /// however it happens to also support byte-addressable non-volatility. + /// + EfiPersistentMemory, + /// + /// A memory region that describes system memory that has not been accepted + /// by a corresponding call to the underlying isolation architecture. + /// + EfiUnacceptedMemoryType, + EfiMaxMemoryType, + // + // +---------------------------------------------------+ + // | 0..(EfiMaxMemoryType - 1) - Normal memory type | + // +---------------------------------------------------+ + // | EfiMaxMemoryType..0x6FFFFFFF - Invalid | + // +---------------------------------------------------+ + // | 0x70000000..0x7FFFFFFF - OEM reserved | + // +---------------------------------------------------+ + // | 0x80000000..0xFFFFFFFF - OS reserved | + // +---------------------------------------------------+ + // + MEMORY_TYPE_OEM_RESERVED_MIN = 0x70000000, + MEMORY_TYPE_OEM_RESERVED_MAX = 0x7FFFFFFF, + MEMORY_TYPE_OS_RESERVED_MIN = 0x80000000, + MEMORY_TYPE_OS_RESERVED_MAX = 0xFFFFFFFF +} EFI_MEMORY_TYPE; + +typedef struct __attribute__((packed)) +{ + uint32_t type; + uint64_t physicalStart; + uint64_t virtualStart; + uint64_t numberOfPages; + uint64_t Attribute; +} EFI_MEMORY_DESCRIPTOR; |
