IgrOS-Kernel is a hobby operating system kernel written in modern C++20 with a thin layer of assembly. It boots via Multiboot (GRUB) on i386 and x86_64, sets up the CPU (GDT, IDT, exceptions, interrupts, paging), manages physical memory and drives basic PC hardware: VGA text mode, serial port, PIT timer, keyboard and CMOS clock.
| CI/CD | |
| Codacy | |
| SonarCloud |
| Area | Implemented | Planned |
|---|---|---|
| Boot | Multiboot (GRUB), protected mode (i386), long mode switch (x86_64) | Multiboot 2, custom bootloader |
| CPU | GDT, IDT, exceptions, hardware interrupts (8259 PIC) | APIC |
| Memory | Physical page allocator, paging | Virtual memory allocator |
| Drivers | VGA text mode, serial port (UART), keyboard (read), CMOS RTC (read), PIT timer (off by default) | Loadable kernel drivers |
| User space | User mode, user programs, GUI |
Linux host with:
- CMake 3.21+ and Ninja
- Clang + LLD, or GCC with multilib
- GRUB tools:
grub-mkrescue(grub-common,grub-pc-bin),xorriso,mtools - QEMU (
qemu-system-x86) to run; BOCHS optionally
On Ubuntu:
sudo apt install ccache clang cmake g++-multilib gcc-multilib grub-common grub-pc-bin lld mtools ninja-build qemu-system-x86 xorrisoBuild, run and test scripts take <i386|x86_64> [clang++|g++] [debug|release] (defaults: clang++ debug).
# Build bootable ISO
config/script/build.sh x86_64
# Run in QEMU (serial output in terminal)
config/script/run-qemu.sh x86_64
# Run in BOCHS
config/script/run-bochs.sh x86_64
# Host unit tests + QEMU boot test
config/script/test.sh x86_64
# Remove build artifacts
config/script/clean.shThe ISO is placed at install/<Debug|Release>/config-linux-<compiler>-<arch>-<type>/kernel.iso.
You can also build with CMake presets directly:
cmake --preset config-linux-clang++-x86_64-debug
cmake --build --preset build-linux-clang++-x86_64-debug --target installThe image contains only the toolchain; sources are mounted from the host, so code changes don't require rebuilding it:
docker compose up kernel_x86_64_clang_build # also: kernel_i386_clang_build, kernel_{i386,x86_64}_gcc_buildThe analysis image adds analyzers, gcovr, QEMU and CodeQL to the toolchain and runs all analysis at once:
docker compose run --rm kernel_analysis # all four configs
docker compose run --rm kernel_analysis g++:x86_64 # or some of them- Unit tests – host-compiled tests of kernel library, memory, interrupts, paging, drivers and multiboot code for both architectures' code paths, in
tests/. Assembly functions (port I/O, control registers, CPU halt) are replaced with fake hardware (tests/hw.hpp):cmake -S tests -B build/tests -G Ninja -DIGROS_TEST_ARCH=x86_64 [-DIGROS_TESTS_COVERAGE=ON] cmake --build build/tests ctest --test-dir build/tests --output-on-failure - Boot test –
tests/boot/qemu-boot.shboots the ISO in QEMU and checks that the kernel reaches the end ofkmainand handles a keyboard IRQ.
GitHub Actions and GitLab CI run both for every compiler/architecture combination; Azure Pipelines runs the boot test.
Coverage is reported to Codacy and SonarCloud. Locally, a coverage build of the tests has a coverage target (needs gcovr), HTML report in build/tests/reports/coverage/.
cmake/modules/EnableAnalysis.cmake adds options and on-demand report targets to the kernel build (reports go to <build dir>/reports/):
| Option / target | What it does |
|---|---|
IGROS_CXX_CLANG_TIDY=ON |
ClangTidy pass during the build |
IGROS_CXX_STRICT_WARNINGS=ON |
Extra warnings (-Wconversion, -Wshadow, -Wold-style-cast, -Wframe-larger-than=1024...), reported but not fatal |
IGROS_KERNEL_UBSAN=ON |
UndefinedBehaviorSanitizer in trap mode: UB raises #UD (vector 6), no runtime library needed |
--target clang-tidy |
ClangTidy over all C++ sources with .clang-tidy checks → clang-tidy-report.txt (needs run-clang-tidy) |
--target cppcheck |
Cppcheck over the compile database (inconclusive, exhaustive) → cppcheck-report.txt |
--target codeql |
CodeQL database from a separate clean build → codeql-results.sarif (needs codeql CLI) |
--target compiler-warnings |
Compiler diagnostics of all C++ sources, recompiled to a temporary directory → compiler-warnings.txt |
--target analysis-report |
HTML page with findings of the reports above → index.html (needs Python 3) |
cmake --preset config-linux-clang++-x86_64-debug -DIGROS_KERNEL_UBSAN=ON
cmake --build --preset build-linux-clang++-x86_64-debug --target cppcheckconfig/script/analysis.sh runs everything for all (or given) configs: a debug build with strict warnings and UBSan, QEMU boot test, all report targets (CodeQL for the first config only, IGROS_ANALYSIS_CODEQL=all|none to change), host tests coverage. The report in build/analysis/index.html merges findings of every tool and config (the same issue reported by several tools or configs is one entry), shows them per file with source lines, build and boot status per config and coverage.
An open report page updates itself whenever the report is regenerated (it reloads index.data.js), also while analysis.sh is still running.
In CI the Analysis workflow runs analysis.sh (CodeQL goes to code scanning instead) and publishes the page on GitHub Pages: master at igr2014.github.io/IgrOS-Kernel, each pull request under pr/<number>/ with a summary comment in the PR (removed when it is closed). The code is kept free of findings, so any finding fails the workflow (after the report is published), as do a config that doesn't build or boot and failing host tests. A finding that doesn't apply is suppressed where it is, with a reason (// NOLINT(<check>): <reason>, // cppcheck-suppress <id>); a check that doesn't fit the kernel at all is disabled in .clang-tidy with the reason next to it.
A UBSan trap before the IDT is loaded ends in a triple fault without a message. analysis.sh resolves it into the report; by hand, boot with qemu-system-x86_64 ... -no-reboot -d int, take IP= of the v=06 line and resolve it with addr2line -f -C -i -e kernel.bin <IP>.
ASan and gcov coverage need a hosted runtime the kernel doesn't have: coverage comes from the host unit tests, SonarCloud and Codacy run in CI.
| Directory | Contents |
|---|---|
arch/ |
CPU support: common x86 code and i386 / x86_64 boot code, GDT, IDT |
drivers/ |
VGA, serial (UART), PIT, CMOS RTC, keyboard |
klib/ |
Freestanding kernel library: memory, strings, printing, math |
mem/ |
Physical memory allocator |
multiboot/ |
Multiboot information parsing |
platform/ |
Platform initialization |
dev/, sys/ |
Device abstraction, ELF definitions |
config/ |
Build/run scripts, linker scripts, CMake toolchain configs |
tests/ |
Unit and boot tests |
kmain.cpp |
Kernel entry point |
See CONTRIBUTING.md and the Code of Conduct.
The repository is mirrored on GitHub, GitLab and Azure DevOps.
MIT © 2017 - 2026 Igor Baklykov