diff options
author | Raghuram Subramani <raghus2247@gmail.com> | 2025-02-07 17:15:28 +0530 |
---|---|---|
committer | Raghuram Subramani <raghus2247@gmail.com> | 2025-02-07 17:17:15 +0530 |
commit | cca4e987ec30229a77a7cd4bf27c9d6670ad79db (patch) | |
tree | 1747ef03b987221e2c655f0fc42e1161a0e8958d | |
parent | d19eaaef708a51d1ac6a89a86c14745ad948e6c8 (diff) |
IDT: Initialize IDT with a very basic exception handler that does nothing
-rw-r--r-- | kernel/CMakeLists.txt | 4 | ||||
-rw-r--r-- | kernel/boot/gdt/gdt.cc | 1 | ||||
-rw-r--r-- | kernel/boot/idt/exceptions.cc | 36 | ||||
-rw-r--r-- | kernel/boot/idt/idt.cc | 46 | ||||
-rw-r--r-- | kernel/boot/idt/isr.s | 72 | ||||
-rw-r--r-- | kernel/include/boot/gdt.h | 15 | ||||
-rw-r--r-- | kernel/include/boot/idt.h | 55 | ||||
-rw-r--r-- | kernel/include/common.h | 1 | ||||
-rw-r--r-- | kernel/kernel/kernel.cc | 2 | ||||
-rw-r--r-- | kernel/kernel/spinlock.cc | 2 | ||||
-rw-r--r-- | kernel/mm/virtual_mm/virtual_mm.cc | 10 |
11 files changed, 230 insertions, 14 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index cd9b187..bc4d5bb 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -6,6 +6,9 @@ set(SRC boot/gdt/gdt.cc boot/gdt/gdt.s + boot/idt/exceptions.cc + boot/idt/idt.cc + boot/idt/isr.s boot/init/boot.s drivers/serial.cc @@ -61,6 +64,7 @@ set(CXX_COMPILE_OPTIONS -Wno-write-strings -Wno-missing-field-initializers -Wno-c++11-long-long + -Wno-c99-extensions ) target_compile_options(kernel PRIVATE diff --git a/kernel/boot/gdt/gdt.cc b/kernel/boot/gdt/gdt.cc index 360d9b8..708d399 100644 --- a/kernel/boot/gdt/gdt.cc +++ b/kernel/boot/gdt/gdt.cc @@ -17,7 +17,6 @@ */ #include <boot/gdt.h> -#include <kernel/io.h> namespace GDT { diff --git a/kernel/boot/idt/exceptions.cc b/kernel/boot/idt/exceptions.cc new file mode 100644 index 0000000..79ffd68 --- /dev/null +++ b/kernel/boot/idt/exceptions.cc @@ -0,0 +1,36 @@ +/* + * bubbl + * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <boot/idt.h> +#include <common.h> +#include <kernel/halt.h> +#include <libk/stdio.h> +#include <stdbool.h> + +namespace IDT +{ + +void +exception_handler(void) +{ + ASSERT_NOT_REACHED(); + while (true) + __asm__ volatile("cli; hlt"); +} + +} diff --git a/kernel/boot/idt/idt.cc b/kernel/boot/idt/idt.cc new file mode 100644 index 0000000..e640fd5 --- /dev/null +++ b/kernel/boot/idt/idt.cc @@ -0,0 +1,46 @@ +/* + * bubbl + * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <boot/idt.h> +#include <kernel/io.h> + +namespace IDT +{ + +extern "C" void *isr_stub_table[]; + +entry_t l_entries[256]; +descriptor_t descriptor = { sizeof(l_entries) - 1, l_entries }; + +void +load(void) +{ + for (uint16_t i = 0; i < 256; i++) + l_entries[i] = (entry_t) { 0 }; + + /* The first 32 entries are exceptions */ + for (uint8_t i = 0; i < 32; i++) { + entry_t idt_entry = IDT_ENTRY((uint32_t) isr_stub_table[i], 0x8E); + l_entries[i] = idt_entry; + } + + __asm__ volatile("lidt %0" ::"m"(descriptor)); + __asm__ volatile("sti"); +} + +} diff --git a/kernel/boot/idt/isr.s b/kernel/boot/idt/isr.s new file mode 100644 index 0000000..925bb27 --- /dev/null +++ b/kernel/boot/idt/isr.s @@ -0,0 +1,72 @@ +;; +;; bubbl +;; Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com> +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. +;; + +extern exception_handler; + +global isr_stub_table +isr_stub_table: +%assign i 0 +%rep 32 +dd ISR_%+i +%assign i i+1 +%endrep + +%macro ISR_WITH_ERROR 1 +ISR_%+%1: + call exception_handler + iret +%endmacro + +%macro ISR_NO_ERROR 1 +ISR_%+%1: + call exception_handler + iret +%endmacro + +ISR_NO_ERROR 0 +ISR_NO_ERROR 1 +ISR_NO_ERROR 2 +ISR_NO_ERROR 3 +ISR_NO_ERROR 4 +ISR_NO_ERROR 5 +ISR_NO_ERROR 6 +ISR_NO_ERROR 7 +ISR_WITH_ERROR 8 +ISR_NO_ERROR 9 +ISR_WITH_ERROR 10 +ISR_WITH_ERROR 11 +ISR_WITH_ERROR 12 +ISR_WITH_ERROR 13 +ISR_WITH_ERROR 14 +ISR_NO_ERROR 15 +ISR_NO_ERROR 16 +ISR_WITH_ERROR 17 +ISR_NO_ERROR 18 +ISR_NO_ERROR 19 +ISR_NO_ERROR 20 +ISR_NO_ERROR 21 +ISR_NO_ERROR 22 +ISR_NO_ERROR 23 +ISR_NO_ERROR 24 +ISR_NO_ERROR 25 +ISR_NO_ERROR 26 +ISR_NO_ERROR 27 +ISR_NO_ERROR 28 +ISR_NO_ERROR 29 +ISR_WITH_ERROR 30 +ISR_NO_ERROR 31 diff --git a/kernel/include/boot/gdt.h b/kernel/include/boot/gdt.h index ff87981..237628c 100644 --- a/kernel/include/boot/gdt.h +++ b/kernel/include/boot/gdt.h @@ -78,13 +78,12 @@ #define GDT_ENTRY(base, limit, access_flags, flags) \ { \ - (limit & 0xffff), /* limit_low */ \ - (base & 0xffff), /* base_low */ \ - ((base >> 16) & 0xff), /* base_mid */ \ - access_flags, /* access_flags */ \ - FLAGS_LIMIT_HIGH(flags, \ - ((limit >> 16) & 0xff)), /* flags_limit_high */ \ - ((base >> 24) & 0xff) /* base_high */ \ + (limit & 0xffff), /* limit_low */ \ + (base & 0xffff), /* base_low */ \ + ((base >> 16) & 0xff), /* base_mid */ \ + access_flags, /* access_flags */ \ + FLAGS_LIMIT_HIGH(flags, ((limit >> 16) & 0xff)), /* flags_limit_high */ \ + ((base >> 24) & 0xff) /* base_high */ \ } namespace GDT @@ -105,6 +104,8 @@ typedef struct { } PACKED descriptor_t; extern "C" void _GDT_flush(descriptor_t *descriptor); + +void initialize(void); void load(void); } diff --git a/kernel/include/boot/idt.h b/kernel/include/boot/idt.h new file mode 100644 index 0000000..2eda86c --- /dev/null +++ b/kernel/include/boot/idt.h @@ -0,0 +1,55 @@ +/* + * bubbl + * Copyright (C) 2024-2025 Raghuram Subramani <raghus2247@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __boot_idt_h +#define __boot_idt_h + +#include <common.h> +#include <stdint.h> + +#define IDT_ENTRY(isr, attributes) \ + { \ + (isr & 0xffff), /* isr_low */ \ + 0, /* segment_selector */ \ + 0, /* reserved */ \ + attributes, /* attributes */ \ + (isr >> 16) /* isr_high */ \ + } + +namespace IDT +{ + +typedef struct { + uint16_t isr_low; + uint16_t segment_selector; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; +} PACKED entry_t; + +typedef struct { + uint16_t limit; /* sizeof(IDT) - 1 */ + entry_t *ptr; /* Address of IDT */ +} PACKED descriptor_t; + +void load(void); +extern "C" NORETURN void exception_handler(void); + +} + +#endif diff --git a/kernel/include/common.h b/kernel/include/common.h index 7c5270a..ecda7b2 100644 --- a/kernel/include/common.h +++ b/kernel/include/common.h @@ -21,6 +21,7 @@ #define ALWAYS_INLINE __attribute__((always_inline)) inline #define PACKED __attribute__((packed)) +#define NORETURN __attribute__((noreturn)) #define ALIGNED(x) __attribute__((aligned(x))) #define KiB 1024 diff --git a/kernel/kernel/kernel.cc b/kernel/kernel/kernel.cc index a4670a9..34a693b 100644 --- a/kernel/kernel/kernel.cc +++ b/kernel/kernel/kernel.cc @@ -17,6 +17,7 @@ */ #include <boot/gdt.h> +#include <boot/idt.h> #include <drivers/serial.h> #include <drivers/vga_text_buffer.h> #include <kernel/halt.h> @@ -44,6 +45,7 @@ kernel_main(uint32_t magic, multiboot_info_t *multiboot_info) MemoryMap::load(multiboot_info); PhysicalMM::initialize(); VirtualMM::initialize(); + IDT::load(); printk("\nKernel", "Started."); diff --git a/kernel/kernel/spinlock.cc b/kernel/kernel/spinlock.cc index 3a9031c..a57206d 100644 --- a/kernel/kernel/spinlock.cc +++ b/kernel/kernel/spinlock.cc @@ -31,5 +31,5 @@ void Spinlock::release(void) { __sync_bool_compare_and_swap(&m_lock, 1, 0); - /* TODO: Enable interrupts here */ + // __asm__ volatile("sti"); } diff --git a/kernel/mm/virtual_mm/virtual_mm.cc b/kernel/mm/virtual_mm/virtual_mm.cc index 3ba0735..e1bef9d 100644 --- a/kernel/mm/virtual_mm/virtual_mm.cc +++ b/kernel/mm/virtual_mm/virtual_mm.cc @@ -50,7 +50,7 @@ get_page_directory(void) ALWAYS_INLINE void load_page_directory(uint32_t *page_directory) { - __asm__("movl %0, %%cr3" ::"r"(page_directory)); + __asm__ volatile("movl %0, %%cr3" ::"r"(page_directory)); } bool @@ -67,10 +67,10 @@ switch_page_directory(uint32_t *page_directory) ALWAYS_INLINE static void enable_paging(void) { - __asm__("movl %%cr0, %%eax;" - "orl $0x80000000, %%eax;" - "movl %%eax, %%cr0" :: - : "eax"); + __asm__ volatile("movl %%cr0, %%eax;" + "orl $0x80000000, %%eax;" + "movl %%eax, %%cr0" :: + : "eax"); } void |