SimpleKernel
March 20, 2026 Β· View on GitHub
SimpleKernel
Interface-Driven OS Kernel for AI-Assisted Learning | Multi-Architecture: RISC-V 64, AArch64
π€ Design Philosophy: Define clear kernel interfaces, let AI generate the implementation β a new paradigm for learning operating systems
π Table of Contents
- β¨ Project Overview
- π€ AI-Oriented Design Philosophy
- ποΈ Interface Architecture Overview
- ποΈ Supported Architectures
- π Quick Start
- π Project Structure
- π― Learning Path
- π¦ Third-Party Dependencies
- π Development Guide
- π€ Contributing
- π License
β¨ Project Overview
SimpleKernel is a modern OS kernel project designed for AI-assisted learning. Written in C++23, it supports 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
π Core Highlights
| 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 |
| π Two-Architecture Support | 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, Dev Container environment, CI/CD, clang-format/clang-tidy |
π€ AI-Oriented Design Philosophy
Why "AI-Oriented"?
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 β β
β ββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Core Workflow
1οΈβ£ Read Interface, Understand Contract
Each module's header file contains complete interface documentation:
/**
* @brief Interrupt subsystem abstract base class
*
* All architecture interrupt handlers must implement this interface.
*
* @pre Hardware interrupt controller has been initialized
* @post Can register interrupt handlers via RegisterInterruptFunc
*
* Known implementations: PLIC (RISC-V), GIC (AArch64)
*/
class InterruptBase {
public:
virtual ~InterruptBase() = default;
/// Execute interrupt handling
virtual void Do(uint64_t cause, cpu_io::TrapContext* context) = 0;
/// Register interrupt handler function
virtual void RegisterInterruptFunc(uint64_t cause, InterruptFunc func) = 0;
};
2οΈβ£ Let AI Implement
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.
3οΈβ£ Test and Verify
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-test
4οΈβ£ Compare with Reference Implementation
If tests fail, refer to the project's reference implementation for comparison and learning.
Integration with AI Tools
| 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 |
ποΈ Interface Architecture Overview
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 β
ββββββββββββββββββββββββββββββββββββββββββββ€
β Device Framework Layer β
β DeviceManager Β· DriverRegistry β
β PlatformBus Β· Ns16550aDriver Β· VirtioBlk β
ββββββββββββββββββββββββββββββββββββββββββββ€
β Architecture Abstraction (arch.h) β
β ArchInit Β· InterruptInit Β· TimerInit β
β EarlyConsole (auto-set during global β
β construction phase) β
ββββββββββββββββββββββββββββββββββββββββββββ€
β Runtime Support Libraries β
β libc (sk_stdio.h, sk_string.h, ...) β
β libcxx (kstd_vector, __cxa_*, ...) β
ββββββββββββββββββββββββββββββββββββββββββββ€
β Hardware / QEMU β
β RISC-V 64 Β· AArch64 β
ββββββββββββββββββββββββββββββββββββββββββββ
Key Interface Files
| 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/device/include/device_manager.hpp | Device manager | header-only |
src/device/include/driver_registry.hpp | Driver registry | header-only |
src/device/include/platform_bus.hpp | Platform bus (FDT enumeration) | header-only |
src/device/include/driver/ns16550a_driver.hpp | NS16550A UART driver | header-only (Probe/Remove pattern) |
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 docs/TODO_interface_refactor.md for the complete interface refactoring plan.
ποΈ Supported Architectures
| Architecture | Boot Chain | Serial | Interrupt Controller | Timer |
|---|---|---|---|---|
| RISC-V 64 | U-Boot + OpenSBI | SBI Call | Direct Mode | SBI Timer |
| AArch64 | U-Boot + ATF + OP-TEE | PL011 | GICv3 | Generic Timer |
π Quick Start
π System Requirements
- Operating System: Linux (Ubuntu 24.04 recommended) or macOS
- Container Engine: Docker or compatible container runtime
- Toolchain: Included in Dev Container (GCC 14 cross-compilers, CMake, QEMU, etc.)
- AI Tools (recommended): GitHub Copilot / ChatGPT / Claude
π οΈ Environment Setup
Option 1: Using Dev Container (Recommended)
# 1. Clone the project
git clone https://github.com/simple-xx/SimpleKernel.git
cd SimpleKernel
# 2. Open in VS Code and reopen in container
# Install Dev Containers extension, click the >< icon at bottom-left
# Select "Reopen in Container"
# Or use CLI
npm install -g @devcontainers/cli
devcontainer up --workspace-folder .
devcontainer exec --workspace-folder . bash
Also supports GitHub Codespaces: Click Code β Codespaces β Create codespace on main
See Dev Container documentation for details.
Option 2: Local Environment
Refer to Toolchain Documentation for local development environment setup.
β‘ Build and Run
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-test
Supported Architecture Presets:
build_riscv64- RISC-V 64-bit architecturebuild_aarch64- ARM 64-bit architecture
π― AI-Assisted Development Workflow
# 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 run
π Project Structure
SimpleKernel/
βββ 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
β βββ device/ # Device management framework
β β βββ include/ # π Device framework interfaces (DeviceManager, DriverRegistry, Bus, etc.)
β β β βββ driver/ # Concrete drivers (ns16550a_driver.hpp, virtio_blk_driver.hpp)
β β βββ device.cpp # Device initialization entry (DeviceInit)
β βββ 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)
βββ docs/ # π 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.
π― Learning Path
We recommend learning and implementing modules in the following order:
Phase 1: Infrastructure (Boot)
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| Early Console | src/arch/arch.h comments | β | Earliest output, understand global construction |
| Serial Driver | ns16550a_driver.hpp | ββ | Implement Probe/Remove, understand device framework and 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 |
Phase 2: Interrupt System
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| Interrupt Base | interrupt_base.h | ββ | Understand unified interrupt abstraction |
| Interrupt Controller | Per-arch driver headers | βββ | GIC/PLIC hardware programming |
| Timer Interrupt | arch.h β TimerInit | ββ | Timer configuration, tick-driven |
Phase 3: Memory Management
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| Virtual Memory | virtual_memory.hpp | βββ | Page table management, address mapping |
| Physical Memory | Related interfaces | βββ | Frame allocator, buddy system |
Phase 4: Task Management (Thread/Task)
| 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 |
Phase 5: System Calls
| Module | Interface File | Difficulty | Description |
|---|---|---|---|
| System Calls | arch.h β SyscallInit | βββ | User/kernel mode switching |
π¦ Third-Party Dependencies
| 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 |
| MRNIU/bmalloc | Memory allocator |
| MRNIU/MPMCQueue | Lock-free MPMC queue |
| MRNIU/device_framework | Device management framework |
π Development Guide
π¨ Code Style
- 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
Naming Conventions
| 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 | libc: sk_ prefix, libcxx: kstd_ prefix | sk_stdio.h / kstd_vector |
π Git Commit Convention
<type>(<scope>): <subject>
type: feat|fix|docs|style|refactor|perf|test|build|revert
scope: optional, affected module (arch, device, libc)
subject: max 50 chars, no period
π Documentation
- Toolchain: docs/0_ε·₯ε ·ιΎ.md
- System Boot: docs/1_η³»η»ε―ε¨.md
- Debug Output: docs/2_θ°θ―θΎεΊ.md
- Interrupts: docs/3_δΈζ.md
- Dev Container: docs/docker.md
- Interface Refactoring Plan: docs/TODO_interface_refactor.md
π€ Contributing
We welcome all forms of contributions!
π― Ways to Contribute
| 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 |
π§ Code Contribution Workflow
- 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
π License
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!
π Star the Project β’ π Report Issues β’ π¬ Join Discussions