Conversation
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
There was a problem hiding this comment.
Pull request overview
该 PR 进行了跨架构/驱动/构建系统的“大规模重构”,新增了多套驱动实现与更现代化的 CMake 构建/CI/文档生成流程,并引入多个第三方子模块以支持系统级功能扩展。
Changes:
- 新增 ELF 解析/错误码 Expected 基础设施,以及多个架构的启动、中断、定时器、回溯等实现骨架
- 新增/重组驱动模块(PLIC/PL011/NS16550A/APIC/ACPI/GIC 等)及对应 CMake 集成与文档
- 重构顶层 CMake/CI(GitHub Actions)、开发容器与工程配置(clang-tidy、子模块等)
Reviewed changes
Copilot reviewed 162 out of 684 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| src/include/kernel_elf.hpp | 新增内核 ELF 解析类,用于符号表/字符串表解析以支持回溯符号化 |
| src/include/kernel.h | 新增内核入口与内存初始化声明 |
| src/include/io.hpp | 新增 MMIO 读写模板封装 |
| src/include/interrupt_base.h | 新增跨架构中断抽象基类与 IPI 接口 |
| src/include/expected.hpp | 新增基于 std::expected 的错误码/错误类型基础设施 |
| src/include/config.h | 引入项目配置头的统一入口 |
| src/include/basic_info.hpp | 新增 BasicInfo 结构与打印,用于启动阶段信息汇总 |
| src/driver/plic/plic.cpp | 新增 RISC-V PLIC 驱动实现 |
| src/driver/plic/include/plic.h | 新增 PLIC 驱动接口定义 |
| src/driver/plic/README.md | 新增 PLIC 驱动使用说明 |
| src/driver/plic/CMakeLists.txt | 新增 PLIC 模块构建配置 |
| src/driver/pl011/pl011.cpp | 新增 ARM PL011 UART 驱动实现 |
| src/driver/pl011/include/pl011.h | 新增 PL011 UART 接口定义 |
| src/driver/pl011/README.md | 新增 PL011 驱动说明 |
| src/driver/pl011/CMakeLists.txt | 新增 PL011 模块构建配置 |
| src/driver/ns16550a/ns16550a.cpp | 新增 NS16550A UART 驱动实现 |
| src/driver/ns16550a/include/ns16550a.h | 新增 NS16550A UART 接口定义 |
| src/driver/ns16550a/README.md | 新增 NS16550A 驱动说明 |
| src/driver/ns16550a/CMakeLists.txt | 新增 NS16550A 模块构建配置 |
| src/driver/include/driver.h | 新增驱动入口声明 |
| src/driver/gic/README.md | 新增 GIC 文档(说明接口/示例) |
| src/driver/gic/CMakeLists.txt | 新增 GIC 模块构建配置 |
| src/driver/driver.cpp | 新增(占位)驱动入口实现 |
| src/driver/apic/io_apic.cpp | 新增 IO APIC 驱动实现 |
| src/driver/apic/include/io_apic.h | 新增 IO APIC 接口定义 |
| src/driver/apic/include/apic.h | 新增 APIC 管理类接口 |
| src/driver/apic/apic.cpp | 新增 APIC 管理类实现 |
| src/driver/apic/CMakeLists.txt | 新增 APIC 模块构建配置 |
| src/driver/acpi/include/acpi.h | 新增 ACPI 结构定义与驱动骨架 |
| src/driver/acpi/acpi.cpp | 新增 ACPI 驱动最小实现 |
| src/driver/acpi/README.md | 新增 ACPI 文档 |
| src/driver/acpi/CMakeLists.txt | 新增 ACPI 模块构建配置 |
| src/driver/README.md | 新增 driver 目录说明 |
| src/driver/CMakeLists.txt | 新增/重构 driver 总模块选择与链接(按架构) |
| src/arch/x86_64/timer.cpp | 新增 x86_64 定时器占位实现 |
| src/arch/x86_64/syscall.cpp | 新增 x86_64 syscall 占位实现 |
| src/arch/x86_64/switch.S | 新增 x86_64 上下文切换汇编骨架(未实现) |
| src/arch/x86_64/sipi.h | 新增 x86_64 SIPI 启动参数定义(重复位置之一) |
| src/arch/x86_64/macro.S | 新增 x86_64 汇编宏文件(占位) |
| src/arch/x86_64/interrupt_main.cpp | 新增 x86_64 中断初始化与键盘/APIC timer 示例处理 |
| src/arch/x86_64/interrupt.cpp | 新增 x86_64 IDT/中断分发实现 |
| src/arch/x86_64/interrupt.S | 新增 x86_64 trap_return 汇编骨架(未实现) |
| src/arch/x86_64/include/sipi.h | 新增 x86_64 SIPI 头(重复位置之一) |
| src/arch/x86_64/include/interrupt.h | 新增 x86_64 Interrupt 类声明 |
| src/arch/x86_64/early_console.cpp | 新增 x86_64 早期串口控制台 |
| src/arch/x86_64/boot.S | 新增 x86_64 AP 启动与栈设置逻辑 |
| src/arch/x86_64/backtrace.cpp | 新增 x86_64 回溯采集与符号化输出 |
| src/arch/riscv64/timer.cpp | 新增 RISC-V 定时器初始化与 Tick 处理 |
| src/arch/riscv64/syscall.cpp | 新增 RISC-V 系统调用分发与返回值处理 |
| src/arch/riscv64/switch.S | 新增 RISC-V 线程切换与 kernel_thread_entry |
| src/arch/riscv64/interrupt_main.cpp | 新增 RISC-V 中断注册、PLIC 初始化、trap 向量设置 |
| src/arch/riscv64/interrupt.cpp | 新增 RISC-V 中断/异常分发表与 IPI 实现 |
| src/arch/riscv64/interrupt.S | 新增 RISC-V trap_entry/trap_return 汇编保存/恢复上下文 |
| src/arch/riscv64/include/interrupt.h | 新增 RISC-V Interrupt 类声明 |
| src/arch/riscv64/early_console.cpp | 新增基于 OpenSBI 的早期控制台 |
| src/arch/riscv64/boot/boot.S | 删除旧 RISC-V 启动汇编 |
| src/arch/riscv64/boot.S | 新增 RISC-V 新启动汇编入口 _boot |
| src/arch/riscv64/backtrace.cpp | 新增 RISC-V 回溯与符号化输出 |
| src/arch/riscv64/arch_main.cpp | 新增 RISC-V 架构初始化与任务上下文初始化 |
| src/arch/riscv64/CMakeLists.txt | 删除旧 riscv64 子模块构建文件 |
| src/arch/ia32/i386/boot/boot.S | 删除旧 i386 multiboot 启动汇编 |
| src/arch/ia32/CMakeLists.txt | 删除旧 ia32 构建文件 |
| src/arch/arch.h | 新增跨架构抽象接口声明(ArchInit/InterruptInit/任务上下文等) |
| src/arch/aarch64/timer.cpp | 新增 AArch64 定时器初始化与 Tick |
| src/arch/aarch64/syscall.cpp | 新增 AArch64 syscall 分发与返回值处理 |
| src/arch/aarch64/switch.S | 新增 AArch64 上下文切换与 kernel_thread_entry |
| src/arch/aarch64/interrupt_main.cpp | 新增 AArch64 向量表安装与异常处理框架/串口中断注册 |
| src/arch/aarch64/interrupt.cpp | 新增 AArch64 GIC 初始化与中断分发/IPI 发送 |
| src/arch/aarch64/interrupt.S | 新增 AArch64 vector_table 与 trap_return 实现 |
| src/arch/aarch64/include/interrupt.h | 新增 AArch64 Interrupt 类声明 |
| src/arch/aarch64/early_console.cpp | 新增 AArch64 早期 PL011 控制台 |
| src/arch/aarch64/boot/boot.S | 删除旧 AArch64 启动汇编 |
| src/arch/aarch64/boot.S | 新增 AArch64 新启动汇编入口 _boot |
| src/arch/aarch64/backtrace.cpp | 新增 AArch64 回溯与符号化输出 |
| src/arch/aarch64/arch_main.cpp | 新增 AArch64 架构初始化与任务上下文初始化 |
| src/arch/aarch64/CMakeLists.txt | 删除旧 aarch64 子模块构建文件 |
| src/arch/README.md | 新增 arch 目录整体文档 |
| src/arch/CMakeLists.txt | 重构 arch 目录为按 CMAKE_SYSTEM_PROCESSOR 选择源文件的接口库 |
| run.sh | 删除旧的运行脚本 |
| docs/1_系统启动.md | 删除旧文档 |
| docs/0_工具链.md | 删除旧文档 |
| doc/task_unit_test_new_design.md | 新增 Task 单测设计文档 |
| doc/git_commit.md | 新增 Git Commit 规范文档 |
| doc/CMakeLists.txt | 新增 doxygen 文档生成配置 |
| cmake/x86_64-gcc.cmake | 新增 x86_64 GCC 工具链探测 |
| cmake/riscv64-gcc.cmake | 新增 riscv64 GCC 工具链探测 |
| cmake/aarch64-gcc.cmake | 新增 aarch64 GCC 工具链探测 |
| cmake/replace_kv.cmake | 新增 KV 替换工具脚本(its/scr 生成辅助) |
| cmake/project_config.cmake | 新增项目配置文件生成与工具链信息输出 |
| cmake/functions.cmake | 新增 coverage/run/debug 等自定义目标函数 |
| cmake/clang.cmake | 新增 clang 工具链配置 |
| cmake/toolchain_mac_x86_64.cmake | 删除旧 mac x86_64 工具链文件 |
| cmake/toolchain_mac_riscv.cmake | 删除旧 mac riscv 工具链文件 |
| cmake/toolchain_mac_aarch64.cmake | 删除旧 mac aarch64 工具链文件 |
| cmake/toolchain_linux_x86_64.cmake | 删除旧 linux x86_64 工具链文件 |
| cmake/toolchain_linux_riscv.cmake | 删除旧 linux riscv 工具链文件 |
| cmake/toolchain_linux_aarch64.cmake | 删除旧 linux aarch64 工具链文件 |
| cmake/header_files.cmake | 删除旧头文件注入辅助脚本 |
| cmake/find_asm_files.cmake | 删除旧汇编文件发现脚本 |
| cmake/arch_detector.cmake | 删除旧 ARCH 参数检测脚本 |
| LICENSE | 更新许可证年份信息 |
| CMakeLists.txt | 重构顶层构建入口,集成 tests/doc/3rd/compile_config 等 |
| 3rd/u-boot | 新增子模块引用 |
| 3rd/optee/optee_os | 新增子模块引用 |
| 3rd/optee/optee_client | 新增子模块引用 |
| 3rd/optee/build | 新增子模块引用 |
| 3rd/opensbi_interface | 新增子模块引用 |
| 3rd/opensbi | 新增子模块引用 |
| 3rd/nanoprintf | 新增子模块引用 |
| 3rd/googletest | 新增子模块引用 |
| 3rd/dtc | 新增子模块引用 |
| 3rd/cpu_io | 新增子模块引用 |
| 3rd/bmalloc | 新增子模块引用 |
| 3rd/arm-trusted-firmware | 新增子模块引用 |
| 3rd/MPMCQueue/include/MPMCQueue.hpp | 新增/引入 MPMCQueue 第三方实现 |
| 3rd/MPMCQueue/test/CMakeLists.txt | 新增 MPMCQueue 的 gtest 单测构建配置 |
| 3rd/MPMCQueue/LICENSE | 新增 MPMCQueue License |
| 3rd/MPMCQueue/CMakePresets.json | 新增 MPMCQueue 的 CMake presets |
| 3rd/MPMCQueue/CMakeLists.txt | 新增 MPMCQueue 顶层构建文件 |
| 3rd/MPMCQueue/.gitignore | 新增 MPMCQueue gitignore |
| 3rd/MPMCQueue/.clang-format | 新增 MPMCQueue clang-format |
| .vscode/settings.json | 删除旧 VSCode 工作区配置 |
| .vscode/launch.json | 新增 VSCode 多架构调试配置 |
| .vscode/c_cpp_properties.json | 删除旧 VSCode C/C++ 配置 |
| .gitmodules | 新增/重构子模块列表 |
| .github/workflows/workflow.yml | 新增新的 CI workflow(docker build + coverage + doc 发布) |
| .github/workflows/build.yml | 删除旧 CI workflow |
| .github/FUNDING.yml | 更新 FUNDING 文件头注释 |
| .devcontainer/devcontainer.json | 新增开发容器配置 |
| .clang-tidy | 新增 clang-tidy 规则集 |
Files not reviewed (19)
- .idea/.gitignore: Language not supported
- .idea/SimpleKernel.iml: Language not supported
- .idea/cmake.xml: Language not supported
- .idea/codeStyles/Project.xml: Language not supported
- .idea/codeStyles/codeStyleConfig.xml: Language not supported
- .idea/dictionaries/nzh.xml: Language not supported
- .idea/encodings.xml: Language not supported
- .idea/git_toolbox_prj.xml: Language not supported
- .idea/inspectionProfiles/Project_Default.xml: Language not supported
- .idea/misc.xml: Language not supported
- .idea/modules.xml: Language not supported
- .idea/runConfigurations/kernel.xml: Language not supported
- .idea/runConfigurations/make_i386_iso.xml: Language not supported
- .idea/runConfigurations/make_x86_64_iso.xml: Language not supported
- .idea/runConfigurations/qemu_i386_debug.xml: Language not supported
- .idea/runConfigurations/qemu_riscv64_debug.xml: Language not supported
- .idea/runConfigurations/qemu_x86_64_debug.xml: Language not supported
- .idea/scopes/src.xml: Language not supported
- .idea/vcs.xml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// 最大外部中断数量 | ||
| static constexpr size_t kInterruptMaxCount = 16; |
There was a problem hiding this comment.
PLIC 的 cause/source_id 在实现中被直接用作 interrupt_handlers_ 下标,但 PLIC source ID 范围通常是 1..1023。kInterruptMaxCount = 16 会导致数组越界(例如串口 IRQ 或任意外设中断),属于必修复问题。建议将 handler 容器改为 std::array<..., 1024>(或 ndev_ + 1 的动态容器并在构造时初始化),并在 RegisterInterruptFunc/Do 中进行边界检查与空函数保护。
| /// 最大外部中断数量 | |
| static constexpr size_t kInterruptMaxCount = 16; | |
| /// 最大外部中断数量 (最多支持 1024 个中断源) | |
| static constexpr size_t kInterruptMaxCount = 1024; |
| void Plic::RegisterInterruptFunc(uint8_t cause, InterruptFunc func) { | ||
| interrupt_handlers_[cause] = func; | ||
| } | ||
|
|
||
| void Plic::Do(uint64_t cause, uint8_t* context) { | ||
| interrupt_handlers_[cause](cause, context); |
There was a problem hiding this comment.
RegisterInterruptFunc 与 Do 都没有对 cause 做任何范围/空指针校验,并且 cause 在调用点(如 Which() 返回的 source_id)可达 1023,当前实现会发生越界访问以及对未注册 handler 的空调用。建议:1) 将 cause 类型改为 uint32_t;2) 增加 if (cause < handlers.size() && handlers[cause]) 的保护;3) 对未注册 handler 记录错误并 Done(source_id)。
| void Plic::RegisterInterruptFunc(uint8_t cause, InterruptFunc func) { | |
| interrupt_handlers_[cause] = func; | |
| } | |
| void Plic::Do(uint64_t cause, uint8_t* context) { | |
| interrupt_handlers_[cause](cause, context); | |
| void Plic::RegisterInterruptFunc(uint32_t cause, InterruptFunc func) { | |
| if (cause >= interrupt_handlers_.size()) { | |
| klog::Error("PLIC: invalid interrupt cause %u for registration (max %zu)\n", | |
| cause, interrupt_handlers_.size() - 1); | |
| return; | |
| } | |
| interrupt_handlers_[cause] = func; | |
| } | |
| void Plic::Do(uint32_t cause, uint8_t* context) { | |
| if (cause < interrupt_handlers_.size() && interrupt_handlers_[cause]) { | |
| interrupt_handlers_[cause](cause, context); | |
| } else { | |
| klog::Error("PLIC: unhandled or invalid interrupt cause %u\n", cause); | |
| Done(cause); | |
| } |
| * @param cause 中断或异常号 | ||
| * @param context 中断上下文 | ||
| */ | ||
| void Do(uint64_t cause, uint8_t* context) const; |
There was a problem hiding this comment.
Plic::Do 同时声明了 const/non-const 两个重载,但实现文件只提供了 non-const 版本。这会引入潜在链接错误(若某处以 const 实例调用)且 API 含义重复。建议保留一个版本(通常 Do 不修改对象状态可设为 const),并确保头/源一致。
| * @param cause 外部中断号 | ||
| * @param context 中断上下文 | ||
| */ | ||
| void Do(uint64_t cause, uint8_t* context); |
There was a problem hiding this comment.
Plic::Do 同时声明了 const/non-const 两个重载,但实现文件只提供了 non-const 版本。这会引入潜在链接错误(若某处以 const 实例调用)且 API 含义重复。建议保留一个版本(通常 Do 不修改对象状态可设为 const),并确保头/源一致。
| auto Pl011::TryGetChar() const -> uint8_t { | ||
| // Wait until there is data in the FIFO or device is disabled | ||
| if (io::In<uint32_t>(base_addr_ + kRegFR) & kFRRXFE) { | ||
| return -1; | ||
| } | ||
| return io::In<uint32_t>(base_addr_ + kRegDR); |
There was a problem hiding this comment.
TryGetChar() 返回类型为 uint8_t,但用 -1 表示无数据会发生整数转换(变为 255),调用方无法可靠区分“读到 0xFF”与“无数据”。建议将返回类型改为 int(与 putchar/getchar 常见约定一致)或返回 std::optional<uint8_t>。
| auto Pl011::TryGetChar() const -> uint8_t { | |
| // Wait until there is data in the FIFO or device is disabled | |
| if (io::In<uint32_t>(base_addr_ + kRegFR) & kFRRXFE) { | |
| return -1; | |
| } | |
| return io::In<uint32_t>(base_addr_ + kRegDR); | |
| auto Pl011::TryGetChar() const -> int { | |
| // Return -1 if there is no data available in the FIFO | |
| if (io::In<uint32_t>(base_addr_ + kRegFR) & kFRRXFE) { | |
| return -1; | |
| } | |
| // Mask to 8 bits and return as int to distinguish all byte values from -1 | |
| return static_cast<int>(io::In<uint32_t>(base_addr_ + kRegDR) & 0xffu); |
| } else if (strcmp(shstrtab + shdr.sh_name, ".strtab") == 0) { | ||
| strtab_ = elf_.data() + shdr.sh_offset; | ||
| } | ||
| } |
There was a problem hiding this comment.
ehdr_.e_shstrndx 直接用于索引 shdr_,但当前仅校验了 ELF identity(magic/class),若 section header 字段异常会触发越界读取。此外解析结束后未验证 .symtab/.strtab 是否找到,DumpStack() 中可能对 strtab_ 进行空指针相加。建议:在解析前增加对 e_shoff/e_shnum/e_shentsize/e_shstrndx 的范围校验;解析后若缺失 .symtab/.strtab 返回 kElfSymtabNotFound/kElfStrtabNotFound(或至少设置为空并在回溯打印中显式处理)。
| } | |
| } | |
| // Ensure that required sections were found; otherwise, later uses | |
| // (e.g., stack dumping) could dereference null pointers or empty spans. | |
| if (symtab_.empty()) { | |
| klog::Err("KernelElf missing required .symtab section.\n"); | |
| while (true) { | |
| cpu_io::Pause(); | |
| } | |
| } | |
| if (strtab_ == nullptr) { | |
| klog::Err("KernelElf missing required .strtab section.\n"); | |
| while (true) { | |
| cpu_io::Pause(); | |
| } | |
| } |
| interrupt_handlers[cause](cause, context); | ||
| cpu_io::ICC_EOIR1_EL1::Write(cause); | ||
| } | ||
|
|
||
| void Interrupt::RegisterInterruptFunc(uint64_t cause, InterruptFunc func) { | ||
| if (func) { | ||
| interrupt_handlers[cause] = func; |
There was a problem hiding this comment.
interrupt_handlers 的大小为 kMaxInterrupt = 128,但 cause 来源于 GIC INTID,在更一般的平台上可能超过 127(SPI 32-1019)。当前实现会发生越界调用。建议:在 Do/RegisterInterruptFunc 中增加 cause < interrupt_handlers.size() 的边界检查;对超界 INTID 做降级处理(记录日志并直接 EOI)。
| interrupt_handlers[cause](cause, context); | |
| cpu_io::ICC_EOIR1_EL1::Write(cause); | |
| } | |
| void Interrupt::RegisterInterruptFunc(uint64_t cause, InterruptFunc func) { | |
| if (func) { | |
| interrupt_handlers[cause] = func; | |
| if (cause < interrupt_handlers.size()) { | |
| interrupt_handlers[cause](cause, context); | |
| } else { | |
| klog::Info("Interrupt cause out of range: 0x%llX, 0x%p\n", cause, | |
| context); | |
| } | |
| cpu_io::ICC_EOIR1_EL1::Write(cause); | |
| } | |
| void Interrupt::RegisterInterruptFunc(uint64_t cause, InterruptFunc func) { | |
| if (cause < interrupt_handlers.size()) { | |
| if (func) { | |
| interrupt_handlers[cause] = func; | |
| } | |
| } else { | |
| klog::Info("RegisterInterruptFunc: cause out of range: 0x%llX\n", cause); |
| switch_to: | ||
|
|
||
| .global kernel_thread_entry | ||
| .type kernel_thread_entry, @function | ||
| kernel_thread_entry: |
There was a problem hiding this comment.
switch_to 与 kernel_thread_entry 仅定义了符号但没有任何指令实现,若被调用会直接顺序跌落到后续位置执行,行为未定义且极易导致崩溃。建议至少提供最小安全实现(例如 jmp ./hlt 循环+错误日志)或在未支持 x86_64 线程切换前不要导出这些符号并避免被链接到运行路径。
| switch_to: | |
| .global kernel_thread_entry | |
| .type kernel_thread_entry, @function | |
| kernel_thread_entry: | |
| switch_to: | |
| /* TODO: implement x86_64 context switch. | |
| * Temporary stub: halt CPU in an infinite loop to avoid | |
| * falling through into unrelated code. */ | |
| cli | |
| .Lswitch_to_hang: | |
| hlt | |
| jmp .Lswitch_to_hang | |
| .global kernel_thread_entry | |
| .type kernel_thread_entry, @function | |
| kernel_thread_entry: | |
| /* TODO: implement kernel thread entry. | |
| * Temporary stub: halt CPU in an infinite loop to avoid | |
| * falling through into unrelated code. */ | |
| cli | |
| .Lkernel_thread_entry_hang: | |
| hlt | |
| jmp .Lkernel_thread_entry_hang |
| .type trap_return, @function | ||
| .align 4 | ||
|
|
||
| trap_return: |
There was a problem hiding this comment.
trap_return 只有标签没有实现,若作为任务返回入口或用户态返回路径被调用会立即执行到未知内存/后续符号,导致不可预测的控制流错误。建议补齐最小可用实现(恢复上下文并 iretq/类似机制),或在未实现前改为显式死循环/断言以避免 silent corruption。
| trap_return: | |
| trap_return: | |
| /* Minimal stub to avoid falling through into unknown memory. | |
| * If this symbol is used as a trap/task return entry before a full | |
| * implementation exists, we explicitly halt instead of silently | |
| * corrupting control flow. | |
| */ | |
| cli /* Disable interrupts */ | |
| 1: | |
| hlt /* Halt CPU until next interrupt (which is disabled) */ | |
| jmp 1b /* Infinite loop */ |
| for (size_t i = 0; | ||
| i < (cpu_io::Idtr::Read().limit + 1) / | ||
| sizeof(cpu_io::detail::register_info::IdtrInfo::Idtr); | ||
| i++) { | ||
| klog::Debug("idtr[%d] 0x%p\n", i, cpu_io::Idtr::Read().base + i); |
There was a problem hiding this comment.
循环上界用的是 sizeof(...Idtr) 而不是 sizeof(...Idt),会导致遍历次数计算错误;并且循环中重复 Idtr::Read() 也不必要。建议改为读取一次 auto idtr = cpu_io::Idtr::Read();,并使用 sizeof(Idt) 计算条目数,打印地址时按条目大小正确偏移。
| for (size_t i = 0; | |
| i < (cpu_io::Idtr::Read().limit + 1) / | |
| sizeof(cpu_io::detail::register_info::IdtrInfo::Idtr); | |
| i++) { | |
| klog::Debug("idtr[%d] 0x%p\n", i, cpu_io::Idtr::Read().base + i); | |
| auto idtr_read = cpu_io::Idtr::Read(); | |
| auto entry_count = | |
| (idtr_read.limit + 1) / | |
| sizeof(cpu_io::detail::register_info::IdtrInfo::Idt); | |
| for (size_t i = 0; i < entry_count; i++) { | |
| klog::Debug("idtr[%d] 0x%p\n", i, idtr_read.base + i); |
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
SimpleKernel 变更对比
核心定位变化
新增核心特性
🤖 AI-First 设计 - 接口文档即 prompt,AI 可直接生成实现
📐 接口与实现分离 - 头文件只有声明和契约,实现在独立
.cpp🌐 三架构支持 - x86_64、RISC-V 64、AArch64
🧪 测试驱动验证 - GoogleTest 测试套件验证正确性
📖 完整 Doxygen 文档 - 每个接口都有完整的契约文档
🏗️ 工程化基础设施 - CMake + Docker + CI/CD
技术栈升级
架构支持变化
项目结构变化
新增目录
移除目录
学习路径对比
Simple-XX/SimpleKernel/main
boot → printf → parse_boot_info → pmm → vmm → heap → lib → intr → TODO...
MRNIU/SimpleKernel/main(模块式)
初级:启动与输出 → 中断管理 → 内存管理
中级:设备树/ELF 解析 → 任务调度 → 同步原语
高级:系统调用 → 多核启动
每个模块都有对应的接口文件,可独立学习,AI 辅助实现。
快速开始命令变化
Simple-XX/SimpleKernel/main
git clone https://github.com/Simple-XX/SimpleKernel.git cd SimpleKernel/ bash ./run.shMRNIU/SimpleKernel/main
文档结构对比
Simple-XX/SimpleKernel/main
MRNIU/SimpleKernel/main
Badge 变化
新增:代码覆盖率(codecov)、提交活跃度统计
优化:更精准的 CI 状态标识
移除:多余的 languages badge
总结
这是一次学习范式的革命,从传统的"阅读实现代码学习"转变为"定义接口契约,AI 生成实现"的新模式。
目标用户:从传统 OS 课程学习者 → AI 时代的 OS 学习者,拥抱 AI 作为学习助手
核心价值: