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

Commit f8b069d

Browse files
committed
add paging functionality and tests; update GDT installation process
1 parent 88e9d97 commit f8b069d

13 files changed

Lines changed: 196 additions & 35 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ OUT_DIR = bin
1313
CFLAGS = -Wimplicit-function-declaration -ffreestanding -m32 -c -Wall -Wextra -I$(INCLUDE)
1414
LDFLAGS = -m elf_i386
1515
NFLAGS = -f bin
16-
QEMU_FLAGS = -monitor stdio -no-reboot
16+
QEMU_FLAGS = -monitor stdio -no-reboot -d int,guest_errors -D kernel.log
1717
CONSOLE = -display curses
1818

1919
SOURCES = $(shell find $(SRC_KERNEL) -name "*.c")

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 30 ; 読み込むセクタの数
2+
SECTOR_COUNT EQU 37 ; 読み込むセクタの数
33
START_SECTOR EQU 2 ; 開始するセクタ番号
44
CYLINDER_NUM EQU 0 ; シリンダ番号
55
HEAD_NUM EQU 0 ; ヘッド番号

src/include/mem/paging.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef _MEM_PAGING_H
2+
#define _MEM_PAGING_H
3+
4+
void paging_init_identity(uint32_t map_mb);
5+
void paging_enable(void);
6+
7+
#endif /* _MEM_PAGING_H */

src/include/mem/segment.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#ifndef _MEM_SEGMENT_H
22
#define _MEM_SEGMENT_H
33

4+
void gdt_build();
45
void gdt_install();
6+
void gdt_dump();
7+
void gdt_install_lgdt();
8+
void gdt_install_jump();
59

610
#endif /* _MEM_SEGMENT_H */

src/include/tests/define.h

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

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

77
#ifdef TEST_TRUE
88
// メモリマップとメモリのテスト
@@ -15,6 +15,8 @@
1515
#define ALLOC_IRQ_TEST
1616
// GDT(セグメント)再構築テスト
1717
#define GDT_TEST
18+
// ページングのテスト
19+
#define PAGING_TEST
1820

1921
/* -------- 宣言 -------- */
2022
#ifdef MEM_TEST
@@ -37,6 +39,10 @@ void alloc_irq_test();
3739
void gdt_test();
3840
#endif /* GDT_TEST */
3941

42+
#ifdef PAGING_TEST
43+
void paging_test();
44+
#endif /* PAGING_TEST */
45+
4046
#endif /* TEST_TRUE */
4147

4248
#endif /* _TESTS_CONFIG_H */

src/kernel/interrupt/idt.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct idt_ptr {
5555
} __attribute__((packed));
5656

5757
extern void isr_stub_table(void); /* assembly stubs */
58+
extern void isr14(void);
5859

5960
#define IDT_ENTRIES 256
6061
static struct idt_entry idt[IDT_ENTRIES];
@@ -81,6 +82,18 @@ void irq_handler_c(uint32_t vec) {
8182
}
8283
}
8384

85+
extern void page_fault_handler(uint32_t vec);
86+
87+
void irq_exception_c(uint32_t vec) {
88+
if (vec == 14) {
89+
page_fault_handler(vec);
90+
} else {
91+
/* other exceptions: just spin */
92+
printk("exception vec=%u\n", (unsigned)vec);
93+
while (1) {}
94+
}
95+
}
96+
8497
/**
8598
* @fn idt_init
8699
* @brief IDTを初期化する
@@ -106,6 +119,7 @@ void idt_init(void) {
106119
extern void isr46(void);
107120
extern void isr47(void);
108121

122+
idt_set_gate(14, (uint32_t)isr14); /* page fault */
109123
idt_set_gate(32, (uint32_t)isr32);
110124
idt_set_gate(33, (uint32_t)isr33);
111125
idt_set_gate(34, (uint32_t)isr34);

src/kernel/interrupt/irq_stubs.asm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@ global isr_stub_table
44
isr_stub_table:
55

66
extern irq_handler_c
7+
extern irq_exception_c
78

89
global isr32
910
isr32:
11+
global isr14
12+
isr14:
13+
pusha
14+
push dword 14
15+
call irq_exception_c
16+
add esp, 4
17+
popa
18+
iretd
19+
1020
pusha
1121
push dword 32
1222
call irq_handler_c

src/kernel/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ void kloop();
1919
*/
2020
void kmain() {
2121
console_init();
22-
gdt_install();
22+
gdt_build();
23+
gdt_install_lgdt();
2324

2425
printk("Welcome to Litecore kernel!\n");
2526
printk(" Version: %s\n", VERSION);

src/kernel/mem/gdt_install.asm

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
BITS 32
2+
SECTION .text
3+
global gdt_install
4+
global gdt_install_lgdt
5+
global gdt_install_jump
6+
extern gp
7+
8+
; lgdt only
9+
gdt_install_lgdt:
10+
mov eax, gp
11+
lgdt [eax]
12+
ret
13+
14+
; jump + reload data segments
15+
gdt_install_jump:
16+
; far return via call/pop to get offset into eax, then push selector and offset
17+
call get_eip
18+
get_eip:
19+
pop eax ; eax = offset to next instruction
20+
push word 0x08 ; push selector (16-bit)
21+
push eax ; push offset (32-bit)
22+
retf
23+
jump_continue:
24+
mov ax, 0x10
25+
mov ds, ax
26+
mov es, ax
27+
mov fs, ax
28+
mov gs, ax
29+
mov ss, ax
30+
ret
31+
32+
; default wrapper: perform lgdt and then jump
33+
gdt_install:
34+
call gdt_install_lgdt
35+
call gdt_install_jump
36+
ret

src/kernel/mem/paging.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <config.h>
2+
#include <stdint.h>
3+
#include <mem/paging.h>
4+
#include <console.h>
5+
#include <interrupt/irq.h>
6+
7+
static uint32_t page_directory[1024] __attribute__((aligned(4096)));
8+
static uint32_t first_table[1024] __attribute__((aligned(4096)));
9+
10+
/**
11+
* @fn paging_init_identity
12+
* @brief 指定されたMB数分のメモリを同一マッピングで初期化する
13+
* @param map_mb マッピングするメモリ容量(MB単位)
14+
*/
15+
void paging_init_identity(uint32_t map_mb) {
16+
uint32_t pages = ((map_mb * 1024u * 1024u) + 0xFFF) / 0x1000;
17+
18+
// 最初のテーブル: 最初の4MBを同一マッピング(1024エントリ)
19+
for (uint32_t i = 0; i < 1024; ++i) {
20+
first_table[i] = (i * 0x1000) | 3u; // present + rw
21+
}
22+
23+
// ディレクトリエントリ0はfirst_tableを指す
24+
page_directory[0] = ((uint32_t)first_table) | 3u;
25+
26+
// 残りのPDEをnot presentにする
27+
for (uint32_t i = 1; i < 1024; ++i) page_directory[i] = 0x00000000;
28+
29+
printk("paging: identity map initialized for %u MB (pages=%u)\n", (unsigned)map_mb, (unsigned)pages);
30+
}
31+
32+
/**
33+
* @fn paging_enable
34+
* @brief ページング機能を有効化する
35+
*/
36+
void paging_enable(void) {
37+
// CR3をロード
38+
asm volatile("mov %%eax, %%cr3" :: "a"((uint32_t)page_directory));
39+
// CR0のPGビットを有効化
40+
uint32_t cr0;
41+
asm volatile("mov %%cr0, %%eax" : "=a" (cr0));
42+
cr0 |= 0x80000000u; // PGビットをセット
43+
asm volatile("mov %%eax, %%cr0" :: "a" (cr0));
44+
}
45+
46+
/**
47+
* @fn page_fault_handler
48+
* @brief ページフォルト発生時のハンドラ
49+
* @param vec 割り込みベクタ番号
50+
*/
51+
void page_fault_handler(uint32_t vec) {
52+
(void)vec;
53+
uint32_t fault_addr;
54+
asm volatile ("mov %%cr2, %0" : "=r" (fault_addr));
55+
printk("PAGE FAULT at 0x%x\n", (unsigned)fault_addr);
56+
while (1) {}
57+
}

0 commit comments

Comments
 (0)