diff --git a/fonts/pixel_font.cpp b/fonts/pixel_font.cpp index 37b7e68..874caf1 100644 --- a/fonts/pixel_font.cpp +++ b/fonts/pixel_font.cpp @@ -8,13 +8,7 @@ void pf_print_char(char c, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT for (SUINT32 y = 0; y < 16; y++) { SUINT8 data = hankaku_pixels[c][y]; for (SSINT32 x = 7; x >= 0; x--) { - // 解码Hankaku字体 - /* - 既然都在这了,就讲一下Hankaku字体是如何解码的 - 比如一个 - {0x00, 0x82, 0x82, 0x44, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00} - 每一个Hex代表一行,比如0x82就是一行,转换成Bin得到10000010,1代表有像素,0代表没像素 - */ + // Hankaku 字体解码:每个字节代表一行,低位在右 SUINT32 current = data & 1; data >>= 1; if (current) @@ -26,6 +20,6 @@ void pf_print_char(char c, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT void pf_print(const char* text, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) { for (SUINT32 i = 0; i < str_len(text); i++) { char c = text[i]; - pf_print_char(c, basex + i * 8, basey, color); // 只要 字数 * 8 + basex 不爆hr就没事 + pf_print_char(c, basex + i * 8, basey, color); } } \ No newline at end of file diff --git a/fonts/ttf/ttf.cpp b/fonts/ttf/ttf.cpp index 191608a..c6b31e4 100644 --- a/fonts/ttf/ttf.cpp +++ b/fonts/ttf/ttf.cpp @@ -4,14 +4,12 @@ #include #include -// Per-glyph scratch — kept static to avoid stack pressure for big Chinese glyphs +// 逐字形临时缓冲区 — 静态分配以避免大中文字形的栈压力 static ttf_outline_t s_outline; static ttf_seg_t s_segs[4096]; static SUINT8 s_coverage[256 * 256]; -// Render one glyph bitmap at screen (px, py) where py is the glyph TOP -// (already converted from baseline). (px, py) may be negative — caller -// must have clipped into the visible region. +// 在屏幕 (px, py) 处渲染单个字形位图,py 为字形顶部(已从基线转换) static void blit_glyph(SSINT32 px, SSINT32 py, SUINT32 w, SUINT32 h, const SUINT8* coverage, SUINT32 N, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) @@ -31,7 +29,7 @@ static void blit_glyph(SSINT32 px, SSINT32 py, SUINT32 w, SUINT32 h, } } -// Render a single codepoint at (x, y) = baseline. Returns advance (26.6). +// 在基线 (x, y) 处渲染单个码点,返回进宽(26.6 定点数) static f26_6 render_codepoint(ttf_face_t* face, SSINT32 cp, SSINT32 x, SSINT32 y, SUINT32 pixel_size, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) diff --git a/fonts/ttf/ttf_parse.cpp b/fonts/ttf/ttf_parse.cpp index e4849a1..24273c3 100644 --- a/fonts/ttf/ttf_parse.cpp +++ b/fonts/ttf/ttf_parse.cpp @@ -3,7 +3,7 @@ #include #include -// ---- Big-endian readers (TTF is big-endian) ---- +// 大端读取器(TTF 为大端格式) static inline SUINT16 rd16(const SUINT8* p) { return ((SUINT16)p[0] << 8) | p[1]; } @@ -27,7 +27,7 @@ static const SUINT8* find_table(ttf_face_t* face, const char tag[4]) { return NULL; } -// ---- UTF-8 ---- +// UTF-8 解码 SSINT32 ttf_utf8_decode(const char** p) { const SUINT8* s = (const SUINT8*)*p; SUINT8 b0 = s[0]; @@ -39,7 +39,7 @@ SSINT32 ttf_utf8_decode(const char** p) { return -1; } -// ---- cmap ---- +// cmap 子表查找 static const SUINT8* find_cmap_subtable(ttf_face_t* face) { const SUINT8* cmap = face->cmap; SUINT16 num = rd16(cmap + 2); @@ -85,7 +85,7 @@ static SUINT16 cmap4_lookup(const SUINT8* sub, SSINT32 cp) { } static SUINT16 cmap12_lookup(const SUINT8* sub, SSINT32 cp) { - // Format 12 header: format(2) reserved(2) length(4) language(4) nGroups(4) + // Format 12 头:format(2) reserved(2) length(4) language(4) nGroups(4) SUINT32 nGroups = rd32(sub + 12); const SUINT8* g = sub + 16; for (SUINT32 i = 0; i < nGroups; i++) { @@ -108,14 +108,14 @@ SUINT16 ttf_cmap_lookup(ttf_face_t* face, SSINT32 cp) { return 0; } -// ---- Glyf decode ---- +// glyf 解码 bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, SUINT32 pixel_size_px, ttf_outline_t* out) { mem_set(out, 0, sizeof(*out)); if (glyph_id >= face->num_glyphs) return false; - // Loca + // Loca 索引 SUINT32 off0, off1; if (face->index_to_loc_format == 0) { off0 = ((SUINT32)rd16(face->loca + glyph_id * 2)) * 2; @@ -126,7 +126,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, } if (off0 >= face->glyf_len) return false; - // Advance width (always readable from hmtx regardless of glyf presence) + // 进宽(始终从 hmtx 读取,无论 glyf 是否存在) { SUINT16 aw; if (glyph_id < face->num_long_hor_metrics) { @@ -138,21 +138,21 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, } if (off0 == off1) { - // Empty glyph (e.g. space) + // 空白字形(如空格) return true; } const SUINT8* g = face->glyf + off0; SSINT16 numContours = rd16s(g + 0); if (numContours < 0) { - // Composite glyph — parse component records and merge outlines + // 复合字形 — 解析组件记录并合并轮廓 const SUINT8* cp = g + 10; SSINT32 all_xmin = 0x7FFFFFFF, all_ymin = 0x7FFFFFFF; SSINT32 all_xmax = -0x7FFFFFFF, all_ymax = -0x7FFFFFFF; - // Composite glyph flags (OpenType spec): - // 0x0001 = ARG_1_AND_2_ARE_WORDS (16-bit args; else 8-bit) - // 0x0002 = ARGS_ARE_XY_VALUES (offsets; else point indices) + // 复合字形标志(OpenType 规范): + // 0x0001 = ARG_1_AND_2_ARE_WORDS(16 位参数;否则 8 位) + // 0x0002 = ARGS_ARE_XY_VALUES(偏移量;否则点索引) // 0x0008 = WE_HAVE_A_SCALE // 0x0040 = WE_HAVE_A_2x2 // 0x0080 = WE_HAVE_AN_X_AND_Y_SCALE @@ -162,41 +162,41 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, SUINT16 comp_flags = rd16(cp); cp += 2; SUINT16 comp_glyph = rd16(cp); cp += 2; - // Read arguments (size depends on ARG_1_AND_2_ARE_WORDS) + // 读取参数(大小取决于 ARG_1_AND_2_ARE_WORDS) SSINT32 arg1, arg2; if (comp_flags & 0x0001) { - // 16-bit signed words + // 16 位有符号字 arg1 = rd16s(cp); cp += 2; arg2 = rd16s(cp); cp += 2; } else { - // 8-bit signed bytes + // 8 位有符号字节 arg1 = (SSINT8)cp[0]; arg2 = (SSINT8)cp[1]; cp += 2; } - // Read transform scale if present + // 如果存在则读取缩放比例 f26_6 scale = F26_ONE; if (comp_flags & 0x0008) { - // WE_HAVE_A_SCALE: 16.16 fixed-point + // WE_HAVE_A_SCALE:16.16 定点数 SSINT16 s16 = rd16s(cp); cp += 2; scale = (f26_6)s16; // already in f26.6 from 16.16 } - // Read x/y scale if present + // 如果存在则读取 x/y 缩放 f26_6 scaleX = F26_ONE, scaleY = F26_ONE; if (comp_flags & 0x0080) { - // WE_HAVE_AN_X_AND_Y_SCALE: two 16.16 values + // WE_HAVE_AN_X_AND_Y_SCALE:两个 16.16 值 SSINT16 sx16 = rd16s(cp); cp += 2; SSINT16 sy16 = rd16s(cp); cp += 2; scaleX = (f26_6)sx16; scaleY = (f26_6)sy16; } - // Read 2x2 matrix if present + // 如果存在则读取 2x2 矩阵 f26_6 m00 = F26_ONE, m01 = 0, m10 = 0, m11 = F26_ONE; if (comp_flags & 0x0040) { - // WE_HAVE_A_2x2: four 2.14 values + // WE_HAVE_A_2x2:四个 2.14 值 SSINT16 a = rd16s(cp); cp += 2; SSINT16 b = rd16s(cp); cp += 2; SSINT16 c = rd16s(cp); cp += 2; @@ -207,36 +207,36 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, m11 = (f26_6)(d >> 8); } - // Load component glyph + // 加载组件字形 ttf_outline_t comp; if (!ttf_load_glyph(face, comp_glyph, pixel_size_px, &comp)) return false; - // Determine if args are offsets (XY values) or point indices + // 判断参数是偏移量(XY 值)还是点索引 SSINT32 offset_x = 0, offset_y = 0; if (comp_flags & 0x0002) { - // ARGS_ARE_XY_VALUES: args are pixel offsets (already scaled) - // Scale from font units to pixel space like simple glyphs + // ARGS_ARE_XY_VALUES:参数是像素偏移量(已缩放) + // 从字体单位缩放到像素空间 offset_x = (SSINT32)(((SSINT64)arg1 * (SSINT64)pixel_size_px * 64 / face->units_per_em)); offset_y = (SSINT32)(((SSINT64)arg2 * (SSINT64)pixel_size_px * 64 / face->units_per_em)); } - // Transform and merge component points + // 变换并合并组件点 for (SUINT16 i = 0; i < comp.num_points; i++) { f26_6 fx = comp.x[i]; f26_6 fy = comp.y[i]; f26_6 tx, ty; if (comp_flags & 0x0040) { - // 2x2 matrix transform + // 2x2 矩阵变换 tx = f26_mul(m00, fx) + f26_mul(m01, fy); ty = f26_mul(m10, fx) + f26_mul(m11, fy); } else if (comp_flags & 0x0008) { - // Uniform scale + // 均匀缩放 tx = f26_mul(scale, fx); ty = f26_mul(scale, fy); } else if (comp_flags & 0x0080) { - // X/Y scale + // x/y 独立缩放 tx = f26_mul(scaleX, fx); ty = f26_mul(scaleY, fy); } else { @@ -295,7 +295,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, SUINT16 instrLen = rd16(p); p += 2; p += instrLen; - // Decode flags (with REPEAT) + // 解码标志(含 REPEAT) SUINT8 flags[1024]; SUINT16 pi = 0; while (pi < numPoints) { @@ -308,7 +308,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, } } - // Decode x-coords into x_raw[] + // 解码 x 坐标到 x_raw[] SSINT32 x_raw[1024]; { SSINT32 x = 0; @@ -324,7 +324,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, x_raw[i] = x; } } - // Decode y-coords into y_raw[] + // 解码 y 坐标到 y_raw[] SSINT32 y_raw[1024]; { SSINT32 y = 0; @@ -341,7 +341,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, } } - // Scale to pixel space (f26_6) + // 缩放到像素空间(f26_6) SUINT64 scale_num = (SUINT64)pixel_size_px * 64; for (SUINT16 i = 0; i < numPoints; i++) { out->x[i] = (f26_6)(((SSINT64)x_raw[i] * (SSINT64)scale_num) / face->units_per_em); @@ -365,7 +365,7 @@ bool ttf_load_glyph(ttf_face_t* face, SUINT16 glyph_id, return true; } -// ---- Open / close ---- +// 打开 / 关闭 ttf_face_t* ttf_open(const void* data, UINTN size) { if (!data || size < 12) return NULL; const SUINT8* d = (const SUINT8*)data; @@ -449,7 +449,7 @@ void ttf_close(ttf_face_t* face) { if (face) kfree(face); } -// ---- Metrics (scaled to pixel_size, returned as 26.6 fp) ---- +// 度量值(缩放到 pixel_size,返回 26.6 定点数) SSINT32 ttf_ascender (ttf_face_t* face, SUINT32 px) { return (SSINT32)(((SSINT64)face->os2_ascender * (SSINT64)px * 64) / face->units_per_em); } diff --git a/fonts/ttf/ttf_render.cpp b/fonts/ttf/ttf_render.cpp index fbf7a7c..3aede4d 100644 --- a/fonts/ttf/ttf_render.cpp +++ b/fonts/ttf/ttf_render.cpp @@ -1,13 +1,12 @@ #include "ttf_internal.h" #include -// ---- Outline -> segments ---- +// 轮廓 → 线段转换 // -// TrueType contour walk: for each pair of consecutive points, emit either -// a line or a quadratic bezier. Two consecutive off-curve points trigger -// synthesis of an on-curve midpoint. +// TrueType 轮廓遍历:对每对连续点,发射直线或二次贝塞尔曲线。 +// 两个连续的非曲线点会触发合成一个曲线中点。 // -// All coordinates remain in 26.6 fp throughout. +// 所有坐标全程使用 26.6 定点数。 void ttf_outline_to_segments(const ttf_outline_t* outline, ttf_seg_t* segs, SUINT32* num_segs) { @@ -92,7 +91,7 @@ void ttf_outline_to_segments(const ttf_outline_t* outline, } } -// ---- Integer sqrt (Newton) ---- +// 整数平方根(牛顿法) static SUINT32 isqrt_u64(SUINT64 n) { if (n == 0) return 0; SUINT32 x = (n > 0xFFFFFFFFu) ? 0xFFFFu : (SUINT32)n; @@ -101,19 +100,19 @@ static SUINT32 isqrt_u64(SUINT64 n) { return x; } -// ---- Scanline fill with subpixel supersampling ---- +// 扫描线填充 + 子像素超采样 // -// For each output row, run N sub-scanlines at offsets (k+0.5)/N. For each -// sub-scanline y, collect all x-intersections, sort, fill alternating -// x-pairs. Sum over N subsamples yields per-pixel coverage in [0, N]. +// 对每个输出行,运行 N 条子扫描线,偏移为 (k+0.5)/N。 +// 对每条子扫描线 y,收集所有 x 交点,排序后交替填充 x 对。 +// 对 N 个子采样求和得到每个像素的覆盖率 [0, N]。 void ttf_rasterize(const ttf_seg_t* segs, SUINT32 num_segs, SSINT32 x0, SSINT32 y0, SUINT32 w, SUINT32 h, SUINT8* coverage, SUINT32 N) { - // Clear coverage + // 清空覆盖率缓冲区 for (SUINT32 i = 0; i < w * h; i++) coverage[i] = 0; - // Intersection x-buf (per scanline, max possible = num_segs) + // 交点 x 缓冲区(每扫描线,最大可能数 = num_segs) f26_6 xs[2048]; if (num_segs > 2048) num_segs = 2048; @@ -222,6 +221,6 @@ void ttf_rasterize(const ttf_seg_t* segs, SUINT32 num_segs, } } } - // (Alpha conversion happens at the caller via N.) + // 覆盖率转换在调用端通过 N 完成 (void)x0; (void)y0; } diff --git a/graphics/context.cpp b/graphics/context.cpp index a80c5d4..fc4d2d0 100644 --- a/graphics/context.cpp +++ b/graphics/context.cpp @@ -1,7 +1,4 @@ -// GFX 存在的意义是什么? -// 每一次想要draw pixel,都需要传入GOP的各种参数, -// 加入 GFX 后,GOP 的context就是全局的,可以直接用 -// 而不用显示传递参数到draw的函数里 +// GFX 全局图形上下文,避免每次绘制都传递 GOP 参数 #include diff --git a/include/fonts/hankaku.h b/include/fonts/hankaku.h index d4dd12a..672610b 100644 --- a/include/fonts/hankaku.h +++ b/include/fonts/hankaku.h @@ -1,7 +1,7 @@ #pragma once #include -// Hankaku 字体,不动 +// Hankaku 8x16 点阵字体数据 static SUINT8 hankaku_pixels[256][16] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00}, diff --git a/include/fonts/pixel_font.h b/include/fonts/pixel_font.h index 0436bf1..0e6fb97 100644 --- a/include/fonts/pixel_font.h +++ b/include/fonts/pixel_font.h @@ -3,6 +3,8 @@ #include #include +// 打印单个字符 void pf_print_char(char c, SUINT32 basex, SUINT32 basey, - EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255, 255}); // Pixel Font 打印字符 -void pf_print(String text, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255, 255}); // Pixel Font 打印string \ No newline at end of file + EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255, 255}); +// 打印字符串 +void pf_print(String text, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255, 255}); \ No newline at end of file diff --git a/include/graphics/context.h b/include/graphics/context.h index 218c242..214f14e 100644 --- a/include/graphics/context.h +++ b/include/graphics/context.h @@ -1,7 +1,5 @@ #pragma once -// 这个文件存在的目的是让graphics的draw功能不用每次传 GOP hr vr base - #include #include diff --git a/include/serial.h b/include/serial.h index 21748f8..0297d18 100644 --- a/include/serial.h +++ b/include/serial.h @@ -4,14 +4,20 @@ #include #include -struct serial_context { // 串行内容结构体 +// 串行通信上下文 +struct serial_context { EFI_SERIAL_IO_PROTOCOL *SerialIo; }; extern serial_context g_serial; -void serial_init(EFI_SERIAL_IO_PROTOCOL *SerialIo); // 初始化串行驱动 -void serial_write(String str); // 往串行写string -void serial_write_char(char c); // 往串行写char(不推荐使用) -void serial_write_hex(UINTN val); // 往串行写十六进制数字 -char serial_read_char(); // 读串行 \ No newline at end of file +// 初始化串行驱动 +void serial_init(EFI_SERIAL_IO_PROTOCOL *SerialIo); +// 写字符串到串行 +void serial_write(String str); +// 写单个字符到串行(不推荐直接使用) +void serial_write_char(char c); +// 写十六进制数字到串行 +void serial_write_hex(UINTN val); +// 从串行读取一个字符 +char serial_read_char(); \ No newline at end of file diff --git a/kernel/entry.cpp b/kernel/entry.cpp index 616824e..7ce3fd4 100644 --- a/kernel/entry.cpp +++ b/kernel/entry.cpp @@ -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"); } diff --git a/kernel/graphics/layer.cpp b/kernel/graphics/layer.cpp index 651fc49..2e87561 100644 --- a/kernel/graphics/layer.cpp +++ b/kernel/graphics/layer.cpp @@ -9,36 +9,35 @@ #include #include -// --- 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, diff --git a/kernel/interrupt/idt.cpp b/kernel/interrupt/idt.cpp index 3379b89..fe23169 100644 --- a/kernel/interrupt/idt.cpp +++ b/kernel/interrupt/idt.cpp @@ -4,7 +4,7 @@ #include #include -// 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); diff --git a/kernel/interrupt/pic.cpp b/kernel/interrupt/pic.cpp index 298232a..038dbfd 100644 --- a/kernel/interrupt/pic.cpp +++ b/kernel/interrupt/pic.cpp @@ -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); diff --git a/kernel/interrupt/pit.cpp b/kernel/interrupt/pit.cpp index 4871437..a3b542d 100644 --- a/kernel/interrupt/pit.cpp +++ b/kernel/interrupt/pit.cpp @@ -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 = "); diff --git a/kernel/main.cpp b/kernel/main.cpp index b6d7e0a..ce8cff5 100644 --- a/kernel/main.cpp +++ b/kernel/main.cpp @@ -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}; diff --git a/kernel/memory/heap.cpp b/kernel/memory/heap.cpp index cc581bd..a3adae8 100644 --- a/kernel/memory/heap.cpp +++ b/kernel/memory/heap.cpp @@ -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; diff --git a/kernel/memory/pmm.cpp b/kernel/memory/pmm.cpp index d3cec15..d92c632 100644 --- a/kernel/memory/pmm.cpp +++ b/kernel/memory/pmm.cpp @@ -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++) { diff --git a/kernel/scheduler/scheduler.cpp b/kernel/scheduler/scheduler.cpp index 52e5c02..188b330 100644 --- a/kernel/scheduler/scheduler.cpp +++ b/kernel/scheduler/scheduler.cpp @@ -6,15 +6,15 @@ #include #include -// 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"); } diff --git a/kernel/serial.cpp b/kernel/serial.cpp index ca4ec37..7d59a56 100644 --- a/kernel/serial.cpp +++ b/kernel/serial.cpp @@ -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;