diff --git a/Makefile b/Makefile index 1c7bf59..27bd7ea 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -CFLAGS = -m32 -nostdlib -fno-builtin -fno-exceptions -fno-leading-underscore -fno-pie -fno-stack-protector +CFLAGS = -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exceptions -fno-leading-underscore -fno-pie -fno-stack-protector -Wno-pointer-to-int-cast LDFLAGS = DISK_IMG_FILES = kernel.bin hello.bin print.bin boot32.bin kernel32.bin -KERNEL32_OBJS = screenstuff.o io.o kernel32_strap.o kernel32.o +KERNEL32_OBJS = screenstuff.o io.o idt.o kernel32_strap.o kernel32.o run: disk.img qemu-system-x86_64 disk.img @@ -28,7 +28,7 @@ boot.sector: boot.asm kernel32.bin: kernel32.ld $(KERNEL32_OBJS) ld $(LDFLAGS) -T $< $(KERNEL32_OBJS) -kernel32_strap.o: kernel32_strap.asm +%.o: %.asm nasm -felf32 $< -o $@ %.o: %.c diff --git a/idt.c b/idt.c new file mode 100644 index 0000000..71d71f3 --- /dev/null +++ b/idt.c @@ -0,0 +1,30 @@ +#include "idt.h" + +GateEntry idt[256]; + +void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type) { + uint32_t handler_addr = (uint16_t)handler; + uint16_t* handler_halves = (uint16_t*)&handler_addr; + idt[interrupt_number] = (GateEntry){ + .offset_low = handler_halves[0], + .selector = code_segment, + .zero = 0, + .type = type, + .offset_high = handler_halves[1] + }; +} + +__attribute__((interrupt)) void ignore_interrupt(struct interrupt_frame* frame) { + // Do nothing +} + +void init_idt() { + idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt}; + asm volatile("lidt %0" : : "m" (desc)); + for (int i=0; i<256; i++) + set_entry(i, 0x08, &ignore_interrupt, 0x8E); +} + +void enable_idt() { + asm ("sti"); +} \ No newline at end of file diff --git a/idt.h b/idt.h new file mode 100644 index 0000000..5bc8b1b --- /dev/null +++ b/idt.h @@ -0,0 +1,32 @@ +#ifndef IDT_H +#define IDT_H + +#include "types.h" +#include "screenstuff.h" + +struct interrupt_frame{ + uint16_t ip; + uint16_t cs; + uint16_t flags; + uint16_t sp; + uint16_t ss; +}; +extern void load_idt(); +void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type); +void init_idt(); +void enable_idt(); + +typedef struct { + uint16_t offset_low; + uint16_t selector; + uint8_t zero; + uint8_t type; + uint16_t offset_high; +}__attribute__((packed)) GateEntry; + +typedef struct { + uint16_t size; + uint32_t offset; +}__attribute__((packed)) idt_desc; + +#endif \ No newline at end of file diff --git a/kernel32.c b/kernel32.c index e6d26f7..a75dcf0 100644 --- a/kernel32.c +++ b/kernel32.c @@ -1,13 +1,34 @@ #include "types.h" #include "screenstuff.h" #include "io.h" +#include "idt.h" + +__attribute__((interrupt)) void interrupt_21(struct interrupt_frame* frame) { + printf("Interrupt 20 received!!\n"); + outb(0x20, 0x20); +} int main() { + init_idt(); + set_entry(0x20, 0x08, &interrupt_21, 0x8E); init_term(); printf("KERNEL32 OK!\n"); printf("Hello, World!\n\nWe are running XnoeOS Code in C now, Protected Mode has been achieved and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n"); + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, 0x20); + outb(0xA1, 0x28); + outb(0x21, 0x04); + outb(0xA1, 0x02); + outb(0x21, 0x01); + outb(0xA1, 0x01); + outb(0x21, 0x00); + outb(0xA1, 0x00); + + enable_idt(); + while (1); } \ No newline at end of file diff --git a/types.h b/types.h index 8706872..1bae039 100644 --- a/types.h +++ b/types.h @@ -5,7 +5,7 @@ typedef char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; -typedef long long int int32_t; -typedef unsigned long long int uint32_t; +typedef long int int32_t; +typedef unsigned long int uint32_t; #endif \ No newline at end of file