Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Simple kernel for learning operating systems. 用于学习操作系统的简单内核

License

Notifications You must be signed in to change notification settings

rayshencc/SimpleKernel

Repository files navigation

codecov workflow commit-activity last-commit-interrupt MIT License LICENSE 996.icu

English | 中文

SimpleKernel

面向 AI 的操作系统学习项目 | Interface-Driven OS Kernel for AI-Assisted Learning

🤖 设计理念:定义清晰的内核接口,由 AI 完成实现——学习操作系统的新范式

📖 目录

✨ 项目简介

SimpleKernel 是一个面向 AI 辅助学习的现代化操作系统内核项目。采用 C++23 编写,支持 x86_64、RISC-V 64 和 AArch64 三种架构。

与传统 OS 教学项目不同,SimpleKernel 采用接口驱动(Interface-Driven) 的设计:

  • 项目主体是接口定义——完整的头文件(.h/.hpp)包含类声明、纯虚接口、类型定义、Doxygen 文档
  • 实现由 AI 完成——你只需要理解接口契约,让 AI 根据接口文档生成实现代码
  • 参考实现可供对照——项目提供完整的参考实现,用于验证 AI 生成代码的正确性

🌟 核心亮点

特性 说明
🤖 AI-First 设计 接口文档即 prompt,AI 可直接根据头文件生成完整实现
📐 接口与实现分离 头文件只有声明和契约,实现在独立的 .cpp
🌐 三架构支持 x86_64、RISC-V 64、AArch64,同一套接口适配不同硬件
🧪 测试驱动验证 GoogleTest 测试套件验证 AI 生成的实现是否符合接口契约
📖 完整 Doxygen 文档 每个接口都有职责描述、前置条件、后置条件、使用示例
🏗️ 工程化基础设施 CMake 构建、Docker 环境、CI/CD、clang-format/clang-tidy

🤖 面向 AI 的设计理念

为什么要"面向 AI"?

传统 OS 教学项目的学习路径:读代码 → 理解原理 → 模仿修改。这种方式存在几个问题:

  1. 内核代码量大,初学者容易迷失在实现细节中
  2. 各模块耦合紧密,难以独立理解单个子系统
  3. 从零实现一个模块的门槛很高,反馈周期长

SimpleKernel 提出一种新范式:读接口 → 理解契约 → AI 实现 → 测试验证

┌─────────────────────────────────────────────────────────┐
│ SimpleKernel 学习流程 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 📐 接口 │───▶│ 🤖 AI │───▶│ 🧪 测试 │ │
│ │ 头文件 │ │ 生成实现 │ │ 验证正确性│ │
│ │ + Doxygen │ │ (.cpp) │ │ GoogleTest│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │
│ │ ┌──────────┐ │ │
│ └────────▶│ 📚 参考 │◀─────────┘ │
│ │ 实现对照 │ │
│ └──────────┘ │
└─────────────────────────────────────────────────────────┘

核心工作流

1️⃣ 阅读接口,理解契约

每个模块的头文件都包含完整的接口文档:

/**
 * @brief 控制台驱动抽象基类
 *
 * 所有串口/控制台驱动必须实现此接口。
 *
 * @pre 硬件已完成基本初始化(时钟使能、引脚配置)
 * @post 调用 PutChar/GetChar 可进行字符级 I/O
 *
 * 已知实现:Ns16550a(RISC-V/x86_64)、Pl011(AArch64)
 */
class ConsoleDriver {
public:
 virtual ~ConsoleDriver() = default;
 virtual void PutChar(uint8_t c) const = 0;
 [[nodiscard]] virtual auto GetChar() const -> uint8_t = 0;
 [[nodiscard]] virtual auto TryGetChar() const -> uint8_t = 0;
};

2️⃣ 让 AI 实现

将头文件作为上下文提供给 AI(如 GitHub Copilot、ChatGPT、Claude 等),要求其生成 .cpp 实现。接口的 Doxygen 注释就是最好的 prompt。

3️⃣ 测试验证

运行项目自带的测试套件,验证 AI 生成的实现是否符合接口契约:

cmake --preset build_riscv64
cd build_riscv64 && make unit-test

4️⃣ 对照参考实现

如果测试不通过,可以参考项目提供的参考实现进行对照和学习。

与 AI 工具的结合方式

场景 使用方式
GitHub Copilot 打开头文件,在对应的 .cpp 中让 Copilot 自动补全实现
ChatGPT / Claude 将头文件内容粘贴为上下文,要求生成完整的 .cpp 实现
Copilot Chat / Cursor 在 IDE 中选中接口,要求 AI 解释契约含义或生成实现
自主学习 先独立思考实现思路,再让 AI 生成,对比差异

🏛️ 接口体系总览

SimpleKernel 的接口按功能分为以下层次:

┌──────────────────────────────────────────┐
│ 应用/系统调用层 │
│ syscall.h · SyscallInit │
├──────────────────────────────────────────┤
│ 任务管理层 │
│ TaskManager · SchedulerBase · Mutex │
│ CfsScheduler · FifoScheduler · RR ... │
├──────────────────────────────────────────┤
│ 内存管理层 │
│ VirtualMemory · PhysicalMemory │
│ MapPage · UnmapPage · AllocFrame │
├──────────────────────────────────────────┤
│ 中断/异常层 │
│ InterruptBase · RegisterInterruptFunc │
│ TimerInit · InterruptInit │
├──────────────────────────────────────────┤
│ 驱动层 │
│ ConsoleDriver · Ns16550a · Pl011 │
│ Gic · Plic · Apic · Timer drivers │
├──────────────────────────────────────────┤
│ 架构抽象层 (arch.h) │
│ ArchInit · InterruptInit · TimerInit │
│ EarlyConsole(全局构造阶段自动设置) │
├──────────────────────────────────────────┤
│ 运行时支持库 │
│ libc (sk_cstdio, sk_cstring, ...) │
│ libcxx (sk_vector, __cxa_*, ...) │
├──────────────────────────────────────────┤
│ 硬件 / QEMU │
│ x86_64 · RISC-V 64 · AArch64 │
└──────────────────────────────────────────┘

关键接口文件

接口文件 职责 实现文件
src/arch/arch.h 架构无关的统一入口 src/arch/{arch}/ 目录
src/include/interrupt_base.h 中断子系统抽象基类 src/arch/{arch}/interrupt.cpp
src/driver/include/console_driver.h 控制台驱动抽象 ns16550a.cpp / pl011.cpp
src/include/virtual_memory.hpp 虚拟内存管理接口 src/virtual_memory.cpp
src/include/kernel_fdt.hpp 设备树解析接口 src/kernel_fdt.cpp
src/include/kernel_elf.hpp ELF 解析接口 src/kernel_elf.cpp
src/task/include/scheduler_base.hpp 调度器抽象基类 cfs_scheduler.cpp
src/include/spinlock.hpp 自旋锁接口 header-only(性能要求)
src/include/mutex.hpp 互斥锁接口 src/task/mutex.cpp

📋 完整接口重构计划见 doc/TODO_interface_refactor.md

🏗️ 支持架构

架构 引导链 串口 中断控制器 时钟
x86_64 U-Boot COM1 8259A PIC 8253/8254
RISC-V 64 U-Boot + OpenSBI SBI Call Direct 模式 SBI Timer
AArch64 U-Boot + ATF + OP-TEE PL011 GICv3 Generic Timer

🚀 快速开始

📋 系统要求

  • 操作系统: Linux (推荐 Ubuntu 24.04) 或 macOS
  • 容器引擎: Docker 20.10+
  • 工具链: 已包含在 Docker 镜像中(GCC 交叉编译器、CMake、QEMU 等)
  • AI 工具(推荐): GitHub Copilot / ChatGPT / Claude

🛠️ 环境搭建

方式一:使用 Docker(推荐)

# 1. 克隆项目
git clone https://github.com/simple-xx/SimpleKernel.git
cd SimpleKernel
git submodule update --init --recursive
# 2. 启动开发环境
docker pull ptrnull233/simple_kernel:latest
docker run --name SimpleKernel-dev -itd -p 233:22 \
 -v $(pwd):/root/SimpleKernel ptrnull233/simple_kernel:latest
# 3. 进入开发容器
docker exec -it SimpleKernel-dev /bin/zsh

方式二:本地环境

参考 工具链文档 配置本地开发环境。

⚡ 编译与运行

cd SimpleKernel
# 选择目标架构编译(以 RISC-V 64 为例)
cmake --preset build_riscv64
cd build_riscv64
# 编译内核
make SimpleKernel
# 在 QEMU 模拟器中运行
make run
# 运行单元测试(验证你的实现)
make unit-test

支持的架构预设:

  • build_riscv64 - RISC-V 64 位架构
  • build_aarch64 - ARM 64 位架构
  • build_x86_64 - x86 64 位架构

🎯 AI 辅助开发工作流

# 1. 在 VS Code 中打开项目(推荐安装 GitHub Copilot 扩展)
code ./SimpleKernel
# 2. 阅读头文件中的接口定义(例如 src/include/virtual_memory.hpp)
# 3. 创建/编辑对应的 .cpp 文件,让 AI 根据接口生成实现
# 4. 编译验证
cd build_riscv64 && make SimpleKernel
# 5. 运行测试
make unit-test
# 6. 在 QEMU 中运行,观察行为
make run

📂 项目结构

SimpleKernel/
├── src/ # 内核源码
│ ├── include/ # 📐 公共接口头文件(项目核心)
│ │ ├── virtual_memory.hpp # 虚拟内存管理接口
│ │ ├── kernel_fdt.hpp # 设备树解析接口
│ │ ├── kernel_elf.hpp # ELF 解析接口
│ │ ├── spinlock.hpp # 自旋锁接口
│ │ ├── mutex.hpp # 互斥锁接口
│ │ └── ...
│ ├── arch/ # 架构相关代码
│ │ ├── arch.h # 📐 架构无关统一接口
│ │ ├── aarch64/ # AArch64 实现
│ │ ├── riscv64/ # RISC-V 64 实现
│ │ └── x86_64/ # x86_64 实现
│ ├── driver/ # 设备驱动
│ │ ├── include/ # 📐 驱动接口(ConsoleDriver 等)
│ │ ├── ns16550a/ # NS16550A 串口驱动实现
│ │ ├── pl011/ # PL011 串口驱动实现
│ │ └── ...
│ ├── task/ # 任务管理
│ │ ├── include/ # 📐 调度器接口(SchedulerBase 等)
│ │ └── ... # 调度器实现
│ ├── libc/ # 内核 C 标准库
│ └── libcxx/ # 内核 C++ 运行时
├── tests/ # 🧪 测试套件
│ ├── unit_test/ # 单元测试
│ ├── integration_test/ # 集成测试
│ └── system_test/ # 系统测试(QEMU 运行)
├── doc/ # 📚 文档
│ ├── TODO_interface_refactor.md # 接口重构计划
│ └── ...
├── cmake/ # CMake 构建配置
├── 3rd/ # 第三方依赖(Git Submodule)
└── tools/ # 构建工具和模板

📐 标记的目录/文件是接口定义——这是你需要重点阅读的内容。

🎯 学习路线

建议按以下顺序学习和实现各模块:

阶段 1:基础设施(Boot)

模块 接口文件 难度 说明
Early Console src/arch/arch.h 注释 最早期的输出,理解全局构造
串口驱动 console_driver.h ⭐⭐ 实现 PutChar/GetChar,理解 MMIO
设备树解析 kernel_fdt.hpp ⭐⭐ 解析硬件信息,理解 FDT 格式
ELF 解析 kernel_elf.hpp ⭐⭐ 符号表解析,用于栈回溯

阶段 2:中断系统(Interrupt)

模块 接口文件 难度 说明
中断基类 interrupt_base.h ⭐⭐ 理解中断处理的统一抽象
中断控制器 各架构驱动头文件 ⭐⭐⭐ GIC/PLIC/PIC 硬件编程
时钟中断 arch.h → TimerInit ⭐⭐ 定时器配置,tick 驱动

阶段 3:内存管理(Memory)

模块 接口文件 难度 说明
虚拟内存 virtual_memory.hpp ⭐⭐⭐ 页表管理、地址映射
物理内存 相关接口 ⭐⭐⭐ 帧分配器、伙伴系统

阶段 4:任务管理(Thread/Task)

模块 接口文件 难度 说明
自旋锁 spinlock.hpp ⭐⭐ 原子操作,多核同步
互斥锁 mutex.hpp ⭐⭐⭐ 基于任务阻塞的锁
调度器 scheduler_base.hpp ⭐⭐⭐ CFS/FIFO/RR 调度算法

阶段 5:系统调用(Syscall)

模块 接口文件 难度 说明
系统调用 arch.h → SyscallInit ⭐⭐⭐ 用户态/内核态切换

📦 第三方依赖

依赖 用途
google/googletest 测试框架
charlesnicholson/nanoprintf printf 实现
MRNIU/cpu_io CPU I/O 操作
riscv-software-src/opensbi RISC-V SBI 实现
MRNIU/opensbi_interface OpenSBI 接口
u-boot/u-boot 通用引导程序
OP-TEE/optee_os OP-TEE 操作系统
ARM-software/arm-trusted-firmware ARM 可信固件
dtc/dtc 设备树编译器

📝 开发指南

🎨 代码风格

  • 语言标准: C23 / C++23
  • 编码规范: Google C++ Style Guide
  • 自动格式化: .clang-format + .clang-tidy
  • 注释规范: Doxygen 风格,接口文件必须包含完整的契约文档

命名约定

类型 风格 示例
文件 小写下划线 kernel_log.hpp
类/结构体 PascalCase TaskManager
函数 PascalCase / snake_case ArchInit / sys_yield
变量 snake_case per_cpu_data
SCREAMING_SNAKE SIMPLEKERNEL_DEBUG
常量 kCamelCase kPageSize
内核 libc/libc++ 头文件 sk_ 前缀 sk_cstdio

📋 Git Commit 规范

<type>(<scope>): <subject>
type: feat|fix|docs|style|refactor|perf|test|build|revert
scope: 可选,影响的模块 (arch, driver, libc)
subject: 不超过50字符,不加句号

📚 文档

🤝 贡献指南

我们欢迎所有形式的贡献!

🎯 贡献方式

方式 说明
🐛 报告问题 通过 GitHub Issues 报告 Bug
📐 改进接口 提出更好的接口抽象和文档改进建议
🧪 补充测试 为现有接口编写更完整的测试用例
📖 完善文档 改进 Doxygen 注释、添加使用示例
🔧 提交实现 提交接口的参考实现或替代实现

🔧 代码贡献流程

  1. Fork 本仓库
  2. 创建功能分支: git checkout -b feat/amazing-feature
  3. 遵循代码规范进行开发
  4. 确保所有测试通过
  5. 提交变更: git commit -m 'feat(scope): add amazing feature'
  6. 创建 Pull Request

📄 许可证

本项目采用多重许可证:


⭐ 如果这个项目对您有帮助,请给我们一个 Star!

🤖 让 AI 帮你写内核,让你专注于理解操作系统原理!

🌟 Star 项目🐛 报告问题💬 参与讨论

About

Simple kernel for learning operating systems. 用于学习操作系统的简单内核

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 94.4%
  • CMake 2.0%
  • Linker Script 1.3%
  • Assembly 1.3%
  • Other 1.0%

AltStyle によって変換されたページ (->オリジナル) /