parent
9e4aaa56ba
commit
9904ac83d8
@ -0,0 +1,89 @@
|
||||
[bits 32]
|
||||
[extern isr_handler]
|
||||
|
||||
%macro ISR_NOERRORCODE 1 ; define a macro, taking one parameter
|
||||
[GLOBAL isr%1] ; %1 accesses the first parameter.
|
||||
isr%1:
|
||||
cli
|
||||
push byte 0
|
||||
push byte %1
|
||||
jmp isr_common_stub
|
||||
%endmacro
|
||||
|
||||
%macro ISR_ERRORCODE 1
|
||||
[GLOBAL isr%1]
|
||||
isr%1:
|
||||
cli
|
||||
push byte %1
|
||||
jmp isr_common_stub
|
||||
%endmacro
|
||||
|
||||
ISR_NOERRORCODE 0
|
||||
ISR_NOERRORCODE 1
|
||||
ISR_NOERRORCODE 2
|
||||
ISR_NOERRORCODE 3
|
||||
ISR_NOERRORCODE 4
|
||||
ISR_NOERRORCODE 5
|
||||
ISR_NOERRORCODE 6
|
||||
ISR_NOERRORCODE 7
|
||||
ISR_ERRORCODE 8
|
||||
ISR_NOERRORCODE 9
|
||||
ISR_ERRORCODE 10
|
||||
ISR_ERRORCODE 11
|
||||
ISR_ERRORCODE 12
|
||||
ISR_ERRORCODE 13
|
||||
ISR_ERRORCODE 14
|
||||
ISR_NOERRORCODE 15
|
||||
ISR_NOERRORCODE 16
|
||||
ISR_NOERRORCODE 17
|
||||
ISR_NOERRORCODE 18
|
||||
ISR_NOERRORCODE 19
|
||||
ISR_NOERRORCODE 20
|
||||
ISR_NOERRORCODE 21
|
||||
ISR_NOERRORCODE 22
|
||||
ISR_NOERRORCODE 23
|
||||
ISR_NOERRORCODE 24
|
||||
ISR_NOERRORCODE 25
|
||||
ISR_NOERRORCODE 26
|
||||
ISR_NOERRORCODE 27
|
||||
ISR_NOERRORCODE 28
|
||||
ISR_NOERRORCODE 29
|
||||
ISR_NOERRORCODE 30
|
||||
ISR_NOERRORCODE 31
|
||||
|
||||
; In isr.c
|
||||
[EXTERN isr_handler]
|
||||
|
||||
; This is our common ISR stub. It saves the processor state, sets
|
||||
; up for kernel mode segments, calls the C-level fault handler,
|
||||
; and finally restores the stack frame.
|
||||
isr_common_stub:
|
||||
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
|
||||
|
||||
mov ax, ds ; Lower 16-bits of eax = ds.
|
||||
push eax ; save the data segment descriptor
|
||||
|
||||
mov ax, 0x10 ; load the kernel data segment descriptor
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
call isr_handler
|
||||
|
||||
pop eax ; reload the original data segment descriptor
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
popa ; Pops edi,esi,ebp...
|
||||
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
||||
sti
|
||||
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
||||
|
||||
[GLOBAL idt_flush]
|
||||
idt_flush:
|
||||
mov eax, [esp + 4]
|
||||
lidt [eax]
|
||||
ret
|
@ -0,0 +1,5 @@
|
||||
; NOT part of the bootloader
|
||||
; this is the kernel entry code that calls main() in kernel.cpp
|
||||
|
||||
%include "boot.asm"
|
||||
%include "idt.asm"
|
@ -0,0 +1,61 @@
|
||||
#include "idt.h"
|
||||
#include "../kernel/mem.h"
|
||||
#include "../drivers/vga.h"
|
||||
|
||||
void isr_handler(registers_t regs) {
|
||||
VGA vga;
|
||||
vga.print("Received interrupt!");
|
||||
}
|
||||
|
||||
static void init_idt() {
|
||||
idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
|
||||
idt_ptr.base = (uint32_t) &idt_entries;
|
||||
|
||||
mem_set((uint8_t*) &idt_entries, 0, sizeof(idt_entry_t) * 256);
|
||||
|
||||
idt_set_gate(0, (uint32_t) isr0, 0x08, 0x8e);
|
||||
idt_set_gate(1, (uint32_t) isr1, 0x08, 0x8e);
|
||||
idt_set_gate(2, (uint32_t) isr2, 0x08, 0x8e);
|
||||
idt_set_gate(3, (uint32_t) isr3, 0x08, 0x8e);
|
||||
idt_set_gate(4, (uint32_t) isr4, 0x08, 0x8e);
|
||||
idt_set_gate(5, (uint32_t) isr5, 0x08, 0x8e);
|
||||
idt_set_gate(6, (uint32_t) isr6, 0x08, 0x8e);
|
||||
idt_set_gate(7, (uint32_t) isr7, 0x08, 0x8e);
|
||||
idt_set_gate(8, (uint32_t) isr8, 0x08, 0x8e);
|
||||
idt_set_gate(9, (uint32_t) isr9, 0x08, 0x8e);
|
||||
idt_set_gate(10, (uint32_t) isr10, 0x08, 0x8e);
|
||||
idt_set_gate(11, (uint32_t) isr11, 0x08, 0x8e);
|
||||
idt_set_gate(12, (uint32_t) isr12, 0x08, 0x8e);
|
||||
idt_set_gate(13, (uint32_t) isr13, 0x08, 0x8e);
|
||||
idt_set_gate(14, (uint32_t) isr14, 0x08, 0x8e);
|
||||
idt_set_gate(15, (uint32_t) isr15, 0x08, 0x8e);
|
||||
idt_set_gate(16, (uint32_t) isr16, 0x08, 0x8e);
|
||||
idt_set_gate(17, (uint32_t) isr17, 0x08, 0x8e);
|
||||
idt_set_gate(18, (uint32_t) isr18, 0x08, 0x8e);
|
||||
idt_set_gate(19, (uint32_t) isr19, 0x08, 0x8e);
|
||||
idt_set_gate(20, (uint32_t) isr20, 0x08, 0x8e);
|
||||
idt_set_gate(21, (uint32_t) isr21, 0x08, 0x8e);
|
||||
idt_set_gate(22, (uint32_t) isr22, 0x08, 0x8e);
|
||||
idt_set_gate(23, (uint32_t) isr23, 0x08, 0x8e);
|
||||
idt_set_gate(24, (uint32_t) isr24, 0x08, 0x8e);
|
||||
idt_set_gate(25, (uint32_t) isr25, 0x08, 0x8e);
|
||||
idt_set_gate(26, (uint32_t) isr26, 0x08, 0x8e);
|
||||
idt_set_gate(27, (uint32_t) isr27, 0x08, 0x8e);
|
||||
idt_set_gate(28, (uint32_t) isr28, 0x08, 0x8e);
|
||||
idt_set_gate(29, (uint32_t) isr29, 0x08, 0x8e);
|
||||
idt_set_gate(30, (uint32_t) isr30, 0x08, 0x8e);
|
||||
idt_set_gate(31, (uint32_t) isr31, 0x08, 0x8e);
|
||||
|
||||
idt_flush((uint32_t) &idt_ptr);
|
||||
}
|
||||
|
||||
static void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
|
||||
idt_entries[num].base_lo = base & 0xFFFF;
|
||||
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
|
||||
idt_entries[num].sel = sel;
|
||||
idt_entries[num].always0 = 0;
|
||||
|
||||
// We must uncomment the OR below when we get to using user-mode.
|
||||
// It sets the interrupt gate's privilege level to 3.
|
||||
idt_entries[num].flags = flags /* | 0x60 */;
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
#ifndef KERNEL_CPU_IDT_H
|
||||
#define KERNEL_CPU_IDT_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct registers
|
||||
{
|
||||
uint32_t ds; // Data segment selector
|
||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
|
||||
uint32_t int_no, err_code; // Interrupt number and error code (if applicable)
|
||||
uint32_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
|
||||
} registers_t;
|
||||
|
||||
void isr_handler(registers_t);
|
||||
|
||||
// A struct describing an interrupt gate.
|
||||
struct idt_entry_struct
|
||||
{
|
||||
uint16_t base_lo; // The lower 16 bits of the address to jump to when this interrupt fires.
|
||||
uint16_t sel; // Kernel segment selector.
|
||||
uint8_t always0; // This must always be zero.
|
||||
uint8_t flags; // More flags. See documentation.
|
||||
uint16_t base_hi; // The upper 16 bits of the address to jump to.
|
||||
} __attribute__((packed));
|
||||
typedef struct idt_entry_struct idt_entry_t;
|
||||
|
||||
// A struct describing a pointer to an array of interrupt handlers.
|
||||
// This is in a format suitable for giving to 'lidt'.
|
||||
struct idt_ptr_struct {
|
||||
uint16_t limit;
|
||||
uint32_t base; // The address of the first element in our idt_entry_t array.
|
||||
} __attribute__((packed));
|
||||
typedef struct idt_ptr_struct idt_ptr_t;
|
||||
|
||||
extern void idt_flush(uint32_t);
|
||||
|
||||
static void init_idt();
|
||||
static void idt_set_gate(uint8_t, uint32_t, uint16_t, uint8_t);
|
||||
|
||||
idt_entry_t idt_entries[256];
|
||||
idt_ptr_t idt_ptr;
|
||||
|
||||
// References to ASM ISR handlers
|
||||
extern void isr0();
|
||||
extern void isr1();
|
||||
extern void isr2();
|
||||
extern void isr3();
|
||||
extern void isr4();
|
||||
extern void isr5();
|
||||
extern void isr6();
|
||||
extern void isr7();
|
||||
extern void isr8();
|
||||
extern void isr9();
|
||||
extern void isr10();
|
||||
extern void isr11();
|
||||
extern void isr12();
|
||||
extern void isr13();
|
||||
extern void isr14();
|
||||
extern void isr15();
|
||||
extern void isr16();
|
||||
extern void isr17();
|
||||
extern void isr18();
|
||||
extern void isr19();
|
||||
extern void isr20();
|
||||
extern void isr21();
|
||||
extern void isr22();
|
||||
extern void isr23();
|
||||
extern void isr24();
|
||||
extern void isr25();
|
||||
extern void isr26();
|
||||
extern void isr27();
|
||||
extern void isr28();
|
||||
extern void isr29();
|
||||
extern void isr30();
|
||||
extern void isr31();
|
||||
|
||||
#endif //KERNEL_CPU_IDT_H
|
@ -1,6 +1,8 @@
|
||||
#ifndef KERNEL_MEM_H
|
||||
#define KERNEL_MEM_H
|
||||
|
||||
void mem_copy(char* source, char* destination, int num_bytes);
|
||||
void mem_copy(uint8_t* source, uint8_t* destination, int num_bytes);
|
||||
|
||||
void mem_set(uint8_t* destination, uint8_t value, uint32_t length);
|
||||
|
||||
#endif //KERNEL_MEM_H
|
||||
|
Loading…
Reference in new issue