From 245d09b056304aa0cb50e70bc4427ba220960ea4 Mon Sep 17 00:00:00 2001 From: Jenny Curle Date: Sun, 7 Apr 2019 13:16:53 +0100 Subject: [PATCH] Implemented IDT But something's wrong with the GDT Next up is a Serial Console --- arch/i386/boot.s | 9 ++++++- include/kernel/descriptor_tables.h | 7 +++++ include/kernel/idt.h | 19 ++++++++++++++ include/kernel/utils.h | 4 +++ kernel/idt.c | 42 ++++++++++++++++++++++++++++++ kernel/kernel.c | 4 ++- kernel/utils.c | 18 ++++++++++++- makefile | 1 + 8 files changed, 101 insertions(+), 3 deletions(-) create mode 100755 include/kernel/descriptor_tables.h create mode 100755 include/kernel/idt.h create mode 100755 kernel/idt.c diff --git a/arch/i386/boot.s b/arch/i386/boot.s index 76b5444..a00dde8 100755 --- a/arch/i386/boot.s +++ b/arch/i386/boot.s @@ -52,4 +52,11 @@ gdt_flush: push $flush2 ljmp *(%esp) #long jump flush2: - ret #return to c code \ No newline at end of file + ret #return to c code + +.global idt_load +.extern idtp +idt_load: + lidt (idtp) + ret + \ No newline at end of file diff --git a/include/kernel/descriptor_tables.h b/include/kernel/descriptor_tables.h new file mode 100755 index 0000000..1d71852 --- /dev/null +++ b/include/kernel/descriptor_tables.h @@ -0,0 +1,7 @@ +#pragma once + +void gdt_set_gate(int, unsigned long, unsigned long, unsigned char, unsigned char); +void gdt_install(); + +void idt_set_gate(unsigned char, unsigned long, unsigned short, unsigned char); +void idt_install(); \ No newline at end of file diff --git a/include/kernel/idt.h b/include/kernel/idt.h new file mode 100755 index 0000000..c3f9aa7 --- /dev/null +++ b/include/kernel/idt.h @@ -0,0 +1,19 @@ +#include + +struct idt_entry { + unsigned short base_low; + unsigned short selector; + unsigned char always0; + unsigned char flags; + unsigned short base_high; +} __attribute__((packed)); + +struct idt_ptr { + unsigned short limit; + unsigned int base; +}__attribute__((packed)); + +struct idt_entry idt[256]; //interrupt table of 256 entries +struct idt_ptr idtp; //pointer to idt table + +extern void idt_load(); diff --git a/include/kernel/utils.h b/include/kernel/utils.h index 22b3469..ba8debb 100755 --- a/include/kernel/utils.h +++ b/include/kernel/utils.h @@ -9,3 +9,7 @@ size_t strlen(const char*); unsigned char inb(unsigned short); void outb(unsigned short, unsigned char); + +void memcpy(void*, void*, size_t); + +void memset(void*, int, size_t); \ No newline at end of file diff --git a/kernel/idt.c b/kernel/idt.c new file mode 100755 index 0000000..ef73559 --- /dev/null +++ b/kernel/idt.c @@ -0,0 +1,42 @@ +#include + +struct idt_entry { + unsigned short base_low; + unsigned short selector; + unsigned char always0; + unsigned char flags; + unsigned short base_high; +} __attribute__((packed)); + +struct idt_ptr { + unsigned short limit; + unsigned int base; +}__attribute__((packed)); + +struct idt_entry idt[256]; // Interrupt table of 256 entries +struct idt_ptr idtp; // Pointer to idt table + +extern void idt_load(); + +void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags) { + idt[num].base_low = base & 0xFFFF; + idt[num].base_high = (base >> 16) & 0xFFFF; + + idt[num].selector = sel; + idt[num].always0 = 0; + + // Must be uncommented when we get to usermode - it sets the permission + // level to 3 + idt[num].flags = flags; // | 0x60; +} + +void idt_install() { + idtp.limit = (sizeof (struct idt_entry) * 256) - 1; + idtp.base = &idt; + + memset(&idt, 0, sizeof(struct idt_entry) * 256); + + // All ISRs go here + + idt_load(); +} \ No newline at end of file diff --git a/kernel/kernel.c b/kernel/kernel.c index 2edb848..5b67615 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -6,7 +6,9 @@ int kernel_main(void) { //Prepare the GDT - gdt_install(); + gdt_install(); + //Prepare interrupts + //idt_install(); //Prepare the screen, and blank it out. screen_initialize(); diff --git a/kernel/utils.c b/kernel/utils.c index b868fc9..279cb89 100644 --- a/kernel/utils.c +++ b/kernel/utils.c @@ -16,4 +16,20 @@ unsigned char inb(unsigned short port) { void outb(unsigned short port, unsigned char data) { asm volatile("outb %1, %0" : : "dN" (port), "a" (data)); -} +} + +void memcpy(void* dest, void* src, size_t n) { + char* src_c = (char*)src; + char* dest_c = (char*)dest; + + for(size_t i = 0; i < n; i++) { + dest_c[i] = src_c[i]; + } +} + +void memset(void* src, int chr, size_t n) { + unsigned char* ptr = src; + while(n--) { + *ptr++ = (unsigned char) chr; + } +} diff --git a/makefile b/makefile index 060d5ca..ffe3c36 100755 --- a/makefile +++ b/makefile @@ -31,6 +31,7 @@ KERNEL_OBJS= \ $(KERNEL_ARCH_OBJS) \ kernel/utils.o \ kernel/gdt.o \ +kernel/idt.o \ kernel/kernel.o OBJS=\