feature: add mkdocs-material documentation site with CI deployment
Generate comprehensive documentation for all 173 source units and integrate mkdocs-material into the build toolchain. Documentation covers kernel core, x86 architecture, drivers, applications, and all subsystems with a tabbed navigation structure. - Add mkdocs.yml with material theme, mermaid support, and tabbed nav - Add doc/index.md landing page - Generate doc/src/ markdown for every Pascal unit in src/ - Reorganize planning docs into doc/planning/ - Add compat, lvglh, and toolchain doc sections - Update Dockerfile to install python3 and mkdocs-material (pinned <2) - Replace pasdoc-based compile_docs.sh with mkdocs build --strict - Add compile_docs.sh to the main build pipeline in compile.sh - Add deploy-docs step in .drone.yml with host volume mount to nginx - Add site/.gitkeep for build output directory
This commit is contained in:
1 parent
7157a57513
commit
26e2fd947e
209 files changed
+16996
-13
No files matched your search
@@ -0,0 +1,137 @@
|
||||
# memory.heap
|
||||
|
||||
Bitmap-based kernel heap allocator providing `kalloc`, `kfree`, and large-allocation support.
|
||||
|
||||
## Overview
|
||||
|
||||
`memory.heap` implements the Asuro logical memory manager (LMM). The heap is organized as a singly/doubly-linked list of 4 MiB virtual pages, each managed by a bitmap that tracks 8-byte allocation units.
|
||||
|
||||
Each heap page has the following layout:
|
||||
|
||||
| Region | Offset | Size |
|
||||
|---|---|---|
|
||||
| `THeapPageHeader` | `0x000000` | 24 bytes |
|
||||
| Bitmap | `0x000018` | 64,512 bytes (516,096 bits) |
|
||||
| Padding | `0x00FC18` | 1,000 bytes |
|
||||
| Data area | `0x010000` | 4,128,768 bytes (516,096 units × 8 bytes) |
|
||||
|
||||
Every allocation is preceded by a 16-byte prefix: 4 bytes for the unit count, 12 bytes of padding. This ensures the returned pointer is 16-byte aligned (required for SSE 128-bit operations) and allows `kfree` to recover the allocation size without a separate metadata structure.
|
||||
|
||||
Allocations larger than a single heap page's capacity are handled by `klalloc`, which maps contiguous virtual pages and stores a magic sentinel (`$FFFFFFFE`) in the header so `kfree` can identify them and call `klfree` instead of the normal bitmap path.
|
||||
|
||||
`kalloc` and `kfree` disable interrupts for the duration of their critical sections using a stack-balanced `pushfd`/`cli`/`pop` sequence and restore the interrupt flag via `restore_if` on all exit paths.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `arch.x86.memory.physical`
|
||||
- `arch.x86.memory.virtual`
|
||||
- `io.syslog`
|
||||
- `debug.tracer`
|
||||
- `core.util`, `arch.x86.util`
|
||||
- `core.panic`
|
||||
|
||||
## Constants
|
||||
|
||||
| Constant | Value | Description |
|
||||
|---|---|---|
|
||||
| `ALLOC_UNIT` | `8` | Bytes per allocation unit |
|
||||
| `DATA_OFFSET` | `$10000` (64 KiB) | Offset from page base to data area |
|
||||
| `PAGE_SIZE_LMM` | `$400000` (4 MiB) | Size of each heap virtual page |
|
||||
| `TOTAL_UNITS` | `516096` | Allocation units per page (`(PAGE_SIZE_LMM - DATA_OFFSET) / ALLOC_UNIT`) |
|
||||
| `BITMAP_DWORDS` | `16128` | 32-bit words required to hold the bitmap |
|
||||
| `SIZE_PREFIX` | `16` | Bytes prepended to every normal allocation |
|
||||
| `LARGE_ALLOC_MAGIC` | `$FFFFFFFE` | Sentinel written at offset +4 in `klalloc` headers |
|
||||
| `GUARD_MAGIC` | `$DEADBEEF` | Guard sentinel for overrun detection (debug builds only) |
|
||||
|
||||
## Types
|
||||
|
||||
### THeapPageHeader / PHeapPageHeader
|
||||
|
||||
```pascal
|
||||
THeapPageHeader = packed record
|
||||
NextPage : PHeapPageHeader;
|
||||
PrevPage : PHeapPageHeader;
|
||||
FreeUnits : uint32;
|
||||
NextFree : uint32;
|
||||
TotalUnits : uint32;
|
||||
Reserved : uint32;
|
||||
end;
|
||||
```
|
||||
|
||||
Located at the base address of each heap virtual page. `NextFree` is a roving hint that tracks the first bitmap index likely to contain free units, reducing average scan time for sequential allocations.
|
||||
|
||||
## Functions and Procedures
|
||||
|
||||
### init
|
||||
|
||||
```pascal
|
||||
procedure init;
|
||||
```
|
||||
|
||||
Allocates the first heap page via `new_heap_page`, sets `Root_Page` and `Search_Page` to it. Panics if the root page cannot be allocated.
|
||||
|
||||
### kalloc
|
||||
|
||||
```pascal
|
||||
function kalloc(size: uint32): void;
|
||||
```
|
||||
|
||||
Allocates `size` bytes from the heap. Returns a 16-byte-aligned pointer. Returns `nil` for zero-size requests. Delegates to `klalloc` for requests too large for a single page. Searches pages starting from `Search_Page` using the `NextFree` roving hint, allocating a new page if no existing page can satisfy the request. Calls `core.panic.panic` if the system is completely out of memory. The allocated region is zeroed before being returned.
|
||||
|
||||
### kfree
|
||||
|
||||
```pascal
|
||||
procedure kfree(area: void);
|
||||
```
|
||||
|
||||
Frees a previously allocated block. Detects large allocations by checking the magic sentinel at `area - 12` and delegates to `klfree` if found. For normal allocations, reads the unit count prefix, validates the range and double-free guard, clears the bitmap range, updates `FreeUnits` and `NextFree`, and calls `try_release_page` to return completely-free pages to the VMM.
|
||||
|
||||
### klalloc
|
||||
|
||||
```pascal
|
||||
function klalloc(size: uint32): void;
|
||||
```
|
||||
|
||||
Allocates `size` bytes by mapping contiguous virtual pages from the low virtual address range (page numbers 5 through `KERNEL_PAGE_NUMBER - 1`). Writes a header containing the page count and `LARGE_ALLOC_MAGIC` sentinel. Returns a pointer 16 bytes past the header. Returns `nil` if no contiguous range is available.
|
||||
|
||||
### klfree
|
||||
|
||||
```pascal
|
||||
procedure klfree(address: uint32);
|
||||
```
|
||||
|
||||
Frees a large allocation by reading the page count from the header at `address` and releasing each mapped virtual page back to the VMM. Validates the page count before proceeding.
|
||||
|
||||
### kpalloc
|
||||
|
||||
```pascal
|
||||
function kpalloc(address: uint32): void;
|
||||
```
|
||||
|
||||
Identity-maps a physical 4 MiB block at the specified address using `force_alloc_block` and `map_page`. Used for memory-mapped hardware regions that must appear at a fixed virtual address.
|
||||
|
||||
### lmm_total_free
|
||||
|
||||
```pascal
|
||||
function lmm_total_free: uint32;
|
||||
```
|
||||
|
||||
Returns the total free bytes across all heap pages by summing `FreeUnits * ALLOC_UNIT` for every page in the linked list.
|
||||
|
||||
### lmm_page_count
|
||||
|
||||
```pascal
|
||||
function lmm_page_count: uint32;
|
||||
```
|
||||
|
||||
Returns the number of heap pages currently in the linked list.
|
||||
|
||||
## Notes
|
||||
|
||||
The `restore_if` helper checks bit 9 (IF) of the saved EFLAGS word and issues `STI` only if interrupts were enabled on entry. It uses `STI` rather than `POPFD` to avoid restoring potentially dangerous EFLAGS bits (IOPL, NT, VM, AC) that could trigger a General Protection Fault or Bad-TSS on the next `IRET`.
|
||||
|
||||
When `DEBUG_LMM` is defined, `kalloc` allocates one additional unit and writes `GUARD_MAGIC` at the end of the allocation. `kfree` verifies this sentinel before freeing; a mismatch triggers a GPF with a syslog error, catching buffer overruns at free time.
|
||||
|
||||
Double-free detection uses `bitmap_all_set`: if any bit in the allocation's range is already clear at free time, the allocator logs an error and GPFs rather than silently corrupting the bitmap.
|
||||
|
||||
Fully empty pages (other than the root page) are returned to the VMM by `try_release_page`, which unlinks the page from the doubly-linked list and calls `arch.x86.memory.virtual.free_page_at_address`.
|
||||
Reference in new issue
Block a user