Interface-Driven OS Kernel for AI-Assisted Learning | Multi-Architecture: x86_64, RISC-V 64, AArch64
🤖 Design Philosophy: Define clear kernel interfaces, let AI generate the implementation — a new paradigm for learning operating systems
- ✨ Project Overview
- 🤖 AI-Oriented Design Philosophy
- 🏛️ Interface Architecture Overview
- 🏗️ Supported Architectures
- 🚀 Quick Start
- 📂 Project Structure
- 🎯 Learning Path
- 📦 Third-Party Dependencies
- 📝 Development Guide
- 🤝 Contributing
- 📄 License
SimpleKernel is a modern OS kernel project designed for AI-assisted learning. Written in C++23, it supports x86_64, RISC-V 64, and AArch64 architectures.
Unlike traditional OS teaching projects, SimpleKernel adopts an Interface-Driven design:
- The project body is interface definitions — complete header files (
.h/.hpp) containing class declarations, pure virtual interfaces, type definitions, and Doxygen documentation - Implementation is done by AI — you only need to understand the interface contracts, and let AI generate
.cppimplementations from the interface docs - Reference implementations for comparison — the project provides complete reference implementations to verify the correctness of AI-generated code
| Feature | Description |
|---|---|
| 🤖 AI-First Design | Interface docs serve as prompts — AI can generate complete implementations directly from header files |
| 📐 Interface-Implementation Separation | Headers contain only declarations and contracts; implementations live in separate .cpp files |
| 🌐 Three-Architecture Support | x86_64, RISC-V 64, AArch64 — one set of interfaces adapting to different hardware |
| 🧪 Test-Driven Verification | GoogleTest test suites verify whether AI-generated implementations conform to interface contracts |
| 📖 Complete Doxygen Documentation | Every interface has responsibility descriptions, preconditions, postconditions, and usage examples |
| 🏗️ Engineering Infrastructure | CMake build, Docker environment, CI/CD, clang-format/clang-tidy |
Traditional OS teaching projects follow: read code → understand principles → mimic and modify. This approach has several problems:
- Kernel codebases are large — beginners easily get lost in implementation details
- Modules are tightly coupled — difficult to understand individual subsystems independently
- Implementing a module from scratch has a high barrier with long feedback cycles
SimpleKernel proposes a new paradigm: read interface → understand contract → AI implements → test verifies
┌─────────────────────────────────────────────────────────┐
│ SimpleKernel Learning Flow │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 📐 Inter- │───▶│ 🤖 AI │───▶│ 🧪 Test │ │
│ │ face Hdrs │ │ Generates│ │ Verifies │ │
│ │ + Doxygen │ │ Impl │ │ Contract │ │
│ │ │ │ (.cpp) │ │ GoogleTest│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │
│ │ ┌──────────┐ │ │
│ └────────▶│ 📚 Ref │◀─────────┘ │
│ │ Impl │ │
│ └──────────┘ │
└─────────────────────────────────────────────────────────┘
Each module's header file contains complete interface documentation:
/**
* @brief Console driver abstract base class
*
* All serial/console drivers must implement this interface.
*
* @pre Hardware has completed basic initialization (clock enable, pin config)
* @post PutChar/GetChar can be used for character-level I/O
*
* Known implementations: 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;
};Provide the header file as context to an AI (e.g., GitHub Copilot, ChatGPT, Claude) and ask it to generate the .cpp implementation. The Doxygen comments in the interface are the best prompt.
Run the project's built-in test suite to verify the AI-generated implementation conforms to the interface contract:
cmake --preset build_riscv64
cd build_riscv64 && make unit-testIf tests fail, refer to the project's reference implementation for comparison and learning.
| Scenario | Usage |
|---|---|
| GitHub Copilot | Open the header file, let Copilot auto-complete the implementation in the corresponding .cpp |
| ChatGPT / Claude | Paste header file contents as context, request a complete .cpp implementation |
| Copilot Chat / Cursor | Select the interface in the IDE, ask AI to explain contract meaning or generate implementation |
| Self-Study | Think about the implementation first, then let AI generate it, and compare differences |
SimpleKernel's interfaces are organized into the following layers:
┌──────────────────────────────────────────┐
│ Application / Syscall Layer │
│ syscall.h · SyscallInit │
├──────────────────────────────────────────┤
│ Task Management Layer │
│ TaskManager · SchedulerBase · Mutex │
│ CfsScheduler · FifoScheduler · RR ... │
├──────────────────────────────────────────┤
│ Memory Management Layer │
│ VirtualMemory · PhysicalMemory │
│ MapPage · UnmapPage · AllocFrame │
├──────────────────────────────────────────┤
│ Interrupt / Exception Layer │
│ InterruptBase · RegisterInterruptFunc │
│ TimerInit · InterruptInit │
├──────────────────────────────────────────┤
│ Driver Layer │
│ ConsoleDriver · Ns16550a · Pl011 │
│ Gic · Plic · Apic · Timer drivers │
├──────────────────────────────────────────┤
│ Architecture Abstraction (arch.h) │
│ ArchInit · InterruptInit · TimerInit │
│ EarlyConsole (auto-set during global │
│ construction phase) │
├──────────────────────────────────────────┤
│ Runtime Support Libraries │
│ libc (sk_cstdio, sk_cstring, ...) │
│ libcxx (sk_vector, __cxa_*, ...) │
├──────────────────────────────────────────┤
│ Hardware / QEMU │
│ x86_64 · RISC-V 64 · AArch64 │
└──────────────────────────────────────────┘
| Interface File | Responsibility | Implementation File |
|---|---|---|
src/arch/arch.h |
Architecture-independent unified entry | Each src/arch/{arch}/ directory |
src/include/interrupt_base.h |
Interrupt subsystem abstract base class | src/arch/{arch}/interrupt.cpp |
src/driver/include/console_driver.h |
Console driver abstraction | ns16550a.cpp / pl011.cpp |
src/include/virtual_memory.hpp |
Virtual memory management interface | src/virtual_memory.cpp |
src/include/kernel_fdt.hpp |
Device tree parsing interface | src/kernel_fdt.cpp |
src/include/kernel_elf.hpp |
ELF parsing interface | src/kernel_elf.cpp |
src/task/include/scheduler_base.hpp |
Scheduler abstract base class | cfs_scheduler.cpp etc. |
src/include/spinlock.hpp |
Spinlock interface | header-only (performance) |
src/include/mutex.hpp |
Mutex interface | src/task/mutex.cpp |
📋 See doc/TODO_interface_refactor.md for the complete interface refactoring plan.
| Architecture | Boot Chain | Serial | Interrupt Controller | Timer |
|---|---|---|---|---|
| x86_64 | U-Boot | NS16550A | 8259A PIC | 8253/8254 |
| RISC-V 64 | U-Boot + OpenSBI | SBI Call | Direct Mode | SBI Timer |
| AArch64 | U-Boot + ATF + OP-TEE | PL011 | GICv3 | Generic Timer |
- Operating System: Linux (Ubuntu 24.04 recommended) or macOS
- Container Engine: Docker 20.10+
- Toolchain: Included in Docker image (GCC cross-compilers, CMake, QEMU, etc.)
- AI Tools (recommended): GitHub Copilot / ChatGPT / Claude
Option 1: Using Docker (Recommended)
# 1. Clone the project
git clone https://github.com/simple-xx/SimpleKernel.git
cd SimpleKernel
git submodule update --init --recursive
# 2. Start development environment
docker pull ptrnull233/simple_kernel:latest
docker run --name SimpleKernel-dev -itd -p 233:22 \
-v $(pwd):/root/SimpleKernel ptrnull233/simple_kernel:latest
# 3. Enter development container
docker exec -it SimpleKernel-dev /bin/zshOption 2: Local Environment
Refer to Toolchain Documentation for local development environment setup.
cd SimpleKernel
# Select target architecture (RISC-V 64 example)
cmake --preset build_riscv64
cd build_riscv64
# Build kernel
make SimpleKernel
# Run in QEMU emulator
make run
# Run unit tests (verify your implementation)
make unit-testSupported Architecture Presets:
build_riscv64- RISC-V 64-bit architecturebuild_aarch64- ARM 64-bit architecturebuild_x86_64- x86 64-bit architecture
# 1. Open project in VS Code (GitHub Copilot extension recommended)
code ./SimpleKernel
# 2. Read interface definitions in header files (e.g., src/include/virtual_memory.hpp)
# 3. Create/edit the corresponding .cpp file, let AI generate implementation from the interface
# 4. Build and verify
cd build_riscv64 && make SimpleKernel
# 5. Run tests
make unit-test
# 6. Run in QEMU, observe behavior
make runSimpleKernel/
├── src/ # Kernel source code
│ ├── include/ # 📐 Public interface headers (project core)
│ │ ├── virtual_memory.hpp # Virtual memory management interface
│ │ ├── kernel_fdt.hpp # Device tree parsing interface
│ │ ├── kernel_elf.hpp # ELF parsing interface
│ │ ├── spinlock.hpp # Spinlock interface
│ │ ├── mutex.hpp # Mutex interface
│ │ └── ...
│ ├── arch/ # Architecture-specific code
│ │ ├── arch.h # 📐 Architecture-independent unified interface
│ │ ├── aarch64/ # AArch64 implementation
│ │ ├── riscv64/ # RISC-V 64 implementation
│ │ └── x86_64/ # x86_64 implementation
│ ├── driver/ # Device drivers
│ │ ├── include/ # 📐 Driver interfaces (ConsoleDriver, etc.)
│ │ ├── ns16550a/ # NS16550A serial driver implementation
│ │ ├── pl011/ # PL011 serial driver implementation
│ │ └── ...
│ ├── task/ # Task management
│ │ ├── include/ # 📐 Scheduler interfaces (SchedulerBase, etc.)
│ │ └── ... # Scheduler implementations
│ ├── libc/ # Kernel C standard library
│ └── libcxx/ # Kernel C++ runtime
├── tests/ # 🧪 Test suite
│ ├── unit_test/ # Unit tests
│ ├── integration_test/ # Integration tests
│ └── system_test/ # System tests (QEMU-based)
├── doc/ # 📚 Documentation
│ ├── TODO_interface_refactor.md # Interface refactoring plan
│ └── ...
├── cmake/ # CMake build configuration
├── 3rd/ # Third-party dependencies (Git Submodule)
└── tools/ # Build tools and templates
Directories/files marked with 📐 are interface definitions — these are what you should focus on reading.
We recommend learning and implementing modules in the following order:
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| Early Console | src/arch/arch.h comments |
⭐ | Earliest output, understand global construction |
| Serial Driver | console_driver.h |
⭐⭐ | Implement PutChar/GetChar, understand MMIO |
| Device Tree Parsing | kernel_fdt.hpp |
⭐⭐ | Parse hardware info, understand FDT format |
| ELF Parsing | kernel_elf.hpp |
⭐⭐ | Symbol table parsing, used for stack backtrace |
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| Interrupt Base | interrupt_base.h |
⭐⭐ | Understand unified interrupt abstraction |
| Interrupt Controller | Per-arch driver headers | ⭐⭐⭐ | GIC/PLIC/PIC hardware programming |
| Timer Interrupt | arch.h → TimerInit |
⭐⭐ | Timer configuration, tick-driven |
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| Virtual Memory | virtual_memory.hpp |
⭐⭐⭐ | Page table management, address mapping |
| Physical Memory | Related interfaces | ⭐⭐⭐ | Frame allocator, buddy system |
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| Spinlock | spinlock.hpp |
⭐⭐ | Atomic operations, multi-core synchronization |
| Mutex | mutex.hpp |
⭐⭐⭐ | Task-blocking based lock |
| Scheduler | scheduler_base.hpp |
⭐⭐⭐ | CFS/FIFO/RR scheduling algorithms |
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| System Calls | arch.h → SyscallInit |
⭐⭐⭐ | User/kernel mode switching |
| Dependency | Purpose |
|---|---|
| google/googletest | Testing framework |
| charlesnicholson/nanoprintf | printf implementation |
| MRNIU/cpu_io | CPU I/O operations |
| riscv-software-src/opensbi | RISC-V SBI implementation |
| MRNIU/opensbi_interface | OpenSBI interface |
| u-boot/u-boot | Universal bootloader |
| OP-TEE/optee_os | OP-TEE operating system |
| ARM-software/arm-trusted-firmware | ARM Trusted Firmware |
| dtc/dtc | Device Tree Compiler |
- Language Standard: C23 / C++23
- Coding Standard: Google C++ Style Guide
- Auto Formatting:
.clang-format+.clang-tidy - Comment Standard: Doxygen style; interface files must contain complete contract documentation
| Type | Style | Example |
|---|---|---|
| Files | lower_snake_case | kernel_log.hpp |
| Classes/Structs | PascalCase | TaskManager |
| Functions | PascalCase / snake_case | ArchInit / sys_yield |
| Variables | snake_case | per_cpu_data |
| Macros | SCREAMING_SNAKE | SIMPLEKERNEL_DEBUG |
| Constants | kCamelCase | kPageSize |
| Kernel libc/libc++ headers | sk_ prefix |
sk_cstdio |
<type>(<scope>): <subject>
type: feat|fix|docs|style|refactor|perf|test|build|revert
scope: optional, affected module (arch, driver, libc)
subject: max 50 chars, no period
- Toolchain: doc/0_工具链.md
- System Boot: doc/1_系统启动.md
- Debug Output: doc/2_调试输出.md
- Interrupts: doc/3_中断.md
- Docker: doc/docker.md
- Interface Refactoring Plan: doc/TODO_interface_refactor.md
We welcome all forms of contributions!
| Method | Description |
|---|---|
| 🐛 Report Issues | Report bugs via GitHub Issues |
| 📐 Improve Interfaces | Suggest better interface abstractions and documentation improvements |
| 🧪 Add Tests | Write more comprehensive test cases for existing interfaces |
| 📖 Improve Documentation | Enhance Doxygen comments, add usage examples |
| 🔧 Submit Implementations | Submit reference or alternative implementations of interfaces |
- Fork this repository
- Create a feature branch:
git checkout -b feat/amazing-feature - Follow coding standards during development
- Ensure all tests pass
- Commit changes:
git commit -m 'feat(scope): add amazing feature' - Create a Pull Request
This project is dual-licensed:
- Code License - MIT License
- Anti-996 License - Anti 996 License
⭐ If this project helps you, please give us a Star!
🤖 Let AI write the kernel, so you can focus on understanding OS principles!