diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/kernel/main.cc | 101 | ||||
| -rw-r--r-- | src/kernel/mm/vm.cc | 2 | ||||
| -rw-r--r-- | src/kernel/proc/proc.cc | 113 | ||||
| -rw-r--r-- | src/kernel/proc/swtch.S | 34 | ||||
| -rw-r--r-- | src/kernel/timer.cc | 28 | ||||
| -rw-r--r-- | src/kernel/trap/handler.cc | 6 |
6 files changed, 232 insertions, 52 deletions
diff --git a/src/kernel/main.cc b/src/kernel/main.cc index 2fa10a2..5dfba9b 100644 --- a/src/kernel/main.cc +++ b/src/kernel/main.cc @@ -2,20 +2,37 @@ #include "kernel/pmm.h" #include "kernel/mm.h" #include "kernel/trap.h" +#include "kernel/proc.h" +#include "kernel/timer.h" -// void print_hex(uint64_t val) -// { -// char buf[17]; -// buf[16] = 0; -// const char *digits = "0123456789ABCDEF"; -// for (int i = 15; i >= 0; i--) -// { -// buf[i] = digits[val & 0xf]; -// val >>= 4; -// } -// Drivers::uart_puts("0x"); -// Drivers::uart_puts(buf); -// } +void delay() +{ + for(volatile int i = 0; i < 1000000; i++) + { + + } +} + +void task_a() +{ + while(1) + { + Drivers::uart_putc('A'); + delay(); + ProcManager::yield(); + } +} + +void task_b() +{ + while (1) + { + Drivers::uart_putc('B'); + delay(); + ProcManager::yield(); + } + +} extern "C" void kernel_main() { @@ -24,39 +41,10 @@ extern "C" void kernel_main() Drivers::uart_puts("\n[Modern DOS Kernel] Booted in S-Mode.\n"); Drivers::uart_puts("2025 Richard Qin\n"); Drivers::uart_puts("\n"); + Drivers::uart_puts("\n[Boot] Kernel started.\n"); - Drivers::uart_puts("[Kernel] Initializing PMM...\n"); PMM::init(); - Drivers::uart_puts("[Kernel] PMM initialized.\n"); - - Drivers::uart_puts("[Kernel] Testing alloc_page...\n"); - void *p1 = PMM::alloc_page(); - void *p2 = PMM::alloc_page(); - - Drivers::uart_puts("Allocated Page 1: "); - Drivers::print_hex((uint64_t)p1); - Drivers::uart_puts("\n"); - - Drivers::uart_puts("Allocated Page 2: "); - Drivers::print_hex((uint64_t)p2); - Drivers::uart_puts("\n"); - - Drivers::uart_puts("[Kernel] Freeing Page 1...\n"); - PMM::free_page(p1); - - void *p3 = PMM::alloc_page(); - Drivers::uart_puts("Allocated Page 3: "); - Drivers::print_hex((uint64_t)p3); - Drivers::uart_puts("\n"); - - if (p3 == p1) - { - Drivers::uart_puts("[Test Passed] Reuse freed memory successfully.\n"); - } - else - { - Drivers::uart_puts("[Test Failed] Memory leak or logic error.\n"); - } + Drivers::uart_puts("[Boot] PMM initialized.\n"); VM::kvminit(); Drivers::uart_puts("[Boot] Kernel page table created.\n"); @@ -67,15 +55,26 @@ extern "C" void kernel_main() Trap::init(); Drivers::uart_puts("[Boot] Trap Handler Installed.\n"); - Drivers::uart_puts("\n[Test] Triggering Page Fault by reading 0x0...\n"); - volatile int *p = (int *)0x0; - int crash = *p; - (void)crash; + Timer::init(); + Drivers::uart_puts("[Boot] Timer Interrupt Enabled.\n"); + + // Drivers::uart_puts("\n[Test] Triggering Page Fault by reading 0x0...\n"); + // volatile int *p = (int *)0x0; + // int crash = *p; + // (void)crash; + + // Drivers::uart_puts("[Test Failed] Shuold not reach here.\n"); + + // Drivers::uart_puts("\n[Test] Triggering Store Fault on Text Segment...\n"); + // *(int*)0x80000000 = 1234; + + ProcManager::init(); + Drivers::uart_puts("[Boot] Process Manager initialized.\n"); - Drivers::uart_puts("[Test Failed] Shuold not reach here.\n"); + ProcManager::create_kernel_thread(task_a, "Task A"); + ProcManager::create_kernel_thread(task_b, "Task B"); - Drivers::uart_puts("\n[Test] Triggering Store Fault on Text Segment...\n"); - *(int*)0x80000000 = 1234; + ProcManager::scheduler(); while (1) { diff --git a/src/kernel/mm/vm.cc b/src/kernel/mm/vm.cc index 3c14d40..8696fdb 100644 --- a/src/kernel/mm/vm.cc +++ b/src/kernel/mm/vm.cc @@ -78,6 +78,8 @@ namespace VM mappages(kernel_pagetable, 0x10000000, 0x10000, 0x10000000, PTE_R | PTE_W); + mappages(kernel_pagetable, 0x2000000, 0x10000, 0x2000000, PTE_R | PTE_W); + mappages(kernel_pagetable, (uint64)text_start, (uint64)text_end - (uint64)text_start, (uint64)text_start, PTE_R | PTE_X); diff --git a/src/kernel/proc/proc.cc b/src/kernel/proc/proc.cc new file mode 100644 index 0000000..469b7eb --- /dev/null +++ b/src/kernel/proc/proc.cc @@ -0,0 +1,113 @@ +#include "kernel/proc.h" +#include "kernel/pmm.h" +#include "drivers/uart.h" + +#define NPROC 10 + +void str_copy(char *dst, const char *src) +{ + while (*src) + *dst++ = *src++; + *dst = 0; +} + +extern "C" void swtch(struct Context *old_ctx, struct Context *new_ctx); + +struct Proc procs[NPROC]; +struct Context main_context; + +namespace ProcManager +{ + void init() + { + for (int i = 0; i < NPROC; i++) + { + procs[i].state = UNUSED; + } + } + + void create_kernel_thread(void (*func)(), const char *name) + { + struct Proc *p = nullptr; + for(int i = 0; i < NPROC; i++) + { + if(procs[i].state == UNUSED) + { + p = &procs[i]; + p->pid = i + 1; + break; + } + } + + if (!p) + { + Drivers::uart_puts("Error: No free process slots!\n"); + return; + } + + p->kstack = PMM::alloc_page(); + if (!p->kstack) + { + Drivers::uart_puts("Error: Alloc kstack failed!\n"); + return; + } + + p->context.ra = (uint64)func; + + p->context.sp = (uint64)p->kstack + 4096; + + p->state = RUNNABLE; + str_copy(p->name, name); + + Drivers::uart_puts("[Proc] Created thread: "); + Drivers::uart_puts(name); + Drivers::uart_puts("\n"); + } + + void yield() + { + struct Proc *p = nullptr; + for(int i = 0; i < NPROC; i++) + { + if (procs[i].state == RUNNING) + { + p = &procs[i]; + break; + } + } + if(p) + { + p->state = RUNNABLE; + swtch(&p->context, &main_context); + } + } + + void scheduler() + { + struct Proc *p = nullptr; + Drivers::uart_puts("[Proc] Scheduler started.\n"); + + for (;;) + { + // int nothing_to_run = 1; + + intr_off(); + + for (p = procs; p < &procs[NPROC]; p++) + { + if (p->state == RUNNABLE) + { + // nothing_to_run = 0; + + p->state = RUNNING; + + intr_on(); + + swtch(&main_context, &p->context); + + intr_off(); + } + } + } + } +}
\ No newline at end of file diff --git a/src/kernel/proc/swtch.S b/src/kernel/proc/swtch.S new file mode 100644 index 0000000..f59de20 --- /dev/null +++ b/src/kernel/proc/swtch.S @@ -0,0 +1,34 @@ +.global swtch + +swtch: + sd ra, 0(a0) + sd sp, 8(a0) + sd s0, 16(a0) + sd s1, 24(a0) + sd s2, 32(a0) + sd s3, 40(a0) + sd s4, 48(a0) + sd s5, 56(a0) + sd s6, 64(a0) + sd s7, 72(a0) + sd s8, 80(a0) + sd s9, 88(a0) + sd s10, 96(a0) + sd s11, 104(a0) + + ld ra, 0(a1) + ld sp, 8(a1) + ld s0, 16(a1) + ld s1, 24(a1) + ld s2, 32(a1) + ld s3, 40(a1) + ld s4, 48(a1) + ld s5, 56(a1) + ld s6, 64(a1) + ld s7, 72(a1) + ld s8, 80(a1) + ld s9, 88(a1) + ld s10, 96(a1) + ld s11, 104(a1) + + ret diff --git a/src/kernel/timer.cc b/src/kernel/timer.cc new file mode 100644 index 0000000..8cb3b0f --- /dev/null +++ b/src/kernel/timer.cc @@ -0,0 +1,28 @@ +#include "common/types.h" +#include "kernel/timer.h" + +#define CLINT_BASE 0x2000000L +#define CLINT_MTIMECMP(hartid) (CLINT_BASE + 0x4000 + 8 * (hartid)) +#define CLINT_MTIME (CLINT_BASE + 0xBFF8) + +#define INTERVAL 1000000 + +namespace Timer{ + uint64 get_time(){ + return *(volatile uint64*)CLINT_MTIME; + } + + void set_next_trigger(){ + uint64 mtime = get_time(); + + *(volatile uint64 *)CLINT_MTIMECMP(0) = mtime + INTERVAL; + } + + void init(){ + set_next_trigger(); + uint64 sie; + asm volatile("csrr %0, sie" : "=r"(sie)); + sie |= (1L << 5); + asm volatile("csrw sie, %0" : : "r"(sie)); + } +}
\ No newline at end of file diff --git a/src/kernel/trap/handler.cc b/src/kernel/trap/handler.cc index 9cc19d1..ecb6652 100644 --- a/src/kernel/trap/handler.cc +++ b/src/kernel/trap/handler.cc @@ -1,6 +1,9 @@ #include "kernel/trap.h" #include "common/types.h" #include "drivers/uart.h" +#include "kernel/proc.h" +#include "kernel/timer.h" + void panic(const char *s) { @@ -48,7 +51,8 @@ namespace Trap case 5: Drivers::uart_puts("[IRQ] Timer Interrupt\n"); - + Timer::set_next_trigger(); + ProcManager::yield(); break; case 9: |
