commit 850434fb99e947be383d59a9948572dd0369f8eb
parent 7030b7656ba51bba8e58893af64d666be5992080
Author: evenfri <evenfri256@gmail.com>
Date: Sun, 23 Aug 2026 21:16:40 +0800
add interupts
Diffstat:
| M | dat.h | | | 28 | ++++++++++++++++++++++++++++ |
| M | fns.h | | | 7 | +++++++ |
| A | gdt.asm | | | 42 | ++++++++++++++++++++++++++++++++++++++++++ |
| A | idt.c | | | 54 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | init.c | | | 9 | ++++++++- |
| A | ints.asm | | | 75 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | mkfile | | | 3 | +++ |
7 files changed, 217 insertions(+), 1 deletion(-)
diff --git a/dat.h b/dat.h
@@ -29,4 +29,32 @@ enum vga_color {
vga_color_white = 15,
};
+/* idt */
+typedef struct {
+ uint16_t isr_low; /* the lower 16 bits of the isr's address */
+ uint16_t kernel_cs; /* the gdt segment selector that the cpu will load into cs before calling the isr */
+ uint8_t reserved; /* set to zero */
+ uint8_t attr; /* type and attributes; see the idt page */
+ uint16_t isr_high; /* the higher 16 bits of the isr's address */
+} __attribute__((packed)) idt_entry_t;
+
+typedef struct {
+ uint16_t limit;
+ uint32_t base;
+} __attribute__((packed)) idtr_t;
+
+typedef void (*int_handler)();
+
+#define icw_1 0x11
+
+#define pic_1 0x20
+#define pic_2 0xa0
+#define pic_1_comm pic_1
+#define pic_1_data (pic_1+1)
+#define pic_2_comm pic_2
+#define pic_2_data (pic_2+1)
+
+#define irq_0 0x20
+#define irq_8 0x28
+
#endif /* dat_h */
diff --git a/fns.h b/fns.h
@@ -40,4 +40,11 @@ void tty_clear(void);
void tty_putchar(char c);
void tty_write(const char* data, size_t size);
+/* gdt */
+extern void gdt_init(void);
+
+/* idt */
+void idt_register(unsigned char vec, int_handler handler);
+void idt_init(void);
+
#endif /* fns_h */
diff --git a/gdt.asm b/gdt.asm
@@ -0,0 +1,42 @@
+bits 32
+
+global gdt_init
+
+section .data
+align 4
+
+gdt_desc:
+ dw gdt_end - gdt - 1 ; limit
+ dd gdt ; start
+
+gdt:
+gdt_null:
+ dd 0x00000000
+ dd 0x00000000
+
+gdt_code:
+ dd 0x0000ffff
+ dd 0x00cf9a00
+
+gdt_data:
+ dd 0x0000ffff
+ dd 0x00cf9200
+
+gdt_end:
+
+section .text
+
+gdt_init:
+ lgdt [gdt_desc]
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ jmp 0x08:.clean_pipe
+
+.clean_pipe:
+ ret
diff --git a/idt.c b/idt.c
@@ -0,0 +1,54 @@
+#include "oxytoxin.h"
+
+static idt_entry_t idt[256];
+static idtr_t idtr;
+
+void excp_handler() {
+ asm volatile ("cli; hlt");
+}
+
+void pic_remap() {
+ asm volatile ("cli");
+
+ outb(pic_1_comm, icw_1); io_wait();
+ outb(pic_2_comm, icw_1); io_wait();
+
+ outb(pic_1_data, irq_0); io_wait();
+ outb(pic_2_data, irq_8); io_wait();
+
+ outb(pic_1_data, 0x01); io_wait();
+ outb(pic_2_data, 0x01); io_wait();
+
+ outb(pic_1_data, 0xfc); io_wait();
+ outb(pic_2_data, 0xff); io_wait();
+}
+
+void idt_load() {
+ int idt_row_count;
+
+ idt_row_count = sizeof(idt) / sizeof(idt[0]);
+ idtr.base = (unsigned int)(&idt[0]);
+ idtr.limit = (sizeof(idt_entry_t) * idt_row_count) - 1;
+ asm volatile ("lidt %0" : : "m" (idtr));
+}
+
+void idt_register(unsigned char vec, int_handler handler) {
+ unsigned int addr;
+
+ addr = (unsigned int) handler;
+ idt[vec].isr_low = addr & 0xffffffff;
+ idt[vec].kernel_cs = 0x08;
+ idt[vec].reserved = 0;
+ idt[vec].attr = 0x8e;
+ idt[vec].isr_high = addr >> 16;
+}
+
+void idt_init(void) {
+ asm volatile ("cli");
+ for (int i = 0; i < 256; i++) {
+ idt_register(i, excp_handler);
+ }
+
+ pic_remap();
+ idt_load();
+}
diff --git a/init.c b/init.c
@@ -1,12 +1,19 @@
#include "oxytoxin.h"
+void stub(void) {
+}
+
void start_kernel(uint32_t magic, multiboot_info_t *mbi) {
(void)magic;
(void)mbi;
tty_init();
+ gdt_init();
+ idt_init();
+
+ idt_register(33, stub);
- tty_write("hello, oxytoxin kernel\n", 23);
+ asm volatile ("sti");
while (1) {
asm volatile ("hlt");
diff --git a/ints.asm b/ints.asm
@@ -0,0 +1,75 @@
+bits 32
+
+extern excp_handler
+
+%macro isr_no_err_stub 1
+global isr_stub_%1
+isr_stub_%1:
+ push dword 0
+ push dword %1
+ jmp isr_common_stub
+%endmacro
+
+%macro isr_err_stub 1
+global isr_stub_%1
+isr_stub_%1:
+ push dword %1
+ jmp isr_common_stub
+%endmacro
+
+section .text
+
+isr_common_stub:
+ pusha
+
+ mov ax, ds
+ push eax
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+
+ call excp_handler
+
+ pop eax
+ mov ds, ax
+ mov es, ax
+
+ ; heh, popa
+ popa
+ add esp, 8
+ iret
+
+isr_no_err_stub 0
+isr_no_err_stub 1
+isr_no_err_stub 2
+isr_no_err_stub 3
+isr_no_err_stub 4
+isr_no_err_stub 5
+isr_no_err_stub 6
+isr_no_err_stub 7
+isr_err_stub 8
+isr_no_err_stub 9
+isr_err_stub 10
+isr_err_stub 11
+isr_err_stub 12
+isr_err_stub 13
+isr_err_stub 14
+isr_no_err_stub 15
+isr_no_err_stub 16
+isr_err_stub 17
+isr_no_err_stub 18
+isr_no_err_stub 19
+isr_no_err_stub 20
+isr_no_err_stub 21
+isr_no_err_stub 22
+isr_no_err_stub 23
+isr_no_err_stub 24
+isr_no_err_stub 25
+isr_no_err_stub 26
+isr_no_err_stub 27
+isr_no_err_stub 28
+isr_no_err_stub 29
+isr_err_stub 30
+isr_no_err_stub 31
+
diff --git a/mkfile b/mkfile
@@ -13,6 +13,9 @@ dirs =
ofiles = boot.$o \
vga.$o \
tty.$o \
+ gdt.$o \
+ ints.$o \
+ idt.$o \
init.$o \
hfiles = dat.h \