Skip to content

Commit ecfb6b1

Browse files
comments
1 parent 7cb20fe commit ecfb6b1

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

include/kernel.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,47 @@ struct reqset {
9595
size_t count;
9696
};
9797

98+
/**
99+
* @brief Called on network up
100+
*/
98101
void network_up();
102+
103+
/**
104+
* @brief Called on network down
105+
*/
99106
void network_down();
107+
108+
/**
109+
* @brief Verify that Limine's GDT and CR3 are sane, and provide
110+
* the expected identity map. Also record the value of gdtr.base
111+
* and CR3 so we can exclude it from BLR reclaim.
112+
*/
100113
void validate_limine_page_tables_and_gdt(void);
114+
115+
/**
116+
* @brief Collects and returns all bootloader response pointers we must preserve.
117+
*
118+
* @details
119+
* Builds a `reqset` structure containing the runtime addresses of all Limine
120+
* request/response pairs and other critical early-boot pointers (e.g. GDT base,
121+
* CR3). These addresses are used during heap initialisation to ensure that
122+
* **Bootloader Reclaimable** memory ranges containing live data structures are
123+
* not erroneously freed back into the general allocator.
124+
*
125+
* By centralising this list, the heap code can simply check each BLR span for
126+
* membership and decide whether to keep or reclaim it.
127+
*
128+
* @return
129+
* A `reqset` with:
130+
* - `count` = number of tracked pointers.
131+
* - `ptrs[]` = array of the addresses to preserve.
132+
*
133+
* @note
134+
* - The values in this set are not compile-time constants; they are filled
135+
* at runtime once the bootloader has populated its responses.
136+
* - Call this only after the Limine hand-off has occurred, typically during
137+
* or just before `init_heap()`.
138+
*/
101139
struct reqset request_addresses(void);
102140

103141
#ifdef PROFILE_KERNEL

include/kmalloc.h

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,60 @@
1313
#include <stddef.h>
1414

1515
/**
16-
* @brief Initialise the kernel heap.
17-
*
18-
* Sets up internal data structures required for dynamic memory allocation.
19-
* Should be called early during kernel initialisation.
16+
* @brief Initialises the kernel’s dynamic memory and DMA-friendly “low heap”.
17+
*
18+
* @details
19+
* `init_heap()` brings up two complementary allocation domains and reconciles the
20+
* bootloader’s memory hand-off into something the kernel can safely and efficiently
21+
* allocate from:
22+
*
23+
* 1) **Low heap (fixed, DMA-friendly window).**
24+
* - Automatically locates a *contiguous 12 MB* region of **USABLE** RAM below 4 GiB
25+
* and assigns it to `LOW_HEAP_START` / `LOW_HEAP_MAX` (both `uint32_t`).
26+
* - This window is reserved exclusively for the bump allocator used by
27+
* `kmalloc_low()` and returns **32-bit physical addresses** suitable for legacy
28+
* devices and DMA engines that cannot address high memory.
29+
* - The low-heap window is deliberately **excluded** from the general allocator to
30+
* avoid fragmentation and to guarantee that drivers always have the expected
31+
* 12 MB of low physical memory available.
32+
*
33+
* 2) **General heap (primary + additional regions).**
34+
* - Chooses the *largest* **USABLE** memmap entry as the primary arena and
35+
* initialises the general allocator (`ta_init`) over it, **carving out** the
36+
* low-heap window if they overlap.
37+
* - Iterates over all remaining **USABLE** entries and adds them with
38+
* `ta_add_region`, again **clipping out** the low-heap window so it is never
39+
* accidentally pooled into the general heap.
40+
*
41+
* 3) **Selective reclamation of bootloader allocations.**
42+
* - Walks all **Bootloader Reclaimable** (BLR) entries and returns them to the
43+
* general heap *except* when either of the following is true:
44+
* • the region is “small” (currently < 1 MB), which typically holds loader
45+
* scaffolding such as page tables, descriptor tables, or tiny request
46+
* structs; or
47+
* • the region contains any *live* pointer supplied by the bootloader
48+
* (e.g., Limine response structures, GDT base, CR3), in which case the
49+
* whole BLR span is kept.
50+
* - This yields the large BLR “scratch” arenas while conservatively preserving
51+
* small or still-referenced chunks. The result is that almost all of the
52+
* bootloader’s memory footprint becomes usable to the kernel immediately.
53+
*
54+
* **What is *not* added to the general heap**
55+
* - **Kernel+Modules** regions (the kernel image and loaded modules).
56+
* - The **Framebuffer** region.
57+
* - Any **ACPI NVS**, **ACPI Reclaimable**, **Bad Memory** or **Reserved** ranges.
58+
*
59+
* **Why this design?**
60+
* - The low heap provides a guaranteed, contiguous, sub-4 GB pool for drivers and
61+
* DMA without requiring the kernel to juggle bounce buffers or IOMMU mappings.
62+
* - Carving the low heap out once, and everywhere, prevents subtle re-introduction
63+
* into the general allocator.
64+
* - Conservative BLR reclamation gives you back the big win (hundreds of MB on
65+
* typical firmware) with minimal complexity, while avoiding the risk of freeing
66+
* loader memory that is still referenced during early boot.
67+
*
68+
* Should be called **once**, early in kernel initialisation, before any dynamic
69+
* memory use by subsystems or drivers.
2070
*/
2171
void init_heap(void);
2272

0 commit comments

Comments
 (0)