[refactor] 整理注释
This commit is contained in:
+2
-1
@@ -8,7 +8,8 @@ extern "C" void kernel_main();
|
||||
extern "C" void _start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
|
||||
(void)ImageHandle;
|
||||
ST = SystemTable;
|
||||
ASM("cli"); // disable interrupts until IDT is ready
|
||||
// 在 IDT 就绪前禁用中断
|
||||
ASM("cli");
|
||||
kernel_main();
|
||||
while (1) ASM ("hlt");
|
||||
}
|
||||
|
||||
+16
-21
@@ -9,36 +9,35 @@
|
||||
#include <pic.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
// --- Layer list (sorted by z, lowest first) ---
|
||||
// 图层列表(按 z 排序,最低在前)
|
||||
|
||||
static layer_t g_layers[LAYER_MAX];
|
||||
static UINT32 g_layer_count = 0;
|
||||
static layer_t* g_layer_list = NULL;
|
||||
|
||||
// Compositor back buffer
|
||||
// 合成器后台缓冲区
|
||||
static EFI_GRAPHICS_OUTPUT_BLT_PIXEL* g_back_buffer = NULL;
|
||||
|
||||
// Focus tracking
|
||||
// 焦点追踪
|
||||
static layer_t* g_focused = NULL;
|
||||
|
||||
// Shift+F10 state (set by IRQ handler, consumed by compositor)
|
||||
// Shift+F10 状态(由 IRQ 处理函数设置,合成器消费)
|
||||
static volatile bool g_shift_held = false;
|
||||
static volatile bool g_switch_pending = false;
|
||||
static volatile layer_t* g_switch_target = NULL;
|
||||
|
||||
// PS/2 scan code set 1
|
||||
// PS/2 扫描码集 1
|
||||
#define PS2_F10 0x44
|
||||
#define PS2_LSHIFT 0x2A
|
||||
#define PS2_RSHIFT 0x36
|
||||
#define PS2_BREAK_BIT 0x80
|
||||
|
||||
// Forward declare
|
||||
// 前向声明
|
||||
static void layer_insert_sorted(layer_t* layer);
|
||||
static void layer_remove(layer_t* layer);
|
||||
static layer_t* find_next_window(layer_t* from);
|
||||
|
||||
// --- PS/2 keyboard IRQ handler ---
|
||||
|
||||
// PS/2 键盘 IRQ 处理
|
||||
static void ps2_irq_handler(trap_frame* frame) {
|
||||
(void)frame;
|
||||
pic_send_eoi(1);
|
||||
@@ -63,8 +62,7 @@ static void ps2_irq_handler(trap_frame* frame) {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Layer management ---
|
||||
|
||||
// 图层管理
|
||||
layer_t* layer_create(const char* name, layer_type_t type, UINT32 w, UINT32 h) {
|
||||
if (g_layer_count >= LAYER_MAX) {
|
||||
serial_write("LAYER: limit reached\n");
|
||||
@@ -162,8 +160,7 @@ void layer_set_visible(layer_t* layer, bool visible) {
|
||||
layer->visible = visible;
|
||||
}
|
||||
|
||||
// --- Sorted insert/remove ---
|
||||
|
||||
// 有序插入/移除
|
||||
static void layer_insert_sorted(layer_t* layer) {
|
||||
layer->next = NULL;
|
||||
|
||||
@@ -216,8 +213,7 @@ static layer_t* find_next_window(layer_t* from) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// --- Initialization ---
|
||||
|
||||
// 初始化
|
||||
void layer_init(void) {
|
||||
UINT32 hr = g_gfx.hr;
|
||||
UINT32 vr = g_gfx.vr;
|
||||
@@ -235,7 +231,7 @@ void layer_init(void) {
|
||||
p++;
|
||||
}
|
||||
|
||||
// Register keyboard IRQ and unmask
|
||||
// 注册键盘 IRQ 并取消屏蔽
|
||||
idt_set_handler(PIC_IRQ_BASE + 1, ps2_irq_handler);
|
||||
pic_unmask_irq(1);
|
||||
|
||||
@@ -244,8 +240,7 @@ void layer_init(void) {
|
||||
serial_write(" bytes)\n");
|
||||
}
|
||||
|
||||
// --- Compositor task ---
|
||||
|
||||
// 合成器任务
|
||||
void layer_compositor_task(void) {
|
||||
serial_write("LAYER: compositor task running\n");
|
||||
|
||||
@@ -253,7 +248,7 @@ void layer_compositor_task(void) {
|
||||
UINT32 vr = g_gfx.vr;
|
||||
|
||||
while (1) {
|
||||
// Process deferred Shift+F10 switch (safe: not inside IRQ)
|
||||
// 处理延迟的 Shift+F10 窗口切换
|
||||
if (g_switch_pending) {
|
||||
g_switch_pending = false;
|
||||
layer_t* target = (layer_t*)g_switch_target;
|
||||
@@ -266,13 +261,13 @@ void layer_compositor_task(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear back buffer
|
||||
// 清除后台缓冲区
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL black = {0, 0, 0, 0};
|
||||
draw_set_target(g_back_buffer, hr, vr);
|
||||
draw_rect(0, 0, hr, vr, black);
|
||||
draw_set_default_target();
|
||||
|
||||
// Composite layers from lowest z to highest
|
||||
// 按 z 从低到高合成图层
|
||||
layer_t* cur = g_layer_list;
|
||||
while (cur) {
|
||||
if (cur->visible && cur->buffer) {
|
||||
@@ -302,7 +297,7 @@ void layer_compositor_task(void) {
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// Blit to screen
|
||||
// Blit 到屏幕
|
||||
uefi_call_wrapper(g_gfx.GOP->Blt, 10,
|
||||
g_gfx.GOP,
|
||||
g_back_buffer,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <pic.h>
|
||||
#include <serial.h>
|
||||
|
||||
// Defined in isr.S — 256 ISR stubs
|
||||
// isr.S 中定义的 256 个 ISR 桩函数
|
||||
extern "C" void* isr_stub_table[256];
|
||||
|
||||
static idt_entry g_idt[256];
|
||||
@@ -15,7 +15,7 @@ void idt_set_handler(UINT8 vector, isr_handler_t handler) {
|
||||
g_handlers[vector] = handler;
|
||||
}
|
||||
|
||||
// Called from isr.S common handler
|
||||
// 由 isr.S 通用处理函数调用
|
||||
extern "C" void isr_dispatch(trap_frame* frame) {
|
||||
UINT8 vector = (UINT8)frame->vector;
|
||||
|
||||
@@ -31,14 +31,14 @@ extern "C" void isr_dispatch(trap_frame* frame) {
|
||||
}
|
||||
}
|
||||
|
||||
// IDT helpers (defined in idt_helpers.S)
|
||||
// IDT 辅助函数(定义在 idt_helpers.S)
|
||||
extern "C" void idt_load(UINT64 base, UINT16 limit);
|
||||
|
||||
static void idt_set_entry(UINT8 vector, UINT64 handler_addr) {
|
||||
g_idt[vector].offset_low = handler_addr & 0xFFFF;
|
||||
g_idt[vector].selector = 0x08; // kernel code segment
|
||||
g_idt[vector].selector = 0x08; // 内核代码段
|
||||
g_idt[vector].ist = 0;
|
||||
g_idt[vector].type_attr = 0x8E; // present, DPL=0, 64-bit interrupt gate
|
||||
g_idt[vector].type_attr = 0x8E; // 存在,DPL=0,64 位中断门
|
||||
g_idt[vector].offset_mid = (handler_addr >> 16) & 0xFFFF;
|
||||
g_idt[vector].offset_high = (handler_addr >> 32) & 0xFFFFFFFF;
|
||||
g_idt[vector].reserved = 0;
|
||||
@@ -47,18 +47,18 @@ static void idt_set_entry(UINT8 vector, UINT64 handler_addr) {
|
||||
void idt_init(void) {
|
||||
serial_write("IDT: initializing 256 entries\n");
|
||||
|
||||
// Clear IDT
|
||||
// 清空 IDT
|
||||
for (SSINT32 i = 0; i < 256; i++) {
|
||||
g_idt[i] = {0};
|
||||
g_handlers[i] = NULL;
|
||||
}
|
||||
|
||||
// Install all 256 ISR stubs
|
||||
// 安装所有 256 个 ISR 桩函数
|
||||
for (SSINT32 i = 0; i < 256; i++) {
|
||||
idt_set_entry(i, (UINT64)isr_stub_table[i]);
|
||||
}
|
||||
|
||||
// Load IDT
|
||||
// 加载 IDT
|
||||
g_idt_ptr.limit = sizeof(g_idt) - 1;
|
||||
g_idt_ptr.base = (UINT64)&g_idt[0];
|
||||
idt_load(g_idt_ptr.base, g_idt_ptr.limit);
|
||||
|
||||
+11
-11
@@ -13,37 +13,37 @@ static inline UINT8 inb(UINT16 port) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 慢速 PIC 的小延迟
|
||||
static void pic_wait(void) {
|
||||
// Small delay for slow PICs
|
||||
ASM("jmp 1f\n\t1: jmp 1f\n\t1:");
|
||||
}
|
||||
|
||||
void pic_init(void) {
|
||||
serial_write("PIC: remapping 8259 PIC\n");
|
||||
|
||||
// Save masks
|
||||
// 保存掩码
|
||||
UINT8 mask1 = inb(PIC1_DATA);
|
||||
UINT8 mask2 = inb(PIC2_DATA);
|
||||
|
||||
// ICW1: begin initialization, ICW4 needed
|
||||
// ICW1:开始初始化,需要 ICW4
|
||||
outb(PIC1_CMD, 0x11); pic_wait();
|
||||
outb(PIC2_CMD, 0x11); pic_wait();
|
||||
|
||||
// ICW2: vector offset
|
||||
outb(PIC1_DATA, PIC_IRQ_BASE); // IRQ 0-7 → vector 0x20-0x27
|
||||
// ICW2:向量偏移
|
||||
outb(PIC1_DATA, PIC_IRQ_BASE); // IRQ 0-7 → 向量 0x20-0x27
|
||||
pic_wait();
|
||||
outb(PIC2_DATA, PIC_IRQ_BASE + 8); // IRQ 8-15 → vector 0x28-0x2F
|
||||
outb(PIC2_DATA, PIC_IRQ_BASE + 8); // IRQ 8-15 → 向量 0x28-0x2F
|
||||
pic_wait();
|
||||
|
||||
// ICW3: cascading
|
||||
outb(PIC1_DATA, 0x04); pic_wait(); // slave on IRQ 2
|
||||
outb(PIC2_DATA, 0x02); pic_wait(); // cascade identity
|
||||
// ICW3:级联
|
||||
outb(PIC1_DATA, 0x04); pic_wait(); // 从片在 IRQ 2
|
||||
outb(PIC2_DATA, 0x02); pic_wait(); // 级联标识
|
||||
|
||||
// ICW4: 8086 mode
|
||||
// ICW4:8086 模式
|
||||
outb(PIC1_DATA, 0x01); pic_wait();
|
||||
outb(PIC2_DATA, 0x01); pic_wait();
|
||||
|
||||
// Restore masks
|
||||
// 恢复掩码
|
||||
outb(PIC1_DATA, mask1);
|
||||
outb(PIC2_DATA, mask2);
|
||||
|
||||
|
||||
@@ -25,14 +25,14 @@ void pit_init(void) {
|
||||
|
||||
UINT32 divisor = PIT_BASE_FREQ / PIT_TICK_HZ;
|
||||
|
||||
// Command byte: channel 0, lobyte/hibyte, rate generator, binary
|
||||
// 命令字节:通道 0,低/高字节,速率生成器,二进制
|
||||
outb(PIT_COMMAND_PORT, 0x36);
|
||||
|
||||
// Send divisor (low byte first, then high byte)
|
||||
// 发送除数(先低字节后高字节)
|
||||
outb(PIT_CHANNEL0_DATA, (UINT8)(divisor & 0xFF));
|
||||
outb(PIT_CHANNEL0_DATA, (UINT8)((divisor >> 8) & 0xFF));
|
||||
|
||||
// Unmask IRQ 0 (timer)
|
||||
// 取消屏蔽 IRQ 0(定时器)
|
||||
pic_unmask_irq(0);
|
||||
|
||||
serial_write("PIT: divisor = ");
|
||||
|
||||
+17
-18
@@ -50,16 +50,15 @@ inline void init_serial() {
|
||||
}
|
||||
}
|
||||
|
||||
// External: PIT IRQ handler defined in pit.cpp
|
||||
// 外部 PIT 中断处理函数,定义在 pit.cpp
|
||||
extern "C" void pit_irq_handler(void);
|
||||
|
||||
// PIC IRQ handler — dispatches IRQ 0 (timer)
|
||||
// PIC 中断处理 — 分发 IRQ 0(定时器)
|
||||
static void irq_handler(trap_frame* frame) {
|
||||
UINT8 vector = (UINT8)frame->vector;
|
||||
UINT8 irq = vector - PIC_IRQ_BASE;
|
||||
|
||||
// Send EOI BEFORE handling, so PIC can deliver new interrupts
|
||||
// immediately after a context switch inside the handler.
|
||||
// 先发送 EOI 再处理,这样上下文切换后 PIC 可以立即投递新中断
|
||||
pic_send_eoi(irq);
|
||||
|
||||
switch (irq) {
|
||||
@@ -81,7 +80,7 @@ extern "C" void kernel_main() {
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
serial_write("\n\n");
|
||||
|
||||
// init memory managers
|
||||
// 初始化内存管理器
|
||||
serial_write("Sylva: init PMM...\n");
|
||||
EFI_STATUS st = pmm_init();
|
||||
if (EFI_ERROR(st)) {
|
||||
@@ -96,7 +95,7 @@ extern "C" void kernel_main() {
|
||||
serial_write("Sylva: init heap...\n");
|
||||
init_heap();
|
||||
|
||||
// test kmalloc/kfree
|
||||
// 测试 kmalloc/kfree
|
||||
serial_write("Sylva: kmalloc test...\n");
|
||||
void* p1 = kmalloc(64);
|
||||
void* p2 = kmalloc(128);
|
||||
@@ -134,7 +133,7 @@ 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();
|
||||
|
||||
@@ -144,24 +143,24 @@ extern "C" void kernel_main() {
|
||||
serial_write("Sylva: init PIC...\n");
|
||||
pic_init();
|
||||
|
||||
// Register IRQ handler (vector 0x20 = PIC_IRQ_BASE + 0)
|
||||
// 注册 IRQ 处理函数(向量 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");
|
||||
|
||||
// Init compositor (allocates back buffer, registers keyboard handler)
|
||||
// 初始化合成器(分配后台缓冲区,注册键盘处理)
|
||||
layer_init();
|
||||
|
||||
// Create desktop layer (full screen, z=0)
|
||||
// 创建桌面图层(全屏,z=0)
|
||||
layer_t* desktop = layer_create("desktop", LAYER_TYPE_DESKTOP, g_gfx.hr, g_gfx.vr);
|
||||
if (desktop) {
|
||||
layer_set_z(desktop, 0);
|
||||
@@ -172,7 +171,7 @@ extern "C" void kernel_main() {
|
||||
layer_set_pos(desktop, 0, 0);
|
||||
}
|
||||
|
||||
// Create window 1 (centered)
|
||||
// 创建窗口 1(居中)
|
||||
layer_t* win1 = layer_create("window_1", LAYER_TYPE_WINDOW, 300, 200);
|
||||
if (win1) {
|
||||
layer_set_pos(win1, (SSINT32)(g_gfx.hr / 2) - 150, (SSINT32)(g_gfx.vr / 2) - 100);
|
||||
@@ -183,7 +182,7 @@ extern "C" void kernel_main() {
|
||||
draw_set_default_target();
|
||||
}
|
||||
|
||||
// Create window 2 (offset from center)
|
||||
// 创建窗口 2(偏离中心)
|
||||
layer_t* win2 = layer_create("window_2", LAYER_TYPE_WINDOW, 250, 180);
|
||||
if (win2) {
|
||||
layer_set_pos(win2, (SSINT32)(g_gfx.hr / 2) - 50, (SSINT32)(g_gfx.vr / 2) - 40);
|
||||
@@ -194,7 +193,7 @@ extern "C" void kernel_main() {
|
||||
draw_set_default_target();
|
||||
}
|
||||
|
||||
// Compositor task (replaces the old demo tasks)
|
||||
// 合成器任务
|
||||
task_create("compositor", layer_compositor_task);
|
||||
|
||||
serial_write("Sylva: disk read benchmark...\n");
|
||||
@@ -220,7 +219,7 @@ extern "C" void kernel_main() {
|
||||
serial_write_hex(kbps);
|
||||
serial_write(" KiB/s)\n");
|
||||
|
||||
// --- TTF demo ---
|
||||
// TTF 渲染演示
|
||||
serial_write("Sylva: ttf_open...\n");
|
||||
ttf_face_t* face = ttf_open(ttf_buf, ttf_size);
|
||||
if (!face) {
|
||||
@@ -228,7 +227,7 @@ extern "C" void kernel_main() {
|
||||
} else {
|
||||
serial_write("Sylva: ttf_open OK\n");
|
||||
|
||||
// Create an overlay layer for TTF output (sits above the two demo windows)
|
||||
// 创建 TTF 文本覆盖图层
|
||||
const UINT32 TL_W = 500, TL_H = 200;
|
||||
layer_t* text_layer = layer_create("ttf_text", LAYER_TYPE_WINDOW, TL_W, TL_H);
|
||||
if (text_layer) {
|
||||
@@ -238,7 +237,7 @@ extern "C" void kernel_main() {
|
||||
draw_set_target(text_layer->buffer, TL_W, TL_H);
|
||||
draw_rect(0, 0, TL_W - 1, TL_H - 1, clear);
|
||||
|
||||
// Render at 4 sizes + mixed CJK
|
||||
// 渲染多种字号和中日韩字符
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL white = {255, 255, 255, 0};
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL yellow = {255, 240, 80, 0};
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL cyan = {80, 220, 255, 0};
|
||||
|
||||
+14
-14
@@ -42,7 +42,7 @@ static void heap_expand(UINTN min_size) {
|
||||
new_block->size = pages * PAGE_SIZE;
|
||||
new_block->next = NULL;
|
||||
|
||||
// Add to free list (sorted by address for coalescing)
|
||||
// 添加到空闲链表(按地址排序以便合并)
|
||||
struct heap_block** prev = &g_heap_free_list;
|
||||
while (*prev && (UINT8*)*prev < (UINT8*)new_block) {
|
||||
prev = &(*prev)->next;
|
||||
@@ -50,7 +50,7 @@ static void heap_expand(UINTN min_size) {
|
||||
new_block->next = *prev;
|
||||
*prev = new_block;
|
||||
|
||||
// Try to merge with the previous free block if adjacent
|
||||
// 尝试与前一个空闲块合并(如果相邻)
|
||||
if (prev != &g_heap_free_list) {
|
||||
struct heap_block* prev_block = g_heap_free_list;
|
||||
while (prev_block->next != new_block) {
|
||||
@@ -104,21 +104,21 @@ void* kmalloc(UINTN size) {
|
||||
while (*prev) {
|
||||
UINTN block_sz = BLOCK_SIZE(*prev);
|
||||
if (block_sz >= alloc_size) {
|
||||
// Found a suitable block
|
||||
// 找到合适的块
|
||||
struct heap_block* block = *prev;
|
||||
|
||||
// Split if remaining space is useful
|
||||
// 如果剩余空间足够则分割
|
||||
if (block_sz >= alloc_size + MIN_BLOCK_SIZE) {
|
||||
struct heap_block* split = (struct heap_block*)((UINT8*)block + alloc_size);
|
||||
split->size = block_sz - alloc_size;
|
||||
// Insert split into free list
|
||||
// 将分割后的块插入空闲链表
|
||||
split->next = block->next;
|
||||
block->size = alloc_size | 1;
|
||||
*prev = split;
|
||||
} else {
|
||||
// Use the whole block
|
||||
// 使用整个块
|
||||
*prev = block->next;
|
||||
block->size = block_sz | 1; // mark used
|
||||
block->size = block_sz | 1; // 标记为已使用
|
||||
}
|
||||
|
||||
if (size > 1024) {
|
||||
@@ -134,11 +134,11 @@ void* kmalloc(UINTN size) {
|
||||
prev = &(*prev)->next;
|
||||
}
|
||||
|
||||
// Out of memory in current heap — expand
|
||||
// 当前堆空间不足,扩展堆
|
||||
UINTN expand_size = alloc_size > PAGE_SIZE ? alloc_size : PAGE_SIZE;
|
||||
heap_expand(expand_size);
|
||||
|
||||
// Retry after expansion
|
||||
// 扩展后重试
|
||||
return kmalloc(size);
|
||||
}
|
||||
|
||||
@@ -151,14 +151,14 @@ void kfree(void* ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark as free
|
||||
// 标记为空闲
|
||||
block->size &= ~(UINTN)1;
|
||||
|
||||
// Merge with next block if it's free
|
||||
// 与下一个空闲块合并
|
||||
struct heap_block* next = next_block(block);
|
||||
if ((UINT8*)next < (UINT8*)g_heap_end) {
|
||||
if (IS_FREE(next)) {
|
||||
// Remove next from free list and merge
|
||||
// 从空闲链表中移除 next 并合并
|
||||
block->size += next->size;
|
||||
struct heap_block** prev = &g_heap_free_list;
|
||||
while (*prev && *prev != next) {
|
||||
@@ -168,7 +168,7 @@ void kfree(void* ptr) {
|
||||
}
|
||||
}
|
||||
|
||||
// Insert block into free list
|
||||
// 将块插入空闲链表
|
||||
struct heap_block** prev = &g_heap_free_list;
|
||||
while (*prev && (UINT8*)*prev < (UINT8*)block) {
|
||||
prev = &(*prev)->next;
|
||||
@@ -201,7 +201,7 @@ void* krealloc(void* ptr, UINTN new_size) {
|
||||
UINTN old_size = BLOCK_SIZE(block) - HEADER_SIZE;
|
||||
|
||||
if (old_size >= new_size) {
|
||||
// Can we split the shrinkage?
|
||||
// 能否分割缩小的部分?
|
||||
UINTN shrink = old_size - new_size;
|
||||
if (shrink >= MIN_BLOCK_SIZE) {
|
||||
block->size = (new_size + HEADER_SIZE) | 1;
|
||||
|
||||
+11
-11
@@ -19,7 +19,7 @@ static inline BOOLEAN bitmap_test(UINTN idx) {
|
||||
return (g_pmm.bitmap[idx / 8] >> (idx % 8)) & 1;
|
||||
}
|
||||
|
||||
// Clean stale entries from free list head
|
||||
// 清理空闲链表头部的过期条目
|
||||
static void clean_free_list() {
|
||||
while (g_pmm.free_list_head != NULL &&
|
||||
bitmap_test((UINTN)g_pmm.free_list_head / PAGE_SIZE)) {
|
||||
@@ -58,7 +58,7 @@ EFI_STATUS pmm_init() {
|
||||
|
||||
UINTN entry_count = map_size / desc_size;
|
||||
|
||||
// First pass: count total pages and find max physical address
|
||||
// 第一遍:统计总页数并找到最大物理地址
|
||||
UINT64 max_addr = 0;
|
||||
UINT64 total_free = 0;
|
||||
for (UINTN i = 0; i < entry_count; i++) {
|
||||
@@ -73,16 +73,16 @@ EFI_STATUS pmm_init() {
|
||||
g_pmm.base_addr = 0;
|
||||
g_pmm.max_addr = max_addr;
|
||||
|
||||
// How many pages does the bitmap cover?
|
||||
// 位图覆盖的页数
|
||||
UINTN total_pages = (UINTN)(max_addr / PAGE_SIZE);
|
||||
g_pmm.total_pages = total_pages;
|
||||
|
||||
// Bitmap size in bytes, rounded up to page boundary
|
||||
// 位图大小(字节),向上取整到页边界
|
||||
g_pmm.bitmap_size = ((total_pages + 7) / 8);
|
||||
UINTN bitmap_pages = (g_pmm.bitmap_size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
g_pmm.bitmap_size = bitmap_pages * PAGE_SIZE; // round to full pages
|
||||
|
||||
// Place bitmap at the end of the highest free conventional memory region
|
||||
// 将位图放在最高空闲常规内存区域的末尾
|
||||
UINT64 bitmap_addr = 0;
|
||||
for (UINTN i = 0; i < entry_count; i++) {
|
||||
EFI_MEMORY_DESCRIPTOR* desc = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)mem_map + i * desc_size);
|
||||
@@ -105,12 +105,12 @@ EFI_STATUS pmm_init() {
|
||||
|
||||
g_pmm.bitmap = (UINT8*)(UINTN)bitmap_addr;
|
||||
|
||||
// Init bitmap: mark ALL pages as used (0xFF)
|
||||
// 初始化位图:将所有页标记为已使用
|
||||
for (UINTN i = 0; i < g_pmm.bitmap_size; i++) {
|
||||
g_pmm.bitmap[i] = 0xFF;
|
||||
}
|
||||
|
||||
// Mark free pages (EfiConventionalMemory) as free in bitmap
|
||||
// 将空闲页(EfiConventionalMemory)在位图中标记为空闲
|
||||
g_pmm.free_pages = 0;
|
||||
UINT64 bm_start_page = bitmap_addr / PAGE_SIZE;
|
||||
UINT64 bm_end_page = (bitmap_addr + g_pmm.bitmap_size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
@@ -123,19 +123,19 @@ EFI_STATUS pmm_init() {
|
||||
UINT64 end_page = start_page + desc->NumberOfPages;
|
||||
|
||||
for (UINT64 p = start_page; p < end_page; p++) {
|
||||
// Skip bitmap pages
|
||||
// 跳过位图占用的页
|
||||
if (p >= bm_start_page && p < bm_end_page) continue;
|
||||
bitmap_clear((UINTN)p);
|
||||
g_pmm.free_pages++;
|
||||
}
|
||||
}
|
||||
|
||||
// Mark bitmap pages as used
|
||||
// 将位图占用的页标记为已使用
|
||||
for (UINT64 p = bm_start_page; p < bm_end_page; p++) {
|
||||
bitmap_set((UINTN)p);
|
||||
}
|
||||
|
||||
// Reserve low memory (first 4 MB) — UEFI firmware may use it during BS calls
|
||||
// 保留低内存(前 4MB)— 固件可能在 Boot Services 调用期间使用
|
||||
UINT64 low_reserve_pages = 0x400;
|
||||
for (UINT64 p = 0; p < low_reserve_pages && p < g_pmm.total_pages; p++) {
|
||||
if (!bitmap_test((UINTN)p)) {
|
||||
@@ -144,7 +144,7 @@ EFI_STATUS pmm_init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Build free list by linking free pages
|
||||
// 通过链接空闲页构建空闲链表
|
||||
g_pmm.free_list_head = NULL;
|
||||
void* prev = NULL;
|
||||
for (UINTN i = 0; i < entry_count; i++) {
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
#include <common.h>
|
||||
#include <serial.h>
|
||||
|
||||
// Assembly: context_switch(UINT64* old_rsp, UINT64 new_rsp)
|
||||
// 汇编函数:context_switch(UINT64* old_rsp, UINT64 new_rsp)
|
||||
extern "C" void context_switch(UINT64* old_rsp, UINT64 new_rsp);
|
||||
|
||||
static task_t g_tasks[TASK_MAX];
|
||||
static UINT32 g_task_count = 0;
|
||||
static task_t* g_current = NULL;
|
||||
static task_t* g_task_list = NULL; // circular linked list head
|
||||
static task_t* g_task_list = NULL; // 循环链表头
|
||||
|
||||
// Trampoline: first thing a new task runs after context_switch.
|
||||
// 跳板函数:新任务在 context_switch 后首先执行的函数
|
||||
static void (*g_task_entries[TASK_MAX])(void);
|
||||
|
||||
extern "C" void task_entry_trampoline() {
|
||||
@@ -37,7 +37,7 @@ task_t* task_create(const char* name, void (*entry)(void)) {
|
||||
|
||||
g_task_entries[id] = entry;
|
||||
|
||||
// Allocate kernel stack
|
||||
// 分配内核栈
|
||||
UINTN stack_pages = TASK_STACK_SIZE / PAGE_SIZE;
|
||||
void* stack = pmm_alloc_pages(stack_pages);
|
||||
if (!stack) {
|
||||
@@ -52,24 +52,21 @@ task_t* task_create(const char* name, void (*entry)(void)) {
|
||||
task->stack_base = stack;
|
||||
task->time_slice = TIME_SLICE_DEFAULT;
|
||||
|
||||
// Copy name
|
||||
// 复制任务名称
|
||||
str_copy(task->name, name, TASK_NAME_LEN);
|
||||
|
||||
// Set up initial stack for first context_switch into this task.
|
||||
// Stack grows downward. context_switch will pop 6 regs then ret.
|
||||
// 设置首次 context_switch 时的初始栈
|
||||
// 栈向下增长。context_switch 会弹出 6 个寄存器然后 ret。
|
||||
//
|
||||
// Layout (high addr -> low addr):
|
||||
// [stack + TASK_STACK_SIZE] <- top
|
||||
// return addr = task_entry_trampoline (ret goes here)
|
||||
// 布局(高地址 → 低地址):
|
||||
// [stack + TASK_STACK_SIZE] <- 栈顶
|
||||
// 返回地址 = task_entry_trampoline(ret 跳转到这里)
|
||||
// rbx = 0
|
||||
// rbp = 0
|
||||
// r12 = 0
|
||||
// r13 = 0
|
||||
// r14 = 0
|
||||
// r15 = 0 <- RSP points here initially
|
||||
//
|
||||
// When preempted by timer IRQ, the ISR stub saves a full trap_frame
|
||||
// on the task's stack — that layout is only created by hardware+ISR.
|
||||
// r15 = 0 <- RSP 初始指向这里
|
||||
//
|
||||
UINT64* sp = (UINT64*)((UINT8*)stack + TASK_STACK_SIZE);
|
||||
|
||||
@@ -84,7 +81,7 @@ task_t* task_create(const char* name, void (*entry)(void)) {
|
||||
|
||||
task->rsp = (UINT64)sp;
|
||||
|
||||
// Insert into circular linked list
|
||||
// 插入循环链表
|
||||
if (g_task_list == NULL) {
|
||||
task->next = task;
|
||||
g_task_list = task;
|
||||
@@ -103,7 +100,7 @@ task_t* task_create(const char* name, void (*entry)(void)) {
|
||||
return task;
|
||||
}
|
||||
|
||||
// Find next READY task in the circular list, starting from g_current->next
|
||||
// 在循环链表中查找下一个就绪任务
|
||||
static task_t* find_next_ready(void) {
|
||||
if (g_current == NULL || g_task_list == NULL) return NULL;
|
||||
|
||||
@@ -117,7 +114,7 @@ static task_t* find_next_ready(void) {
|
||||
next = next->next;
|
||||
} while (next != start);
|
||||
|
||||
return NULL; // no READY tasks
|
||||
return NULL; // 没有就绪任务
|
||||
}
|
||||
|
||||
void yield(void) {
|
||||
@@ -137,27 +134,27 @@ void yield(void) {
|
||||
context_switch(&cur->rsp, next->rsp);
|
||||
}
|
||||
|
||||
// Timer tick handler — called from PIT IRQ 0
|
||||
// 定时器 tick 处理 — 由 PIT IRQ 0 调用
|
||||
void scheduler_tick(void) {
|
||||
if (g_current == NULL) return;
|
||||
|
||||
// Decrement time slice
|
||||
// 递减时间片
|
||||
if (g_current->time_slice > 0) {
|
||||
g_current->time_slice--;
|
||||
}
|
||||
|
||||
// If time slice expired, preempt
|
||||
// 时间片用完则抢占
|
||||
if (g_current->time_slice == 0) {
|
||||
task_t* cur = g_current;
|
||||
task_t* next = find_next_ready();
|
||||
|
||||
if (next == NULL || next == cur) {
|
||||
// No other task ready, or only this task — reload time slice
|
||||
// 没有其他就绪任务,或仅此一个 — 重置时间片
|
||||
cur->time_slice = TIME_SLICE_DEFAULT;
|
||||
return;
|
||||
}
|
||||
|
||||
// Preempt
|
||||
// 抢占
|
||||
cur->state = TASK_STATE_READY;
|
||||
cur->time_slice = TIME_SLICE_DEFAULT;
|
||||
next->state = TASK_STATE_RUNNING;
|
||||
@@ -174,7 +171,7 @@ void scheduler_run(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find first READY task
|
||||
// 查找第一个就绪任务
|
||||
task_t* start = g_task_list->next;
|
||||
task_t* t = start;
|
||||
do {
|
||||
@@ -197,12 +194,12 @@ void scheduler_run(void) {
|
||||
serial_write(t->name);
|
||||
serial_write("'\n");
|
||||
|
||||
// First context switch — switch to the task's stack
|
||||
// This will never return (until all tasks terminate)
|
||||
// 首次上下文切换 — 切换到任务栈
|
||||
// 此后不会返回(直到所有任务终止)
|
||||
UINT64 dummy_rsp;
|
||||
context_switch(&dummy_rsp, t->rsp);
|
||||
|
||||
// We only return here when ALL tasks are terminated
|
||||
// 只有所有任务终止后才会返回到这里
|
||||
serial_write("SCHED: all tasks finished\n");
|
||||
while (1) ASM ("hlt");
|
||||
}
|
||||
@@ -216,10 +213,10 @@ void task_exit(void) {
|
||||
|
||||
g_current->state = TASK_STATE_TERMINATED;
|
||||
|
||||
// Yield to next task — we won't come back
|
||||
// 让出 CPU 给下一个任务 — 不会回来
|
||||
yield();
|
||||
|
||||
// Should never reach here
|
||||
// 不应到达此处
|
||||
while (1) ASM ("hlt");
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ void serial_write_hex(UINTN val) {
|
||||
}
|
||||
|
||||
char serial_read_char() {
|
||||
// 后面可能用的上,比如远程调试?
|
||||
if (!g_serial.SerialIo) return 0;
|
||||
char c = 0;
|
||||
UINTN size = 1;
|
||||
|
||||
Reference in New Issue
Block a user