commit
f7392578c9
@ -31,7 +31,9 @@ OBJS = \
|
||||
list.o \
|
||||
memory.o \
|
||||
serial.o \
|
||||
gdt.o
|
||||
gdt.o \
|
||||
idt.o \
|
||||
isr.o
|
||||
|
||||
|
||||
DEPS = $(OBJS:.o=.d)
|
||||
@ -39,7 +41,7 @@ DEPS = $(OBJS:.o=.d)
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): CPPFLAGS += -MMD -Iinclude -I ../libs/libc/include/
|
||||
$(TARGET): CFLAGS += $(K_EXTRA_CFLAGS)
|
||||
$(TARGET): CFLAGS += $(K_EXTRA_CFLAGS) -g
|
||||
$(TARGET): LDFLAGS += -Wl,-Tk.lds
|
||||
$(TARGET): LDLIBS = -L../libs/libc -lc
|
||||
$(TARGET): $(OBJS)
|
||||
|
26
k/gdt.c
26
k/gdt.c
@ -2,7 +2,7 @@
|
||||
|
||||
static struct gdt gdt = { 0 };
|
||||
|
||||
static void create_kernel_ds()
|
||||
static void create_kernel_ds(void)
|
||||
{
|
||||
struct gdt_entry *entry = gdt.entries + KERNEL_DS_INDEX;
|
||||
|
||||
@ -30,7 +30,7 @@ static void create_kernel_ds()
|
||||
entry->base_3 = (base >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static void create_kernel_cs()
|
||||
static void create_kernel_cs(void)
|
||||
{
|
||||
struct gdt_entry *entry = gdt.entries + KERNEL_CS_INDEX;
|
||||
|
||||
@ -58,13 +58,13 @@ static void create_kernel_cs()
|
||||
entry->base_3 = (base >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static void create_gdt()
|
||||
static void create_gdt(void)
|
||||
{
|
||||
create_kernel_ds();
|
||||
create_kernel_cs();
|
||||
}
|
||||
|
||||
static void load_gdt()
|
||||
static void load_gdt(void)
|
||||
{
|
||||
struct gdt_r gdtr;
|
||||
gdtr.addr = (uint32_t)&gdt;
|
||||
@ -76,12 +76,9 @@ static void load_gdt()
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static void load_ds()
|
||||
static void load_ds(void)
|
||||
{
|
||||
struct segment_selector selector;
|
||||
selector.index = KERNEL_DS_INDEX;
|
||||
selector.table_indicator = 0;
|
||||
selector.rpl = 0;
|
||||
struct segment_selector selector = KERNEL_DS_SEGMENT_SELECTOR;
|
||||
|
||||
asm volatile("movw %0, %%ax\n"
|
||||
"movw %%ax, %%ds\n"
|
||||
@ -93,12 +90,9 @@ static void load_ds()
|
||||
: "ax");
|
||||
}
|
||||
|
||||
static void load_cs()
|
||||
static void load_cs(void)
|
||||
{
|
||||
struct segment_selector selector;
|
||||
selector.index = KERNEL_CS_INDEX;
|
||||
selector.table_indicator = 0;
|
||||
selector.rpl = 0;
|
||||
struct segment_selector selector = KERNEL_CS_SEGMENT_SELECTOR;
|
||||
|
||||
asm volatile("pushl %0\n"
|
||||
"pushl $1f\n"
|
||||
@ -108,13 +102,13 @@ static void load_cs()
|
||||
: "m" (selector));
|
||||
}
|
||||
|
||||
static void reload_segment_selectors()
|
||||
static void reload_segment_selectors(void)
|
||||
{
|
||||
load_ds();
|
||||
load_cs();
|
||||
}
|
||||
|
||||
void init_gdt()
|
||||
void init_gdt(void)
|
||||
{
|
||||
create_gdt();
|
||||
load_gdt();
|
||||
|
5
k/gdt.h
5
k/gdt.h
@ -9,6 +9,9 @@
|
||||
#define KERNEL_CS_INDEX 1
|
||||
#define KERNEL_DS_INDEX 2
|
||||
|
||||
#define KERNEL_CS_SEGMENT_SELECTOR {0, 0, KERNEL_CS_INDEX}
|
||||
#define KERNEL_DS_SEGMENT_SELECTOR {0, 0, KERNEL_DS_INDEX}
|
||||
|
||||
struct gdt_entry
|
||||
{
|
||||
uint16_t limit_1 : 16; // 16 lsbs of the segment limit
|
||||
@ -60,6 +63,6 @@ struct segment_selector
|
||||
uint16_t index : 13; // index of the entry in the table
|
||||
} __attribute__ ((packed));
|
||||
|
||||
void init_gdt();
|
||||
void init_gdt(void);
|
||||
|
||||
#endif /* !GDT_H */
|
||||
|
88
k/idt.c
Normal file
88
k/idt.c
Normal file
@ -0,0 +1,88 @@
|
||||
#include "idt.h"
|
||||
#include "stdio.h"
|
||||
|
||||
static struct idt idt = { 0 };
|
||||
|
||||
static struct idt_entry_descriptor idt_entries_descriptors[IDT_NB_ENTRIES] = {
|
||||
{(uint32_t)&isr_divide, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 0
|
||||
{(uint32_t)&isr_debug, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 1
|
||||
{(uint32_t)&isr_nmi, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 2
|
||||
{(uint32_t)&isr_breakpoint, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 3
|
||||
{(uint32_t)&isr_overflow, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 4
|
||||
{(uint32_t)&isr_bound_range_exceeded, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 5
|
||||
{(uint32_t)&isr_invalid_opcode, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 6
|
||||
{(uint32_t)&isr_device_not_available, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 7
|
||||
{(uint32_t)&isr_double_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 8
|
||||
{(uint32_t)&isr_coprocessor_segment_overrun, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 9
|
||||
{(uint32_t)&isr_invalid_tss, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 10
|
||||
{(uint32_t)&isr_segment_not_present, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 11
|
||||
{(uint32_t)&isr_stack_segment_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 12
|
||||
{(uint32_t)&isr_general_protection, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 13
|
||||
{(uint32_t)&isr_page_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 14
|
||||
{0, {0, 0, 0}, 0}, // 15
|
||||
{(uint32_t)&isr_fpu_floating_point_error, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 16
|
||||
{(uint32_t)&isr_alignment_check, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 17
|
||||
{(uint32_t)&isr_machine_check, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 18
|
||||
{(uint32_t)&isr_simd_floating_point_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 19
|
||||
{(uint32_t)&isr_virtualization_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 20
|
||||
{(uint32_t)&isr_control_protection_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 21
|
||||
{0, {0, 0, 0}, 0}, // 22
|
||||
{0, {0, 0, 0}, 0}, // 23
|
||||
{0, {0, 0, 0}, 0}, // 24
|
||||
{0, {0, 0, 0}, 0}, // 25
|
||||
{0, {0, 0, 0}, 0}, // 26
|
||||
{0, {0, 0, 0}, 0}, // 27
|
||||
{0, {0, 0, 0}, 0}, // 28
|
||||
{0, {0, 0, 0}, 0}, // 29
|
||||
{0, {0, 0, 0}, 0}, // 30
|
||||
{0, {0, 0, 0}, 0} // 31
|
||||
};
|
||||
|
||||
void interrupt_handler(struct isr_param *isr_param)
|
||||
{
|
||||
printf("Oh no %d!\r\n", isr_param->int_vector);
|
||||
}
|
||||
|
||||
struct idt_entry create_idt_entry(struct idt_entry_descriptor descriptor)
|
||||
{
|
||||
struct idt_entry res = { 0 };
|
||||
|
||||
res.selector = descriptor.selector;
|
||||
res.offset_1 = descriptor.offset & 0xffff;
|
||||
res.offset_2 = (descriptor.offset >> 16) & 0xffff;
|
||||
|
||||
res.type = descriptor.type;
|
||||
res.size = 1;
|
||||
res.desc_priv = 0;
|
||||
res.present = 1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void create_idt(void)
|
||||
{
|
||||
for (int i = 0; i < IDT_NB_ENTRIES; ++i)
|
||||
{
|
||||
struct idt_entry entry = create_idt_entry(idt_entries_descriptors[i]);
|
||||
idt.entries[i] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void load_idt(void)
|
||||
{
|
||||
struct idt_r idtr;
|
||||
idtr.addr = (uint32_t)&idt;
|
||||
idtr.limit = IDT_SIZE - 1;
|
||||
|
||||
asm volatile("lidt %0\n"
|
||||
:
|
||||
: "m" (idtr)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
void init_idt(void)
|
||||
{
|
||||
create_idt();
|
||||
load_idt();
|
||||
}
|
51
k/idt.h
Normal file
51
k/idt.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef IDT_H
|
||||
#define IDT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "gdt.h"
|
||||
#include "isr.h"
|
||||
|
||||
#define IDT_NB_ENTRIES 32
|
||||
#define IDT_SIZE (IDT_NB_ENTRIES * sizeof(struct idt_entry))
|
||||
|
||||
#define INTERRUPT_TYPE 0x6
|
||||
#define TRAP_TYPE 0x7
|
||||
|
||||
struct idt_entry
|
||||
{
|
||||
uint16_t offset_1 : 16;
|
||||
struct segment_selector selector;
|
||||
|
||||
uint8_t zero_1 : 8; // unused, set to 0
|
||||
uint8_t type : 3; // gate type
|
||||
uint8_t size : 1;
|
||||
uint8_t zero_2 : 1; // set to 0 for interrupt and trap gates
|
||||
uint8_t desc_priv : 2; // Descriptor privilege
|
||||
uint8_t present : 1;
|
||||
|
||||
uint16_t offset_2 : 16;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct idt
|
||||
{
|
||||
struct idt_entry entries[IDT_NB_ENTRIES];
|
||||
};
|
||||
|
||||
struct idt_r
|
||||
{
|
||||
uint16_t limit;
|
||||
uint32_t addr;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct idt_entry_descriptor
|
||||
{
|
||||
uint32_t offset;
|
||||
struct segment_selector selector;
|
||||
char type;
|
||||
};
|
||||
|
||||
void init_idt(void);
|
||||
|
||||
void interrupt_handler(struct isr_param *isr_param);
|
||||
|
||||
#endif /* !IDT_H */
|
129
k/isr.S
Normal file
129
k/isr.S
Normal file
@ -0,0 +1,129 @@
|
||||
.section .text
|
||||
|
||||
isr:
|
||||
pushal
|
||||
pushl %esp
|
||||
add $32, (%esp)
|
||||
call interrupt_handler
|
||||
add $4, %esp
|
||||
popal
|
||||
add $8, %esp
|
||||
iret
|
||||
|
||||
.global isr_divide
|
||||
isr_divide:
|
||||
pushl $0 // error code padding
|
||||
pushl $0 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_debug
|
||||
isr_debug:
|
||||
pushl $0 // error code padding
|
||||
pushl $1 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_nmi
|
||||
isr_nmi:
|
||||
pushl $0 // error code padding
|
||||
pushl $2 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_breakpoint
|
||||
isr_breakpoint:
|
||||
pushl $0 // error code padding
|
||||
pushl $3 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_overflow
|
||||
isr_overflow:
|
||||
pushl $0 // error code padding
|
||||
pushl $4 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_bound_range_exceeded
|
||||
isr_bound_range_exceeded:
|
||||
pushl $0 // error code padding
|
||||
pushl $5 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_invalid_opcode
|
||||
isr_invalid_opcode:
|
||||
pushl $0 // error code padding
|
||||
pushl $6 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_device_not_available
|
||||
isr_device_not_available:
|
||||
pushl $0 // error code padding
|
||||
pushl $7 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_double_fault
|
||||
isr_double_fault:
|
||||
pushl $8 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_coprocessor_segment_overrun
|
||||
isr_coprocessor_segment_overrun:
|
||||
pushl $0 // error code padding
|
||||
pushl $9 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_invalid_tss
|
||||
isr_invalid_tss:
|
||||
pushl $10 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_segment_not_present
|
||||
isr_segment_not_present:
|
||||
pushl $11 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_stack_segment_fault
|
||||
isr_stack_segment_fault:
|
||||
pushl $12 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_general_protection
|
||||
isr_general_protection:
|
||||
pushl $13 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_page_fault
|
||||
isr_page_fault:
|
||||
pushl $14 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_fpu_floating_point_error
|
||||
isr_fpu_floating_point_error:
|
||||
pushl $0 // error code padding
|
||||
pushl $16 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_alignment_check
|
||||
isr_alignment_check:
|
||||
pushl $17 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_machine_check
|
||||
isr_machine_check:
|
||||
pushl $0 // error code padding
|
||||
pushl $18 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_simd_floating_point_exception
|
||||
isr_simd_floating_point_exception:
|
||||
pushl $0 // error code padding
|
||||
pushl $19 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_virtualization_exception
|
||||
isr_virtualization_exception:
|
||||
pushl $0 // error code padding
|
||||
pushl $20 // int vector
|
||||
jmp isr
|
||||
|
||||
.global isr_control_protection_exception
|
||||
isr_control_protection_exception:
|
||||
pushl $21 // int vector
|
||||
jmp isr
|
32
k/isr.h
Normal file
32
k/isr.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef ISR_H
|
||||
#define ISR_H
|
||||
|
||||
struct isr_param
|
||||
{
|
||||
uint32_t int_vector;
|
||||
uint32_t error_code;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
void isr_divide(void);
|
||||
void isr_debug(void);
|
||||
void isr_nmi(void);
|
||||
void isr_breakpoint(void);
|
||||
void isr_overflow(void);
|
||||
void isr_bound_range_exceeded(void);
|
||||
void isr_invalid_opcode(void);
|
||||
void isr_device_not_available(void);
|
||||
void isr_double_fault(void);
|
||||
void isr_coprocessor_segment_overrun(void);
|
||||
void isr_invalid_tss(void);
|
||||
void isr_segment_not_present(void);
|
||||
void isr_stack_segment_fault(void);
|
||||
void isr_general_protection(void);
|
||||
void isr_page_fault(void);
|
||||
void isr_fpu_floating_point_error(void);
|
||||
void isr_alignment_check(void);
|
||||
void isr_machine_check(void);
|
||||
void isr_simd_floating_point_exception(void);
|
||||
void isr_virtualization_exception(void);
|
||||
void isr_control_protection_exception(void);
|
||||
|
||||
#endif /* !ISR_H */
|
16
k/k.c
16
k/k.c
@ -23,15 +23,17 @@
|
||||
*/
|
||||
#include <k/kstd.h>
|
||||
|
||||
#include "multiboot.h"
|
||||
#include "stdio.h"
|
||||
#include "serial.h"
|
||||
#include "gdt.h"
|
||||
#include "idt.h"
|
||||
#include "multiboot.h"
|
||||
#include "serial.h"
|
||||
#include "stdio.h"
|
||||
|
||||
static void k_init(void)
|
||||
{
|
||||
init_serial();
|
||||
init_gdt();
|
||||
init_idt();
|
||||
}
|
||||
|
||||
void k_main(unsigned long magic, multiboot_info_t *info)
|
||||
@ -43,8 +45,14 @@ void k_main(unsigned long magic, multiboot_info_t *info)
|
||||
char *fb = (void *)0xb8000;
|
||||
|
||||
k_init();
|
||||
|
||||
asm volatile("int $3\n"
|
||||
:
|
||||
:
|
||||
:);
|
||||
printf("bonjour\r\n");
|
||||
|
||||
|
||||
|
||||
for (unsigned i = 0; ; ) {
|
||||
*fb = star[i++ % 4];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user