This commit is contained in:
boreddevnl
2026-03-16 10:23:40 +01:00
parent d01c309166
commit b427b1d4ac
13 changed files with 464 additions and 87 deletions

39
docs/architecture/core.md Normal file
View File

@@ -0,0 +1,39 @@
# Core Architecture
BoredOS is a 64-bit hobbyist operating system designed for the x86_64 architecture. While it features kernel-space drivers and a built-in window manager, it supports fully-isolated userspace applications and includes a networking stack.
This document serves as an overview of the core architecture and the layout of the kernel source code.
## Source Code Layout (`src/`)
The OS heavily relies on module separation. The `src/` directory is logically split into several domains:
- **`arch/`**: Contains the assembly routines needed for bootstrapping the system (`boot.asm`) and setting up the CPU state for userland execution (`process_asm.asm`). It also handles architecture-specific mechanisms like the Global Descriptor Table (GDT) and Interrupt Descriptor Table (IDT).
- **`core/`**: The initialization sequence of the OS lives here. `main.c` is the entry point from the bootloader. This directory also contains essential kernel utilities (`kutils.c`), panic handlers (`panic.c`), and built-in command parsing logic (`cmd.c`).
- **`dev/`**: Device drivers. This includes the PCI scanner, disk management infrastructure, input drivers (keyboard and mouse), and the Real Time Clock (RTC).
- **`fs/`**: Filesystem implementations. The system uses a Virtual File System (VFS) abstraction alongside an in-memory FAT32 filesystem with support for drives over ATA that are formatted as FAT32 (plain/MBR).
- **`mem/`**: Physical and virtual memory management. It controls page frame allocation, paging, and kernel heap operations.
- **`net/`**: The networking stack. BoredOS relies on `lwIP` for processing IPv4 and TCP/UDP traffic, interacting with a range of NICs via `net/nic/`.
- **`sys/`**: System calls and process management. The ELF loader resides here, parsing userland binaries and setting them up for execution.
- **`wm/`**: The graphical subsystem. It handles drawing primitives, window structures, font rendering, and double-buffering.
- **`userland/`**: Out-of-kernel components. This includes the custom SDK/compiler environment (`libc/`) and user applications (`cli/`, `gui/`, `games/`).
## Boot Process
BoredOS uses **Limine** as its primary bootloader.
1. **Limine Initialization**: The machine firmware (BIOS or UEFI) loads Limine. Limine parses `limine.conf`, sets up an early graphical framebuffer, and reads the kernel ELF file into memory.
2. **Multiboot2 Protocol**: The kernel expects the Limine boot protocol (which is compatible with modern Multiboot specifications). Passing a framebuffer and memory map is handled natively by Limine's request structures (defined locally via `limine.h`).
3. **Kernel Entry (`main.c`)**: The entry point `_start` is called. It immediately initializes the serial port for debugging, sets up core structures (GDT/IDT), initializes the physical memory manager based on the Limine memory map, and starts the virtual memory manager.
4. **Driver Initialization**: PCI buses are scanned, finding the network card or disk controllers. The filesystem is mounted.
5. **Window Manager**: The UI is drawn on top of the Limine-provided framebuffer.
## Userland Transition
The OS supports privilege separation (Ring 0 vs. Ring 3). When an application (like `browser.elf` or `viewer.elf`) is launched, the kernel:
1. Loads the ELF file from the filesystem using the ELF parser in `sys/elf.c`.
2. Allocates a new virtual address space (Page Directory) for the process.
3. Maps the executable segments according to the ELF headers.
4. Switches to User Mode (Ring 3) via the `iretq` instruction, jumping into the application's entry point (`crt0.asm`).
Programs then interact with the core kernel using system calls (`syscall.c`).

View File

@@ -0,0 +1,28 @@
# Filesystem Architecture
BoredOS implements a rudimentary but functional filesystem layer designed to support reading system assets and user applications during runtime.
## Virtual File System (VFS)
The Virtual File System acts as an abstraction layer across different underlying storage mechanisms (even if, currently, only one type is fully utilized). System calls targeting files (`SYS_FS`) route through the VFS rather than interacting with the disk directly.
Key VFS functionalities include:
- **File Descriptors**: Mapping integer IDs to internal file structures for userland processes.
- **Standard Operations**: Standardizing `open()`, `read()`, `write()`, `close()`, `seek()`, and directory listings.
- **Path Parsing**: Resolving absolute and relative paths.
## FAT32 Implementation
The primary filesystem logic in `fat32.c` has a dual nature, supporting both an in-memory RAM filesystem for booting and standard block devices for external storage.
### Booting and the RAMFS
Since BoredOS boots from a CD-ROM ISO image generated by `xorriso`, it does not read directly off the CD to execute applications.
1. **ISO Booting**: During boot, Limine loads necessary files (such as userland `.elf` binaries, fonts, and wallpapers) into memory as standard boot modules.
2. **RAM Simulation**: The FAT32 filesystem code parses these loaded memory modules and automatically constructs a synthetic FAT32 directory tree inside RAM.
3. **Root Filesystem**: All active execution of built-in GUI and CLI apps occurs off this read-only, in-memory FAT32 simulation.
### ATA Disk Support
Beyond the core RAMFS used for booting, the FAT32 implementation natively supports interacting with permanent storage:
1. **ATA Block Driver**: The kernel features an ATA block device driver capable of communicating with physical hard disks (or raw disk images attached via QEMU).
2. **Partition Compatibility**: The driver can recognize and natively mount external ATA disks formatted as single FAT32 filesystems or structured with a Master Boot Record (MBR) partition table.
3. **VFS Integration**: When external storage is mounted, the VFS delegates operations down directly to the FAT32 driver, which will read native sectors across the ATA interface.

View File

@@ -0,0 +1,23 @@
# Memory Management
Memory management in BoredOS is split into physical and virtual layers, designed to support both kernel operations and userland isolation on the x86_64 architecture.
## Physical Memory Management (PMM)
The PMM is responsible for tracking which physical RAM frames (usually 4KB each) are free and which are in use.
1. **Memory Map**: During boot, Limine provides a memory map detailing the available, reserved, and unusable physical memory regions.
2. **Bitmap Allocator**: The core PMM uses a bitmap-based allocation strategy. Each bit in the bitmap represents a single physical page (frame). If a bit is `1`, the page is in use; if `0`, it is free.
3. **Allocation**: When a new page is requested (e.g., for userland space or kernel heap), the PMM scans the bitmap for the first available zero bit, marks it as used, and returns the physical address.
## Virtual Memory Management (VMM) and Paging
BoredOS uses 4-level paging (PML4), a requirement for x86_64 long mode, dividing the virtual address space between the kernel and userland.
- **Kernel Space**: The kernel relies on a higher-half design where its code, data, and heap are mapped to high addresses (typically above `0xFFFF800000000000`). This ensures the kernel remains mapped and accessible regardless of which user process is currently active.
- **User Space**: Userland applications are loaded into lower virtual addresses (starting frequently around `0x40000000`).
- **Page Faults**: The `mem/` subsystem registers an Interrupt Service Routine (ISR) for page faults (Interrupt 14). If a process accesses unmapped memory, the handler determines whether to allocate a new frame (e.g., for stack growth or lazy loading) or terminate the process for a segmentation fault.
## Kernel Heap
Dynamic allocation within the kernel (`kmalloc` and `kfree`) is layered on top of the physical allocator. The kernel maintains its own heap area in virtual memory. When the heap requires more space, it requests physical frames from the PMM and maps them into the kernel's virtual address space using the VMM.

View File

@@ -0,0 +1,33 @@
# Window Manager (WM)
BoredOS features a fully custom, graphical Window Manager built directly into the kernel, residing in the `src/wm/` directory. It is responsible for compositing the screen, handling window logic, rendering text, and dispatching UI events.
## Framebuffer and Rendering
1. **Limine Framebuffer**: During boot, the Limine bootloader requests a graphical framebuffer from the hardware (e.g., GOP in UEFI environments) and passes a pointer to this linear memory buffer to the kernel.
2. **Double Buffering**: To prevent screen tearing, the WM does not draw directly to the screen. It allocates a "back buffer" in kernel memory equal to the size of the screen. All drawing operations (lines, rectangles, windows) happen on this back buffer.
3. **Compositing**: Once per frame or upon request, the entire back buffer (or dirty regions) is copied to the actual Limine physical framebuffer memory, making the changes visible instantly.
## Window System (`wm.c`)
The windowing system is built around a linked list of `Window` structures.
- **Z-Ordering**: The list determines the draw order. Windows at the back of the list are drawn first, and the active window is drawn last (on top).
- **Window Structures**: Each window object tracks its dimensions (`x`, `y`, `width`, `height`), title, background color, and an internal buffer if it's acting as a canvas for userland apps.
- **Decorations**: The kernel handles drawing window borders, title bars, and close buttons automatically unless a borderless style is specified.
## Input Handling and Events
The WM acts as the central hub for input routing.
1. **Mouse Driver**: The PS/2 mouse driver (`dev/mouse.c`) detects movement and button clicks. It raises interrupts that update global cursor coordinates.
2. **Hit Testing**: The WM checks these coordinates against the bounding boxes of existing windows. It handles dragging logic (if the user clicks a title bar) or focus changes.
3. **Event Queue**: If a userland application owns the window that was clicked, the WM packages the input (coordinates, button state) into an event message and drops it into the owning process's event queue. The application can retrieve these via the custom libc UI functions.
## Userland API (`libui.c`)
Applications do not talk to the hardware directly. Instead, they use a library (`libui.c`) which makes specialized system calls (`SYS_GUI`).
- **Window Creation**: `ui_create_window()` asks the kernel to instantiate a new window object and returns a handle.
- **Drawing**: Applications can request the kernel to fill rectangles or plot pixels inside their designated window area.
- **Event Polling**: The UI loop inside an app continuously calls `ui_poll_event()` to respond to mouse clicks and window movement dispatched by the kernel WM.