[feat] 100Hz task switch
This commit is contained in:
+50
-10
@@ -8,11 +8,14 @@
|
||||
#include <memory/heap.h>
|
||||
#include <scheduler.h>
|
||||
#include <fs.h>
|
||||
#include <gdt.h>
|
||||
#include <idt.h>
|
||||
#include <pic.h>
|
||||
#include <pit.h>
|
||||
|
||||
extern EFI_SYSTEM_TABLE *ST;
|
||||
|
||||
inline void init_gop() {
|
||||
// 初始化 GOP
|
||||
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP;
|
||||
uefi_call_wrapper(ST->BootServices->SetWatchdogTimer, 4, 0, 0, 0, NULL);
|
||||
@@ -21,7 +24,6 @@ inline void init_gop() {
|
||||
}
|
||||
|
||||
inline void init_serial() {
|
||||
// 初始化串行驱动
|
||||
EFI_SERIAL_IO_PROTOCOL *SerialIo = NULL;
|
||||
EFI_GUID gEfiSerialIoProtocolGuid = EFI_SERIAL_IO_PROTOCOL_GUID;
|
||||
EFI_HANDLE *SerialHandles = NULL;
|
||||
@@ -45,6 +47,26 @@ inline void init_serial() {
|
||||
}
|
||||
}
|
||||
|
||||
// External: PIT IRQ handler defined in pit.cpp
|
||||
extern "C" void pit_irq_handler(void);
|
||||
|
||||
// PIC IRQ handler — dispatches IRQ 0 (timer)
|
||||
static void irq_handler(trap_frame* frame) {
|
||||
UINT8 vector = (UINT8)frame->vector;
|
||||
UINT8 irq = vector - PIC_IRQ_BASE;
|
||||
|
||||
switch (irq) {
|
||||
case 0: // PIT timer
|
||||
pit_irq_handler();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Send EOI to PIC
|
||||
pic_send_eoi(irq);
|
||||
}
|
||||
|
||||
extern "C" void kernel_main() {
|
||||
init_gop();
|
||||
init_serial();
|
||||
@@ -53,7 +75,7 @@ extern "C" void kernel_main() {
|
||||
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, (CHAR16*)L"Kernel is running!\n");
|
||||
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
serial_write("\n\n"); // 防止和前面串了serial.log看不清
|
||||
serial_write("\n\n");
|
||||
|
||||
// init memory managers
|
||||
serial_write("Sylva: init PMM...\n");
|
||||
@@ -108,27 +130,46 @@ extern "C" void kernel_main() {
|
||||
pf_print("Welcome to Sylva OS!\n");
|
||||
serial_write(" Kernel prepared well.\n");
|
||||
|
||||
// --- Interrupt infrastructure ---
|
||||
serial_write("Sylva: init GDT...\n");
|
||||
gdt_init();
|
||||
|
||||
serial_write("Sylva: init IDT...\n");
|
||||
idt_init();
|
||||
|
||||
serial_write("Sylva: init PIC...\n");
|
||||
pic_init();
|
||||
|
||||
// Register IRQ handler (vector 0x20 = PIC_IRQ_BASE + 0)
|
||||
idt_set_handler(PIC_IRQ_BASE + 0, irq_handler);
|
||||
|
||||
serial_write("Sylva: init PIT...\n");
|
||||
pit_init();
|
||||
pit_set_tick_handler(scheduler_tick);
|
||||
|
||||
// Enable interrupts
|
||||
ASM("sti");
|
||||
serial_write("Sylva: interrupts enabled\n");
|
||||
|
||||
// --- Multitasking demo ---
|
||||
serial_write("Sylva: creating tasks...\n");
|
||||
|
||||
// Task A: prints a message 3 times, yielding between each
|
||||
// Task A: prints messages — preemption handles time slicing
|
||||
task_create("taskA", []() {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
serial_write("[taskA] running iteration ");
|
||||
serial_write_hex(i);
|
||||
serial_write("\n");
|
||||
yield();
|
||||
}
|
||||
serial_write("[taskA] done\n");
|
||||
});
|
||||
|
||||
// Task B: prints a message 5 times
|
||||
// Task B: prints messages
|
||||
task_create("taskB", []() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
serial_write("[taskB] hello from taskB #");
|
||||
serial_write_hex(i);
|
||||
serial_write("\n");
|
||||
yield();
|
||||
}
|
||||
serial_write("[taskB] done\n");
|
||||
});
|
||||
@@ -136,10 +177,9 @@ extern "C" void kernel_main() {
|
||||
// Task C: short task
|
||||
task_create("taskC", []() {
|
||||
serial_write("[taskC] quick task\n");
|
||||
yield();
|
||||
serial_write("[taskC] finished\n");
|
||||
});
|
||||
|
||||
serial_write("Sylva: starting scheduler\n");
|
||||
serial_write("Sylva: starting preemptive scheduler\n");
|
||||
scheduler_run(); // never returns
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user