Skip to main content
Aeolos is a x86_64 hobby operating system written in C and Assembly. The kernel follows a modular monolithic design with clear separation between subsystems.

System Components

The kernel is organized into several major subsystems:

Boot & Initialization

Stivale2 bootloader protocol, kernel entry point, and system initialization sequence

Memory Management

Physical Memory Manager (PMM) and Virtual Memory Manager (VMM) with paging support

Process Management

Task structures, scheduler, and multitasking implementation

Device Support

Framebuffer, serial port, and terminal drivers

Kernel Entry Point

The kernel begins execution in kmain() located in kernel/kmain.c:47. The initialization sequence follows a carefully ordered process:
kernel/kmain.c
_Noreturn void kmain(stivale2_struct* info)
{
    // convert the physical address to a virtual one, since we will be removing identity mapping later
    bootinfo = (stivale2_struct*)PHYS_TO_VIRT(info);

    // some info
    klog_printf("Aeolos x86_64 (alpha)\n");
    klog_printf("Built on "__DATE__" at "__TIME__".\n\n");

    idt_init();
    cpu_features_init();

    // system initialization
    pmm_init((stv2_struct_tag_mmap*)stv2_find_struct_tag(bootinfo, STV2_STRUCT_TAG_MMAP_ID));
    vmm_init();
    gdt_init();

    // initialize framebuffer and terminal
    fb_init((stv2_struct_tag_fb*)stv2_find_struct_tag(bootinfo, STV2_STRUCT_TAG_FB_ID));
    serial_init();
    term_init();

    // further system initialization
    acpi_init((stv2_struct_tag_rsdp*)stv2_find_struct_tag(bootinfo, STV2_STRUCT_TAG_RSDP_ID));
    hpet_init();
    apic_init();
    vfs_init();
    smp_init();

    // since we do not need the bootloader info anymore
    pmm_reclaim_bootloader_mem();

    // initialize multitasking
    sched_init(kinit);

    // DO NOT put anything here. Put it in kinit() instead

    while (true)
        ;
}

Initialization Phases

The kernel initialization follows these phases:

Phase 1: Core Initialization

  1. IDT Setup - Interrupt Descriptor Table initialization
  2. CPU Features - Detect and enable CPU features
  3. Memory Management - Initialize PMM and VMM
  4. GDT Setup - Global Descriptor Table initialization

Phase 2: Device Initialization

  1. Framebuffer - Initialize graphics output
  2. Serial Port - Enable serial communication
  3. Terminal - Set up terminal subsystem

Phase 3: System Services

  1. ACPI - Advanced Configuration and Power Interface
  2. HPET - High Precision Event Timer
  3. APIC - Advanced Programmable Interrupt Controller
  4. VFS - Virtual File System
  5. SMP - Symmetric Multiprocessing support

Phase 4: Multitasking

After reclaiming bootloader memory, the scheduler is initialized with kinit() as the first kernel task:
kernel/kmain.c
void kinit(tid_t tid)
{
    (void)tid;
    klog_show();
    klog_ok("first kernel task started\n");

    initrd_init((stv2_struct_tag_modules*)stv2_find_struct_tag(bootinfo, STV2_STRUCT_TAG_MODULES_ID));

    // Test VFS functionality
    klog_printf("\n");
    char buff[4096] = { 0 };
    vfs_handle_t fh = vfs_open("/docs/test.txt", VFS_MODE_READ);
    klog_info("reading \"/docs/test.txt\":\n\n");
    int64_t nb = vfs_read(fh, 4096, buff);
    klog_printf("%s\n", buff, nb);
    klog_info("bytes read: %d\n", nb);
    vfs_close(fh);

    vfs_debug();
    pmm_dumpstats();

    klog_warn("This OS is a work in progress. The computer will now halt.");
    sched_kill(tid);
}
The kmain() function never returns. After sched_init(), code should be placed in kinit() instead, as indicated by the comment in the source.

Memory Layout

Aeolos uses a higher-half kernel design:
  • Higher Half Offset: 0xFFFFFFFF80000000 - Kernel code and data mapped here
  • Physical Memory: 0xFFFF800000000000 - All physical memory mapped to this virtual base
  • Page Size: 4096 bytes (4 KiB)
The kernel transitions from bootloader-provided identity mapping to its own paging structures during initialization.

Design Philosophy

Each subsystem is self-contained with clear interfaces. Memory management, process management, and device drivers are cleanly separated.
The kernel converts bootloader-provided physical addresses to virtual addresses early to prevent issues when identity mapping is removed.
Bootloader memory is reclaimed after initialization. Dead tasks are cleaned up by a dedicated janitor task.

Key Constants

ConstantValueDescription
PAGE_SIZE4096Standard page size in bytes
KSTACK_SIZE4096Kernel stack size per task
TID_MAX65536Maximum number of tasks
CPU_MAXVariesMaximum supported CPUs

Next Steps

Boot Process

Learn about the Stivale2 boot protocol and kernel initialization

Memory Management

Explore PMM and VMM implementation details

Build docs developers (and LLMs) love