...
This commit is contained in:
16
src/boot.asm
16
src/boot.asm
@@ -1,5 +1,6 @@
|
|||||||
global _start
|
global _start
|
||||||
extern kernel_main
|
extern kernel_main
|
||||||
|
extern setup_idt
|
||||||
|
|
||||||
%define FLAGS 0b10
|
%define FLAGS 0b10
|
||||||
%define MAGIC 0x1BADB002
|
%define MAGIC 0x1BADB002
|
||||||
@@ -25,6 +26,17 @@ section .bss
|
|||||||
pd:
|
pd:
|
||||||
resb 4096
|
resb 4096
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
align 8
|
||||||
|
idt64:
|
||||||
|
resb 4096
|
||||||
|
|
||||||
|
section .data
|
||||||
|
align 8
|
||||||
|
idt64_descriptor:
|
||||||
|
dw 4095 ; IDT size (256 entries * 16 bytes - 1)
|
||||||
|
dq idt64 ; IDT base address
|
||||||
|
|
||||||
section .data
|
section .data
|
||||||
align 8
|
align 8
|
||||||
gdt64:
|
gdt64:
|
||||||
@@ -140,6 +152,10 @@ section .text
|
|||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
|
call setup_idt
|
||||||
|
sti
|
||||||
|
|
||||||
call kernel_main
|
call kernel_main
|
||||||
.hang:
|
.hang:
|
||||||
hlt
|
hlt
|
||||||
|
|||||||
114
src/idt.asm
Normal file
114
src/idt.asm
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
global setup_idt
|
||||||
|
extern handle_isr
|
||||||
|
|
||||||
|
%macro ISR_NOERR 1
|
||||||
|
isr_stub_%1:
|
||||||
|
push qword 0
|
||||||
|
push qword %1
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro ISR_ERR 1
|
||||||
|
isr_stub_%1:
|
||||||
|
push qword %1
|
||||||
|
jmp isr_common
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro GENERATE_NUB_ISR_NOERR 2
|
||||||
|
%assign i %1
|
||||||
|
%rep (%2 - %1 + 1)
|
||||||
|
ISR_NOERR i
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 64
|
||||||
|
setup_idt:
|
||||||
|
ret
|
||||||
|
|
||||||
|
isr_common:
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push rbp
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
mov rdi, rsp
|
||||||
|
call handle_isr
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rbp
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
add rsp, 16
|
||||||
|
iretq
|
||||||
|
|
||||||
|
; CPU exceptions 0-31. Some of there contain error codes, so we define them manually
|
||||||
|
ISR_NOERR 0
|
||||||
|
ISR_NOERR 1
|
||||||
|
ISR_NOERR 2
|
||||||
|
ISR_NOERR 3
|
||||||
|
ISR_NOERR 4
|
||||||
|
ISR_NOERR 5
|
||||||
|
ISR_NOERR 6
|
||||||
|
ISR_NOERR 7
|
||||||
|
ISR_ERR 8
|
||||||
|
ISR_NOERR 9
|
||||||
|
ISR_ERR 10
|
||||||
|
ISR_ERR 11
|
||||||
|
ISR_ERR 12
|
||||||
|
ISR_ERR 13
|
||||||
|
ISR_ERR 14
|
||||||
|
ISR_NOERR 15
|
||||||
|
ISR_NOERR 16
|
||||||
|
ISR_ERR 17
|
||||||
|
ISR_NOERR 18
|
||||||
|
ISR_NOERR 19
|
||||||
|
ISR_NOERR 20
|
||||||
|
ISR_NOERR 21
|
||||||
|
ISR_NOERR 22
|
||||||
|
ISR_NOERR 23
|
||||||
|
ISR_NOERR 24
|
||||||
|
ISR_NOERR 25
|
||||||
|
ISR_NOERR 26
|
||||||
|
ISR_NOERR 27
|
||||||
|
ISR_NOERR 28
|
||||||
|
ISR_NOERR 29
|
||||||
|
ISR_ERR 30
|
||||||
|
ISR_NOERR 31
|
||||||
|
|
||||||
|
; The remaining isr-s does not have an error code
|
||||||
|
GENERATE_ISRS 32, 255
|
||||||
|
|
||||||
|
%macro GENERATE_ISR_TABLE 2
|
||||||
|
%assign i %1
|
||||||
|
%rep (%2 - %1 + 1)
|
||||||
|
dq isr_stub_%[i]
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
section .data
|
||||||
|
global isr_stub_table
|
||||||
|
isr_stub_table:
|
||||||
|
GENERATE_ISR_TABLE 0, 255
|
||||||
80
src/idt.c
80
src/idt.c
@@ -1,31 +1,18 @@
|
|||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
#include "kernel.h"
|
||||||
#define IDT_SIZE 256
|
|
||||||
|
|
||||||
#define PIC1_COMMAND 0x20
|
#define PIC1_COMMAND 0x20
|
||||||
#define PIC1_DATA 0x21
|
#define PIC1_DATA 0x21
|
||||||
#define PIC2_COMMAND 0xA0
|
#define PIC2_COMMAND 0xA0
|
||||||
#define PIC2_DATA 0xA1
|
#define PIC2_DATA 0xA1
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
u16 address_low;
|
|
||||||
u16 selector;
|
|
||||||
u8 ist;
|
|
||||||
u8 flags;
|
|
||||||
u16 address_mid;
|
|
||||||
u32 address_high;
|
|
||||||
u32 reserved;
|
|
||||||
} __attribute__((packed)) interrupt_descriptor;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u16 limit;
|
u16 limit;
|
||||||
u64 base;
|
u64 base;
|
||||||
} __attribute__((packed)) idtr_t;
|
} __attribute__((packed)) idtr_t;
|
||||||
|
|
||||||
extern void* isr_stub_table[];
|
|
||||||
static irq_handler_t irq_handlers[16] = {0};
|
static irq_handler_t irq_handlers[16] = {0};
|
||||||
|
|
||||||
static const char* exception_messages[32] = {
|
static const char* exception_messages[32] = {
|
||||||
@@ -63,32 +50,17 @@ static const char* exception_messages[32] = {
|
|||||||
"reserved",
|
"reserved",
|
||||||
};
|
};
|
||||||
|
|
||||||
static interrupt_descriptor idt[IDT_SIZE];
|
void register_irq_handler(u8 irq, irq_handler_t handler)
|
||||||
|
|
||||||
static void pic_remap(int offset1, int offset2)
|
|
||||||
{
|
{
|
||||||
u8 a1, a2;
|
if (irq >= 16)
|
||||||
|
{
|
||||||
|
kernel_panic();
|
||||||
|
}
|
||||||
|
|
||||||
a1 = inb(PIC1_DATA);
|
irq_handlers[irq] = handler;
|
||||||
a2 = inb(PIC2_DATA);
|
|
||||||
|
|
||||||
outb(PIC1_COMMAND, 0x11);
|
|
||||||
outb(PIC2_COMMAND, 0x11);
|
|
||||||
|
|
||||||
outb(PIC1_DATA, offset1);
|
|
||||||
outb(PIC2_DATA, offset2);
|
|
||||||
|
|
||||||
outb(PIC1_DATA, 4);
|
|
||||||
outb(PIC2_DATA, 2);
|
|
||||||
|
|
||||||
outb(PIC1_DATA, 0x01);
|
|
||||||
outb(PIC2_DATA, 0x01);
|
|
||||||
|
|
||||||
outb(PIC1_DATA, a1);
|
|
||||||
outb(PIC2_DATA, a2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pic_send_eoi(u8 irq)
|
static inline void pic_send_eoi(u8 irq)
|
||||||
{
|
{
|
||||||
if (irq >= 8)
|
if (irq >= 8)
|
||||||
{
|
{
|
||||||
@@ -98,42 +70,6 @@ static void pic_send_eoi(u8 irq)
|
|||||||
outb(PIC1_COMMAND, 0x20);
|
outb(PIC1_COMMAND, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_irq_handler(u8 irq, irq_handler_t handler)
|
|
||||||
{
|
|
||||||
irq_handlers[irq] = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void idt_set_descriptor(u8 vector, void* handler, u8 dpl)
|
|
||||||
{
|
|
||||||
interrupt_descriptor* entry = &idt[vector];
|
|
||||||
|
|
||||||
entry->address_low = (u64)handler & 0xFFFF;
|
|
||||||
entry->address_mid = ((u64)handler >> 16) & 0xFFFF;
|
|
||||||
entry->address_high = (u64)handler >> 32;
|
|
||||||
entry->selector = 0x08;
|
|
||||||
entry->flags = 0b1110 | ((dpl & 0b11) << 5) | (1 << 7);
|
|
||||||
entry->ist = 0;
|
|
||||||
entry->reserved = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_idt(void)
|
|
||||||
{
|
|
||||||
pic_remap(0x20, 0x28);
|
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
idt_set_descriptor(i, isr_stub_table[i], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
idtr_t idtr = {
|
|
||||||
.base = (uintptr_t)&idt[0],
|
|
||||||
.limit = (u16)sizeof(interrupt_descriptor) * IDT_SIZE - 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
__asm__ volatile("lidt %0" : : "m"(idtr));
|
|
||||||
__asm__ volatile("sti");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_isr(isr_frame_t* frame)
|
void handle_isr(isr_frame_t* frame)
|
||||||
{
|
{
|
||||||
if (frame->int_no < 32)
|
if (frame->int_no < 32)
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ typedef struct
|
|||||||
|
|
||||||
typedef void (*irq_handler_t)(const isr_frame_t*);
|
typedef void (*irq_handler_t)(const isr_frame_t*);
|
||||||
|
|
||||||
void init_idt(void);
|
|
||||||
|
|
||||||
static inline void outb(u16 port, u8 val)
|
static inline void outb(u16 port, u8 val)
|
||||||
{
|
{
|
||||||
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||||
|
|||||||
@@ -9,10 +9,6 @@ void kernel_main()
|
|||||||
vga_print_success();
|
vga_print_success();
|
||||||
vga_print(" VGA intialzied\n");
|
vga_print(" VGA intialzied\n");
|
||||||
|
|
||||||
init_idt();
|
|
||||||
vga_print_success();
|
|
||||||
vga_print(" IDT intialzied\n");
|
|
||||||
|
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
vga_print_success();
|
vga_print_success();
|
||||||
vga_print(" Keyboard intialzied\n");
|
vga_print(" Keyboard intialzied\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user