Skip to content
This repository was archived by the owner on Jan 14, 2026. It is now read-only.

Commit c8685d3

Browse files
committed
add interrupt handling and vector test functionality
1 parent 63f0e55 commit c8685d3

10 files changed

Lines changed: 358 additions & 20 deletions

File tree

src/boot/config.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
KERNEL_OFFSET EQU 0x10000 ; カーネルをロードするアドレス
2-
SECTOR_COUNT EQU 25 ; 読み込むセクタの数
2+
SECTOR_COUNT EQU 31 ; 読み込むセクタの数
33
START_SECTOR EQU 2 ; 開始するセクタ番号
44
CYLINDER_NUM EQU 0 ; シリンダ番号
55
HEAD_NUM EQU 0 ; ヘッド番号

src/include/interrupt/idt.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef _INTERRUPT_IDT_H
2+
#define _INTERRUPT_IDT_H
3+
4+
#include <stdint.h>
5+
6+
void idt_init(void);
7+
8+
#endif /* _INTERRUPT_IDT_H */

src/include/tests/define.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
#define _TESTS_CONFIG_H
33

44
// テストを実行するかどうか
5-
// #define TEST_TRUE
5+
#define TEST_TRUE
66

77
#ifdef TEST_TRUE
88
// メモリマップとメモリのテスト
99
#define MEM_TEST
1010
// 割り込みのテスト
1111
#define INTERRUPT_TEST
12-
12+
// 割り込みベクタのテスト
13+
#define INTERRUPT_VECTOR_TEST
1314

1415
/* -------- 宣言 -------- */
1516
#ifdef MEM_TEST
@@ -20,6 +21,10 @@ void mem_test();
2021
void interrupt_test();
2122
#endif /* INTERRUPT_TEST */
2223

24+
#ifdef INTERRUPT_VECTOR_TEST
25+
void interrupt_vector_test();
26+
#endif /* INTERRUPT_VECTOR_TEST */
27+
2328
#endif /* TEST_TRUE */
2429

2530
#endif /* _TESTS_CONFIG_H */

src/kernel/interrupt/idt.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#include <config.h>
2+
#include <interrupt/idt.h>
3+
#include <interrupt/irq.h>
4+
5+
6+
/* PIC ports */
7+
#define PIC1_COMMAND 0x20
8+
#define PIC1_DATA 0x21
9+
#define PIC2_COMMAND 0xA0
10+
#define PIC2_DATA 0xA1
11+
12+
static inline uint8_t inb(uint16_t port) {
13+
uint8_t ret;
14+
__asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
15+
return ret;
16+
}
17+
18+
static inline void outb(uint16_t port, uint8_t val) {
19+
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
20+
}
21+
22+
/* Remap PIC to vectors starting at 32 */
23+
static void pic_remap(void) {
24+
unsigned char a1, a2;
25+
a1 = inb(PIC1_DATA);
26+
a2 = inb(PIC2_DATA);
27+
28+
outb(PIC1_COMMAND, 0x11);
29+
outb(PIC2_COMMAND, 0x11);
30+
outb(PIC1_DATA, 0x20); /* Master PIC vector offset */
31+
outb(PIC2_DATA, 0x28); /* Slave PIC vector offset */
32+
outb(PIC1_DATA, 0x04);
33+
outb(PIC2_DATA, 0x02);
34+
outb(PIC1_DATA, 0x01);
35+
outb(PIC2_DATA, 0x01);
36+
37+
outb(PIC1_DATA, a1);
38+
outb(PIC2_DATA, a2);
39+
}
40+
41+
extern void load_idt(void* ptr, unsigned size);
42+
43+
/* Minimal IDT entry struct */
44+
struct idt_entry {
45+
uint16_t base_lo;
46+
uint16_t sel;
47+
uint8_t always0;
48+
uint8_t flags;
49+
uint16_t base_hi;
50+
} __attribute__((packed));
51+
52+
struct idt_ptr {
53+
uint16_t limit;
54+
uint32_t base;
55+
} __attribute__((packed));
56+
57+
extern void isr_stub_table(void); /* assembly stubs */
58+
59+
#define IDT_ENTRIES 256
60+
static struct idt_entry idt[IDT_ENTRIES];
61+
static struct idt_ptr idtp;
62+
63+
static void idt_set_gate(int n, uint32_t handler) {
64+
idt[n].base_lo = handler & 0xFFFF;
65+
idt[n].sel = 0x08; // code segment
66+
idt[n].always0 = 0;
67+
idt[n].flags = 0x8E;
68+
idt[n].base_hi = (handler >> 16) & 0xFFFF;
69+
}
70+
71+
/**
72+
* @fn irq_handler_c
73+
* @param vec 割り込みベクター番号
74+
*/
75+
void irq_handler_c(uint32_t vec) {
76+
if (vec >= 32 && vec < 32 + 16) {
77+
uint32_t irq = vec - 32;
78+
interrupt_raise((irq << 16) | 0u);
79+
if (irq >= 8) outb(PIC2_COMMAND, 0x20);
80+
outb(PIC1_COMMAND, 0x20);
81+
}
82+
}
83+
84+
/**
85+
* @fn idt_init
86+
* @brief IDTを初期化する
87+
*/
88+
void idt_init(void) {
89+
pic_remap();
90+
91+
/* 明示的に各isrシンボルをextern宣言し、それをIDTに登録する(脳筋だぜぇ〜www */
92+
extern void isr32(void);
93+
extern void isr33(void);
94+
extern void isr34(void);
95+
extern void isr35(void);
96+
extern void isr36(void);
97+
extern void isr37(void);
98+
extern void isr38(void);
99+
extern void isr39(void);
100+
extern void isr40(void);
101+
extern void isr41(void);
102+
extern void isr42(void);
103+
extern void isr43(void);
104+
extern void isr44(void);
105+
extern void isr45(void);
106+
extern void isr46(void);
107+
extern void isr47(void);
108+
109+
idt_set_gate(32, (uint32_t)isr32);
110+
idt_set_gate(33, (uint32_t)isr33);
111+
idt_set_gate(34, (uint32_t)isr34);
112+
idt_set_gate(35, (uint32_t)isr35);
113+
idt_set_gate(36, (uint32_t)isr36);
114+
idt_set_gate(37, (uint32_t)isr37);
115+
idt_set_gate(38, (uint32_t)isr38);
116+
idt_set_gate(39, (uint32_t)isr39);
117+
idt_set_gate(40, (uint32_t)isr40);
118+
idt_set_gate(41, (uint32_t)isr41);
119+
idt_set_gate(42, (uint32_t)isr42);
120+
idt_set_gate(43, (uint32_t)isr43);
121+
idt_set_gate(44, (uint32_t)isr44);
122+
idt_set_gate(45, (uint32_t)isr45);
123+
idt_set_gate(46, (uint32_t)isr46);
124+
idt_set_gate(47, (uint32_t)isr47);
125+
126+
idtp.limit = sizeof(struct idt_entry) * IDT_ENTRIES - 1;
127+
idtp.base = (uint32_t)&idt;
128+
load_idt(&idtp, sizeof(idtp));
129+
130+
}

src/kernel/interrupt/irq.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,28 @@
55
* Save EFLAGS and disable interrupts.
66
*/
77
uint32_t irq_save(void) {
8-
uint32_t flags;
9-
asm volatile(
10-
"pushf\n\t"
11-
"pop %0\n\t"
12-
: "=r" (flags)
13-
:
14-
: "memory"
15-
);
16-
asm volatile("cli" ::: "memory");
17-
return flags;
8+
uint32_t flags;
9+
asm volatile(
10+
"pushf\n\t"
11+
"pop %0\n\t"
12+
: "=r" (flags)
13+
:
14+
: "memory"
15+
);
16+
asm volatile("cli" ::: "memory");
17+
return flags;
1818
}
1919

2020
/**
2121
* @fn irq_restore
2222
* Restore EFLAGS.
2323
*/
2424
void irq_restore(uint32_t flags) {
25-
asm volatile(
26-
"push %0\n\t"
27-
"popf\n\t"
28-
:
29-
: "r" (flags)
30-
: "memory"
31-
);
25+
asm volatile(
26+
"push %0\n\t"
27+
"popf\n\t"
28+
:
29+
: "r" (flags)
30+
: "memory"
31+
);
3232
}

src/kernel/interrupt/irq_stubs.asm

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
[BITS 32]
2+
3+
global isr_stub_table
4+
isr_stub_table:
5+
6+
extern irq_handler_c
7+
8+
global isr32
9+
isr32:
10+
pusha
11+
push dword 32
12+
call irq_handler_c
13+
add esp, 4
14+
popa
15+
iretd
16+
17+
global isr33
18+
isr33:
19+
pusha
20+
push dword 33
21+
call irq_handler_c
22+
add esp, 4
23+
popa
24+
iretd
25+
26+
global isr34
27+
isr34:
28+
pusha
29+
push dword 34
30+
call irq_handler_c
31+
add esp, 4
32+
popa
33+
iretd
34+
35+
global isr35
36+
isr35:
37+
pusha
38+
push dword 35
39+
call irq_handler_c
40+
add esp, 4
41+
popa
42+
iretd
43+
44+
global isr36
45+
isr36:
46+
pusha
47+
push dword 36
48+
call irq_handler_c
49+
add esp, 4
50+
popa
51+
iretd
52+
53+
global isr37
54+
isr37:
55+
pusha
56+
push dword 37
57+
call irq_handler_c
58+
add esp, 4
59+
popa
60+
iretd
61+
62+
global isr38
63+
isr38:
64+
pusha
65+
push dword 38
66+
call irq_handler_c
67+
add esp, 4
68+
popa
69+
iretd
70+
71+
global isr39
72+
isr39:
73+
pusha
74+
push dword 39
75+
call irq_handler_c
76+
add esp, 4
77+
popa
78+
iretd
79+
80+
global isr40
81+
isr40:
82+
pusha
83+
push dword 40
84+
call irq_handler_c
85+
add esp, 4
86+
popa
87+
iretd
88+
89+
global isr41
90+
isr41:
91+
pusha
92+
push dword 41
93+
call irq_handler_c
94+
add esp, 4
95+
popa
96+
iretd
97+
98+
global isr42
99+
isr42:
100+
pusha
101+
push dword 42
102+
call irq_handler_c
103+
add esp, 4
104+
popa
105+
iretd
106+
107+
global isr43
108+
isr43:
109+
pusha
110+
push dword 43
111+
call irq_handler_c
112+
add esp, 4
113+
popa
114+
iretd
115+
116+
global isr44
117+
isr44:
118+
pusha
119+
push dword 44
120+
call irq_handler_c
121+
add esp, 4
122+
popa
123+
iretd
124+
125+
global isr45
126+
isr45:
127+
pusha
128+
push dword 45
129+
call irq_handler_c
130+
add esp, 4
131+
popa
132+
iretd
133+
134+
global isr46
135+
isr46:
136+
pusha
137+
push dword 46
138+
call irq_handler_c
139+
add esp, 4
140+
popa
141+
iretd
142+
143+
global isr47
144+
isr47:
145+
pusha
146+
push dword 47
147+
call irq_handler_c
148+
add esp, 4
149+
popa
150+
iretd

src/kernel/interrupt/load_idt.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <stdint.h>
2+
3+
void load_idt(void* ptr, unsigned size) {
4+
(void)size;
5+
__asm__ volatile ("lidtl (%0)" : : "r" (ptr));
6+
}

src/kernel/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <device/pci.h>
44
#include <device/keyboard.h>
55
#include <interrupt/irq.h>
6+
#include <interrupt/idt.h>
67
#include <mem/map.h>
78
#include <mem/manager.h>
89

@@ -31,6 +32,7 @@ void kmain() {
3132

3233
new_line();
3334
printk("> INTERRUPT INIT\n");
35+
idt_init();
3436
interrupt_init();
3537
printk("ok\n");
3638

0 commit comments

Comments
 (0)