Add initial IDT and GDT setup.
WIP interrupt handling. Interrupts do not yet return.
This commit is contained in:
@@ -17,6 +17,8 @@ section .text
|
|||||||
align 16
|
align 16
|
||||||
global _start:function (_start.end - _start)
|
global _start:function (_start.end - _start)
|
||||||
_start:
|
_start:
|
||||||
|
cli
|
||||||
|
|
||||||
extern kernel_main
|
extern kernel_main
|
||||||
call kernel_main
|
call kernel_main
|
||||||
|
|
||||||
@@ -26,3 +28,13 @@ _start:
|
|||||||
hlt
|
hlt
|
||||||
jmp .hang
|
jmp .hang
|
||||||
.end:
|
.end:
|
||||||
|
|
||||||
|
global interrupts_enable
|
||||||
|
interrupts_enable:
|
||||||
|
sti
|
||||||
|
ret
|
||||||
|
|
||||||
|
global interrupts_disable
|
||||||
|
interrupts_disable:
|
||||||
|
cli
|
||||||
|
ret
|
||||||
|
|||||||
68
src/modules/main/device_manager.cpp
Normal file
68
src/modules/main/device_manager.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "device_manager.h"
|
||||||
|
#include "console.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
static const char expected_signature[] = "RSD PTR ";
|
||||||
|
|
||||||
|
struct Acpi10RSDPDescriptor
|
||||||
|
{
|
||||||
|
char signature[8];
|
||||||
|
uint8_t checksum;
|
||||||
|
char oem_id[6];
|
||||||
|
uint8_t revision;
|
||||||
|
uint32_t rsdt_address;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct Acpi20RSDPDescriptor
|
||||||
|
{
|
||||||
|
char signature[8];
|
||||||
|
uint8_t checksum10;
|
||||||
|
char oem_id[6];
|
||||||
|
uint8_t revision;
|
||||||
|
uint32_t rsdt_address;
|
||||||
|
|
||||||
|
uint32_t length;
|
||||||
|
uint64_t xsdt_address;
|
||||||
|
uint8_t checksum20;
|
||||||
|
uint8_t reserved[3];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
uint8_t acpi_checksum(const T *p, size_t off = 0)
|
||||||
|
{
|
||||||
|
uint8_t sum = 0;
|
||||||
|
const uint8_t *c = reinterpret_cast<const uint8_t *>(p);
|
||||||
|
for (int i = off; i < sizeof(T); ++i) sum += c[i];
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_manager::device_manager(const void *root_table)
|
||||||
|
{
|
||||||
|
console *cons = console::get();
|
||||||
|
|
||||||
|
kassert(root_table != 0, "ACPI root table pointer is null.");
|
||||||
|
|
||||||
|
const Acpi10RSDPDescriptor *acpi1 =
|
||||||
|
reinterpret_cast<const Acpi10RSDPDescriptor *>(root_table);
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof(acpi1->signature); ++i)
|
||||||
|
kassert(acpi1->signature[i] == expected_signature[i],
|
||||||
|
"ACPI RSDP table signature mismatch");
|
||||||
|
|
||||||
|
uint8_t sum = acpi_checksum(acpi1, 0);
|
||||||
|
kassert(sum == 0, "ACPI 1.0 RSDP checksum mismatch.");
|
||||||
|
|
||||||
|
kassert(acpi1->revision > 1, "ACPI 1.0 not supported.");
|
||||||
|
|
||||||
|
const Acpi20RSDPDescriptor *acpi2 =
|
||||||
|
reinterpret_cast<const Acpi20RSDPDescriptor *>(acpi1);
|
||||||
|
|
||||||
|
sum = acpi_checksum(acpi2, sizeof(Acpi10RSDPDescriptor));
|
||||||
|
kassert(sum == 0, "ACPI 2.0 RSDP checksum mismatch.");
|
||||||
|
|
||||||
|
cons->puts("ACPI 2.0 tables loading...\n");
|
||||||
|
}
|
||||||
10
src/modules/main/device_manager.h
Normal file
10
src/modules/main/device_manager.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class device_manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
device_manager(const void *root_table);
|
||||||
|
|
||||||
|
device_manager() = delete;
|
||||||
|
device_manager(const device_manager &) = delete;
|
||||||
|
};
|
||||||
32
src/modules/main/interrupt_isrs.inc
Normal file
32
src/modules/main/interrupt_isrs.inc
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
ISR( 0, isr0);
|
||||||
|
ISR( 1, isr1);
|
||||||
|
ISR( 2, isr2);
|
||||||
|
ISR( 3, isr3);
|
||||||
|
ISR( 4, isr4);
|
||||||
|
ISR( 5, isr5);
|
||||||
|
ISR( 6, isr6);
|
||||||
|
ISR( 7, isr7);
|
||||||
|
ISR( 8, isr8);
|
||||||
|
ISR( 9, isr9);
|
||||||
|
ISR(10, isr10);
|
||||||
|
ISR(11, isr11);
|
||||||
|
ISR(12, isr12);
|
||||||
|
ISR(13, isr13);
|
||||||
|
ISR(14, isr14);
|
||||||
|
ISR(15, isr15);
|
||||||
|
ISR(16, isr16);
|
||||||
|
ISR(17, isr17);
|
||||||
|
ISR(18, isr18);
|
||||||
|
ISR(19, isr19);
|
||||||
|
ISR(20, isr20);
|
||||||
|
ISR(21, isr21);
|
||||||
|
ISR(22, isr22);
|
||||||
|
ISR(23, isr23);
|
||||||
|
ISR(24, isr24);
|
||||||
|
ISR(25, isr25);
|
||||||
|
ISR(26, isr26);
|
||||||
|
ISR(27, isr27);
|
||||||
|
ISR(28, isr28);
|
||||||
|
ISR(29, isr29);
|
||||||
|
ISR(30, isr30);
|
||||||
|
ISR(31, isr31);
|
||||||
297
src/modules/main/interrupts.cpp
Normal file
297
src/modules/main/interrupts.cpp
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "console.h"
|
||||||
|
#include "interrupts.h"
|
||||||
|
|
||||||
|
enum class gdt_flags : uint8_t
|
||||||
|
{
|
||||||
|
ac = 0x01,
|
||||||
|
rw = 0x02,
|
||||||
|
dc = 0x04,
|
||||||
|
ex = 0x08,
|
||||||
|
r1 = 0x20,
|
||||||
|
r2 = 0x40,
|
||||||
|
r3 = 0x60,
|
||||||
|
pr = 0x80,
|
||||||
|
|
||||||
|
res_1 = 0x10
|
||||||
|
};
|
||||||
|
|
||||||
|
inline gdt_flags
|
||||||
|
operator | (gdt_flags lhs, gdt_flags rhs)
|
||||||
|
{
|
||||||
|
return static_cast<gdt_flags>(
|
||||||
|
static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gdt_descriptor
|
||||||
|
{
|
||||||
|
uint16_t limit_low;
|
||||||
|
uint16_t base_low;
|
||||||
|
uint8_t base_mid;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t granularity;
|
||||||
|
uint8_t base_high;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct idt_descriptor
|
||||||
|
{
|
||||||
|
uint16_t base_low;
|
||||||
|
uint16_t selector;
|
||||||
|
uint8_t ist;
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t base_mid;
|
||||||
|
uint32_t base_high;
|
||||||
|
uint32_t reserved; // must be zero
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct table_ptr
|
||||||
|
{
|
||||||
|
uint16_t limit;
|
||||||
|
uint64_t base;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
gdt_descriptor g_gdt_table[10];
|
||||||
|
idt_descriptor g_idt_table[256];
|
||||||
|
table_ptr g_gdtr;
|
||||||
|
table_ptr g_idtr;
|
||||||
|
|
||||||
|
|
||||||
|
struct registers;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void idt_write();
|
||||||
|
void idt_load();
|
||||||
|
|
||||||
|
void gdt_write();
|
||||||
|
void gdt_load();
|
||||||
|
|
||||||
|
void isr_handler(registers);
|
||||||
|
|
||||||
|
#define ISR(i, name) extern void name ()
|
||||||
|
#include "interrupt_isrs.inc"
|
||||||
|
#undef ISR
|
||||||
|
}
|
||||||
|
|
||||||
|
void idt_dump(const table_ptr &table);
|
||||||
|
void gdt_dump(const table_ptr &table);
|
||||||
|
|
||||||
|
void
|
||||||
|
set_gdt_entry(uint8_t i, uint32_t base, uint32_t limit, bool is64, gdt_flags flags)
|
||||||
|
{
|
||||||
|
g_gdt_table[i].limit_low = limit & 0xffff;
|
||||||
|
|
||||||
|
g_gdt_table[i].base_low = base & 0xffff;
|
||||||
|
g_gdt_table[i].base_mid = (base >> 16) & 0xff;
|
||||||
|
g_gdt_table[i].base_high = (base >> 24) & 0xff;
|
||||||
|
|
||||||
|
g_gdt_table[i].granularity =
|
||||||
|
((limit >> 16) & 0xf) | (is64 ? 0xa0 : 0xc0);
|
||||||
|
|
||||||
|
g_gdt_table[i].flags = static_cast<uint8_t>(flags | gdt_flags::res_1 | gdt_flags::pr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_idt_entry(uint8_t i, uint64_t addr, uint16_t selector, uint8_t flags)
|
||||||
|
{
|
||||||
|
g_idt_table[i].base_low = addr & 0xffff;
|
||||||
|
g_idt_table[i].base_mid = (addr >> 16) & 0xffff;
|
||||||
|
g_idt_table[i].base_high = (addr >> 32) & 0xffffffff;
|
||||||
|
g_idt_table[i].selector = selector;
|
||||||
|
g_idt_table[i].flags = flags;
|
||||||
|
g_idt_table[i].ist = 0;
|
||||||
|
g_idt_table[i].reserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
interrupts_init()
|
||||||
|
{
|
||||||
|
uint8_t *p;
|
||||||
|
|
||||||
|
gdt_load();
|
||||||
|
gdt_dump(g_gdtr);
|
||||||
|
|
||||||
|
p = reinterpret_cast<uint8_t *>(&g_gdt_table);
|
||||||
|
for (int i = 0; i < sizeof(g_gdt_table); ++i) p[i] = 0;
|
||||||
|
|
||||||
|
g_gdtr.limit = sizeof(g_gdt_table) - 1;
|
||||||
|
g_gdtr.base = reinterpret_cast<uint64_t>(&g_gdt_table);
|
||||||
|
|
||||||
|
set_gdt_entry(1, 0, 0xfffff, false, gdt_flags::rw);
|
||||||
|
set_gdt_entry(2, 0, 0xfffff, false, gdt_flags::rw | gdt_flags::ex | gdt_flags::dc);
|
||||||
|
set_gdt_entry(3, 0, 0xfffff, false, gdt_flags::rw);
|
||||||
|
set_gdt_entry(4, 0, 0xfffff, false, gdt_flags::rw | gdt_flags::ex);
|
||||||
|
|
||||||
|
set_gdt_entry(6, 0, 0xfffff, false, gdt_flags::rw);
|
||||||
|
set_gdt_entry(7, 0, 0xfffff, true, gdt_flags::rw | gdt_flags::ex);
|
||||||
|
|
||||||
|
gdt_write();
|
||||||
|
gdt_load();
|
||||||
|
gdt_dump(g_gdtr);
|
||||||
|
|
||||||
|
p = reinterpret_cast<uint8_t *>(&g_idt_table);
|
||||||
|
for (int i = 0; i < sizeof(g_idt_table); ++i) p[i] = 0;
|
||||||
|
|
||||||
|
g_idtr.limit = sizeof(g_idt_table) - 1;
|
||||||
|
g_idtr.base = reinterpret_cast<uint64_t>(&g_idt_table);
|
||||||
|
|
||||||
|
#define ISR(i, name) set_idt_entry(i, reinterpret_cast<uint64_t>(& name), 0x38, 0x8e);
|
||||||
|
#include "interrupt_isrs.inc"
|
||||||
|
#undef ISR
|
||||||
|
|
||||||
|
idt_write();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct registers
|
||||||
|
{
|
||||||
|
uint64_t ds;
|
||||||
|
uint64_t rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax;
|
||||||
|
uint64_t interrupt, errorcode;
|
||||||
|
uint64_t rip, cs, eflags, user_esp, ss;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
isr_handler(registers regs)
|
||||||
|
{
|
||||||
|
console::get()->puts("received interrupt: ");
|
||||||
|
console::get()->put_dec(regs.interrupt);
|
||||||
|
console::get()->puts("\n");
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
gdt_dump(const table_ptr &table)
|
||||||
|
{
|
||||||
|
console *cons = console::get();
|
||||||
|
|
||||||
|
cons->puts("Loaded GDT at: ");
|
||||||
|
cons->put_hex(table.base);
|
||||||
|
cons->puts(" size: ");
|
||||||
|
cons->put_dec(table.limit + 1);
|
||||||
|
cons->puts(" bytes\n");
|
||||||
|
|
||||||
|
int count = (table.limit + 1) / sizeof(gdt_descriptor);
|
||||||
|
const gdt_descriptor *gdt =
|
||||||
|
reinterpret_cast<const gdt_descriptor *>(table.base);
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
uint32_t base =
|
||||||
|
(gdt[i].base_high << 24) |
|
||||||
|
(gdt[i].base_mid << 16) |
|
||||||
|
gdt[i].base_low;
|
||||||
|
|
||||||
|
uint32_t limit =
|
||||||
|
static_cast<uint32_t>(gdt[i].granularity & 0x0f) << 16 |
|
||||||
|
gdt[i].limit_low;
|
||||||
|
|
||||||
|
cons->puts(" Entry ");
|
||||||
|
cons->put_dec(i);
|
||||||
|
|
||||||
|
cons->puts(": Base ");
|
||||||
|
cons->put_hex(base);
|
||||||
|
|
||||||
|
cons->puts(" Limit ");
|
||||||
|
cons->put_hex(limit);
|
||||||
|
|
||||||
|
cons->puts(" Privs ");
|
||||||
|
cons->put_dec((gdt[i].flags >> 5) & 0x03);
|
||||||
|
|
||||||
|
cons->puts(" Flags ");
|
||||||
|
|
||||||
|
if (gdt[i].flags & 0x80) {
|
||||||
|
cons->puts("P ");
|
||||||
|
|
||||||
|
if (gdt[i].flags & 0x08)
|
||||||
|
cons->puts("EX ");
|
||||||
|
else
|
||||||
|
cons->puts(" ");
|
||||||
|
|
||||||
|
if (gdt[i].flags & 0x04)
|
||||||
|
cons->puts("DC ");
|
||||||
|
else
|
||||||
|
cons->puts(" ");
|
||||||
|
|
||||||
|
if (gdt[i].flags & 0x02)
|
||||||
|
cons->puts("RW ");
|
||||||
|
else
|
||||||
|
cons->puts(" ");
|
||||||
|
|
||||||
|
if (gdt[i].granularity & 0x80)
|
||||||
|
cons->puts("KB ");
|
||||||
|
else
|
||||||
|
cons->puts(" B ");
|
||||||
|
|
||||||
|
if ((gdt[i].granularity & 0x60) == 0x20)
|
||||||
|
cons->puts("64");
|
||||||
|
else if ((gdt[i].granularity & 0x60) == 0x40)
|
||||||
|
cons->puts("32");
|
||||||
|
else
|
||||||
|
cons->puts("16");
|
||||||
|
}
|
||||||
|
|
||||||
|
cons->puts("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
idt_dump(const table_ptr &table)
|
||||||
|
{
|
||||||
|
console *cons = console::get();
|
||||||
|
|
||||||
|
cons->puts("Loaded IDT at: ");
|
||||||
|
cons->put_hex(table.base);
|
||||||
|
cons->puts(" size: ");
|
||||||
|
cons->put_dec(table.limit + 1);
|
||||||
|
cons->puts(" bytes\n");
|
||||||
|
|
||||||
|
int count = (table.limit + 1) / sizeof(idt_descriptor);
|
||||||
|
const idt_descriptor *idt =
|
||||||
|
reinterpret_cast<const idt_descriptor *>(table.base);
|
||||||
|
|
||||||
|
if (count > 32) count = 32;
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
uint64_t base =
|
||||||
|
(static_cast<uint64_t>(idt[i].base_high) << 32) |
|
||||||
|
(static_cast<uint64_t>(idt[i].base_mid) << 16) |
|
||||||
|
idt[i].base_low;
|
||||||
|
|
||||||
|
cons->puts(" Entry ");
|
||||||
|
cons->put_dec(i);
|
||||||
|
|
||||||
|
cons->puts(": Base ");
|
||||||
|
cons->put_hex(base);
|
||||||
|
|
||||||
|
cons->puts(" Sel(");
|
||||||
|
cons->put_dec(idt[i].selector & 0x3);
|
||||||
|
cons->puts(",");
|
||||||
|
cons->put_dec((idt[i].selector & 0x4) >> 2);
|
||||||
|
cons->puts(",");
|
||||||
|
cons->put_dec(idt[i].selector >> 3);
|
||||||
|
cons->puts(") ");
|
||||||
|
|
||||||
|
cons->puts("IST ");
|
||||||
|
cons->put_dec(idt[i].ist);
|
||||||
|
|
||||||
|
switch (idt[i].flags & 0xf) {
|
||||||
|
case 0x5: cons->puts(" 32tsk "); break;
|
||||||
|
case 0x6: cons->puts(" 16int "); break;
|
||||||
|
case 0x7: cons->puts(" 16trp "); break;
|
||||||
|
case 0xe: cons->puts(" 32int "); break;
|
||||||
|
case 0xf: cons->puts(" 32trp "); break;
|
||||||
|
default:
|
||||||
|
cons->puts(" ?");
|
||||||
|
cons->put_hex(idt[i].flags & 0xf);
|
||||||
|
cons->puts(" ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cons->puts("DPL ");
|
||||||
|
cons->put_dec((idt[i].flags >> 5) & 0x3);
|
||||||
|
|
||||||
|
if (idt[i].flags & 0x80)
|
||||||
|
cons->puts(" P");
|
||||||
|
|
||||||
|
cons->puts("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/modules/main/interrupts.h
Normal file
8
src/modules/main/interrupts.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void interrupts_enable();
|
||||||
|
void interrupts_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void interrupts_init();
|
||||||
112
src/modules/main/interrupts.s
Normal file
112
src/modules/main/interrupts.s
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
extern g_idtr
|
||||||
|
extern g_gdtr
|
||||||
|
|
||||||
|
global idt_write
|
||||||
|
idt_write:
|
||||||
|
lidt [g_idtr]
|
||||||
|
ret
|
||||||
|
|
||||||
|
global idt_load
|
||||||
|
idt_load:
|
||||||
|
sidt [g_idtr]
|
||||||
|
ret
|
||||||
|
|
||||||
|
global gdt_write
|
||||||
|
gdt_write:
|
||||||
|
lgdt [g_gdtr]
|
||||||
|
ret
|
||||||
|
|
||||||
|
global gdt_load
|
||||||
|
gdt_load:
|
||||||
|
sgdt [g_gdtr]
|
||||||
|
ret
|
||||||
|
|
||||||
|
%macro ISR_NOERRCODE 1
|
||||||
|
global isr%1
|
||||||
|
isr%1:
|
||||||
|
cli
|
||||||
|
push byte 0
|
||||||
|
push byte %1
|
||||||
|
jmp isr_handler_prelude
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro ISR_ERRCODE 1
|
||||||
|
global isr%1
|
||||||
|
isr%1:
|
||||||
|
cli
|
||||||
|
push byte %1
|
||||||
|
jmp isr_handler_prelude
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
ISR_NOERRCODE 0
|
||||||
|
ISR_NOERRCODE 1
|
||||||
|
ISR_NOERRCODE 2
|
||||||
|
ISR_NOERRCODE 3
|
||||||
|
ISR_NOERRCODE 4
|
||||||
|
ISR_NOERRCODE 5
|
||||||
|
ISR_NOERRCODE 6
|
||||||
|
ISR_NOERRCODE 7
|
||||||
|
ISR_ERRCODE 8
|
||||||
|
ISR_NOERRCODE 9
|
||||||
|
ISR_ERRCODE 10
|
||||||
|
ISR_ERRCODE 11
|
||||||
|
ISR_ERRCODE 12
|
||||||
|
ISR_ERRCODE 13
|
||||||
|
ISR_ERRCODE 14
|
||||||
|
ISR_NOERRCODE 15
|
||||||
|
ISR_NOERRCODE 16
|
||||||
|
ISR_NOERRCODE 17
|
||||||
|
ISR_NOERRCODE 18
|
||||||
|
ISR_NOERRCODE 19
|
||||||
|
ISR_NOERRCODE 20
|
||||||
|
ISR_NOERRCODE 21
|
||||||
|
ISR_NOERRCODE 22
|
||||||
|
ISR_NOERRCODE 23
|
||||||
|
ISR_NOERRCODE 24
|
||||||
|
ISR_NOERRCODE 25
|
||||||
|
ISR_NOERRCODE 26
|
||||||
|
ISR_NOERRCODE 27
|
||||||
|
ISR_NOERRCODE 28
|
||||||
|
ISR_NOERRCODE 29
|
||||||
|
ISR_NOERRCODE 30
|
||||||
|
ISR_NOERRCODE 31
|
||||||
|
|
||||||
|
extern isr_handler
|
||||||
|
global isr_handler_prelude
|
||||||
|
isr_handler_prelude:
|
||||||
|
push rax
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rbx
|
||||||
|
push rbp
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
|
||||||
|
mov ax, ds ; Save the data segment register
|
||||||
|
push rax
|
||||||
|
|
||||||
|
mov ax, 0x10 ; load the kernel data segment
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
call isr_handler
|
||||||
|
|
||||||
|
pop rax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rbp
|
||||||
|
pop rbx
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rax
|
||||||
|
|
||||||
|
add rsp, 8 ; because the ISRs added err/num
|
||||||
|
sti
|
||||||
|
iretq
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
#include "interrupts.h"
|
||||||
#include "kernel_data.h"
|
#include "kernel_data.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
@@ -27,6 +28,8 @@ load_console(const popcorn_data *header)
|
|||||||
header->log_length};
|
header->log_length};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" { void isr31(); }
|
||||||
|
|
||||||
void
|
void
|
||||||
kernel_main(popcorn_data *header)
|
kernel_main(popcorn_data *header)
|
||||||
{
|
{
|
||||||
@@ -37,5 +40,14 @@ kernel_main(popcorn_data *header)
|
|||||||
cons.set_color(0x08, 0x00);
|
cons.set_color(0x08, 0x00);
|
||||||
cons.puts(GIT_VERSION " booting...\n");
|
cons.puts(GIT_VERSION " booting...\n");
|
||||||
|
|
||||||
|
interrupts_init();
|
||||||
|
interrupts_enable();
|
||||||
|
|
||||||
|
cons.puts("Interrupts initialized.\n");
|
||||||
|
|
||||||
|
// isr31();
|
||||||
|
__asm__ __volatile__("int $31");
|
||||||
|
|
||||||
|
cons.puts("boogity!");
|
||||||
do_the_set_registers(header);
|
do_the_set_registers(header);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user