summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/gdt.c71
-rw-r--r--kernel/gdt.h54
-rw-r--r--kernel/interrupts.c19
-rw-r--r--kernel/interrupts.h29
-rw-r--r--kernel/kernel.c32
5 files changed, 116 insertions, 89 deletions
diff --git a/kernel/gdt.c b/kernel/gdt.c
index f72f1ab..24b52f7 100644
--- a/kernel/gdt.c
+++ b/kernel/gdt.c
@@ -1,4 +1,3 @@
-// http://wiki.osdev.org/GDT_Tutorial
#include "kernel.h"
#include "gdt.h"
#include "asm_gdt.h"
@@ -8,28 +7,69 @@
#define GDT_SIZE 6
-//https://wiki.osdev.org/Task_State_Segment
-//Define the TSS as a global structure, boah TODO: move to own page?
+static uint8_t gdt_structs[GDT_SIZE*8*SMP_MAX_PROC]; // GLOBAL DESCRIPTOR TABLES
+
+typedef volatile struct strtss{
+ unsigned short link;
+ unsigned short link_h;
+ unsigned long esp0;
+ unsigned short ss0;
+ unsigned short ss0_h;
+ unsigned long esp1;
+ unsigned short ss1;
+ unsigned short ss1_h;
+ unsigned long esp2;
+ unsigned short ss2;
+ unsigned short ss2_h;
+ unsigned long cr3;
+ unsigned long eip;
+ unsigned long eflags;
+ unsigned long eax;
+ unsigned long ecx;
+ unsigned long edx;
+ unsigned long ebx;
+ unsigned long esp;
+ unsigned long ebp;
+ unsigned long esi;
+ unsigned long edi;
+ unsigned short es;
+ unsigned short es_h;
+ unsigned short cs;
+ unsigned short cs_h;
+ unsigned short ss;
+ unsigned short ss_h;
+ unsigned short ds;
+ unsigned short ds_h;
+ unsigned short fs;
+ unsigned short fs_h;
+ unsigned short gs;
+ unsigned short gs_h;
+ unsigned short ldt;
+ unsigned short ldt_h;
+ unsigned short trap;
+ unsigned short iomap;
+}__attribute__((packed)) tss_struct;
+
tss_struct sys_tss[SMP_MAX_PROC];
+typedef struct GDT_struct
+{
+ uint32_t base;
+ uint32_t limit;
+ uint32_t type;
+}GDT;
+
void install_tss(uint32_t cpu,uint32_t esp0){
// now fill each value
// set values necessary
sys_tss[cpu].ss0 = 0x10; //kernel data
sys_tss[cpu].esp0 = esp0;
-
// now set the IO bitmap (not necessary, so set above limit)
// sys_tss.iomap = ( unsigned short ) sizeof( tss_struct );
}
-typedef struct GDT_struct
-{
- uint32_t base;
- uint32_t limit;
- uint32_t type;
-}GDT;
-
+/*
//alternative
struct gdt_entry_bits
{
@@ -51,6 +91,7 @@ struct gdt_entry_bits
unsigned int gran :1; //1 to use 4k page addressing, 0 for byte addressing
unsigned int base_high :8;
} __packed; //or __attribute__((packed))
+*/
void setup_gdt(uint8_t *gdt_struct)
{
@@ -105,6 +146,8 @@ void gdt_init()
{
static int last_cpu=0;
+ if(last_cpu>=SMP_MAX_PROC)kpanic("not enough SMP_MAX_PROC");
+
/*
Pr=1 Privl 1 Exec DC RW Ac
0x9A == 1001 1010 == 1 00 1 1 0 1 0
@@ -113,8 +156,9 @@ void gdt_init()
0xF2 == 1111 0010 == 1 11 1 0 0 1 0
*/
-//static uint8_t gdt_struct[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE
- uint8_t *gdt_struct=kballoc(1); //[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE
+ //static uint8_t gdt_struct[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE
+ //uint8_t *gdt_struct=kballoc(1); //[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE
+ uint8_t *gdt_struct=&gdt_structs[GDT_SIZE*8*last_cpu];
GDT myGDT[GDT_SIZE];
//selector 0x0
@@ -156,6 +200,5 @@ void gdt_init()
last_cpu++;
setup_gdt(gdt_struct);
-
}
diff --git a/kernel/gdt.h b/kernel/gdt.h
index 314cc99..9b7eece 100644
--- a/kernel/gdt.h
+++ b/kernel/gdt.h
@@ -1,49 +1,21 @@
// https://xarnze.com/posts/post/Tutorial:%20Entering%20User%20mode
// http://wiki.osdev.org/TSS
// http://wiki.osdev.org/Global_Descriptor_Table
+// http://wiki.osdev.org/GDT_Tutorial
+//https://wiki.osdev.org/Task_State_Segment
#include <stdint.h>
-typedef volatile struct strtss{
- unsigned short link;
- unsigned short link_h;
- unsigned long esp0;
- unsigned short ss0;
- unsigned short ss0_h;
- unsigned long esp1;
- unsigned short ss1;
- unsigned short ss1_h;
- unsigned long esp2;
- unsigned short ss2;
- unsigned short ss2_h;
- unsigned long cr3;
- unsigned long eip;
- unsigned long eflags;
- unsigned long eax;
- unsigned long ecx;
- unsigned long edx;
- unsigned long ebx;
- unsigned long esp;
- unsigned long ebp;
- unsigned long esi;
- unsigned long edi;
- unsigned short es;
- unsigned short es_h;
- unsigned short cs;
- unsigned short cs_h;
- unsigned short ss;
- unsigned short ss_h;
- unsigned short ds;
- unsigned short ds_h;
- unsigned short fs;
- unsigned short fs_h;
- unsigned short gs;
- unsigned short gs_h;
- unsigned short ldt;
- unsigned short ldt_h;
- unsigned short trap;
- unsigned short iomap;
-}__attribute__((packed)) tss_struct;
-
+/** Call this one on each CPU to get a fresh 6-entries GDT
+ * * 0
+ * * ring0 code
+ * * ring0 data
+ * * ring3 code
+ * * ring3 data
+ * * tss
+ */
void gdt_init();
+
+/** update tss.esp0 for a given cpu
+ */
void install_tss(uint32_t cpu,uint32_t esp0);
diff --git a/kernel/interrupts.c b/kernel/interrupts.c
index d0de5ed..44ab9b5 100644
--- a/kernel/interrupts.c
+++ b/kernel/interrupts.c
@@ -242,23 +242,22 @@ void interrupts_init(uint16_t sel)
int_install_ir(17, 0b10001110, 0x08,&exc17);
int_install_ir(18, 0b10001110, 0x08,&exc18);
- // PIT
+ // PIT (IOAPIC)
int_install_ir(0x90, 0b10001110, 0x08,&int0);
- // Keyboard
+ // Keyboard (IOAPIC)
int_install_ir(0x91, 0b10001110, 0x08,&int1);
- // Mouse
+ // Mouse (IOAPIC)
int_install_ir(0x92, 0b10001110, 0x08,&int12);
- // System Calls / they can be called from ring3 (0b11)
- int_install_ir(0x80, 0b11101110, 0x08,&int128);
+ // APIC Timer (LAPIC)
+ int_install_ir(0x8C, 0b10001110, 0x08,&int200);
- // IPI
- int_install_ir(0x81, 0b11101110, 0x08,&int129);
+ // System Calls (User Software / Ring 3)
+ int_install_ir(0x80, 0b11101110, 0x08,&int128);
- int_install_ir(170, 0b11101110, 0x08,&int170);
+ // Inter Processesor Interrupts (Kernel Software)
+ int_install_ir(0x81, 0b10001110, 0x08,&int129);
- // APIC Timer
- int_install_ir(0x8C, 0b11101110, 0x08,&int200);
}
diff --git a/kernel/interrupts.h b/kernel/interrupts.h
index 48e8c20..80fa95e 100644
--- a/kernel/interrupts.h
+++ b/kernel/interrupts.h
@@ -11,29 +11,38 @@
*
* Exceptions
* ----------
- * 0x00-0x12 Exceptions
+ * * 0x00-0x12 Exceptions
*
* Legacy PIC
* ----------
- * 0x20-0x27 disabled pic
- * 0x28-0x36 disabled pic
+ * * 0x20-0x27 disabled pic
+ * * 0x28-0x36 disabled pic
*
* Hardware Interrupts
* -------------------
* This interrupts are remapped by the IOAPIC
*
- * 0x0 PIT Timer -> 0x90
- * 0x1 Keyboard -> 0x91
- * 0xC Mouse -> 0x92
+ * * 0x0 PIT Timer -> 0x90
+ * * 0x1 Keyboard -> 0x91
+ * * 0xC Mouse -> 0x92
*
* Local Interrupts from LAPICs
* ----------------------
- * 0x8C APIC Timer
+ * * 0x8C APIC Timer
*
* Software Interrupts
* -------------------
- * 0x80 System Call
- * 0x81 IPI
+ * * 0x80 System Call
+ * * 0x81 IPI
+ *
+ * Usage
+ * -----
+ *
+ * Run interrupts_init() once first with the desired selector, usually 0x08.
+ * After that you can install the interrupts on each cpu via interrupts_install.
+ * interrupt_handler() and exception_handler() will be called accordingly from
+ * the interrupt handlers this functionality is backed by. You can find them
+ * in asm_int.h
*/
#define INTERRUPT_PIT_TIMER 0x90
@@ -46,5 +55,7 @@
void interrupts_init(uint16_t sel);
void interrupts_install();
+uint32_t interrupt_handler(uint32_t esp, uint32_t irq);
+void exception_handler(uint32_t esp, uint32_t irq);
#endif
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 724b1a0..12b2063 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -37,9 +37,25 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("Compiled on: %s at %s",__DATE__,__TIME__);
klog("Version: git-commit: %s",GIT_REVISION);
klog("======================================");
-
+
klog("Communication Port (COM1) init ..."); //delayed info
+ fixme("Check if kernel size does not exceed memory limits!");
+
+ // collect some info (before we start paging)
+ klog("Search / Read Multiboot Structures ... ");
+ multiboot_information *info;
+ info=get_multiboot(eax, ebx);
+
+ klog("Search / Read ACPI Structures... ");
+ smp_processors procdata;
+ bool acpi_found=acpi_find(&procdata);
+
+ klog("Search / Read MP Structures... ");
+ smp_processors procdata2;
+ bool mp_found=mp_find(&procdata2);
+ //
+
klog("Global Descriptor Table (GDT) init ...");
gdt_init();
@@ -56,20 +72,6 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("Mouse init ...");
mouse_init();
- // gather some info (before we start paging)
- klog("Search / Read Multiboot Structures ... ");
- multiboot_information *info;
- info=get_multiboot(eax, ebx);
-
- klog("Search / Read ACPI Structures... ");
- smp_processors procdata;
- bool acpi_found=acpi_find(&procdata);
-
- klog("Search / Read MP Structures... ");
- smp_processors procdata2;
- bool mp_found=mp_find(&procdata2);
- //
-
// memory management
klog("Memory init ... ");
uint32_t kernel_blocks=mem_init(info);