|
miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
|
#include <miniOS/types.h>

Go to the source code of this file.
Functions | |
| void | pmm_init (uint64_t mb_info_phys) |
| uint64_t | pmm_alloc_frame (void) |
| void | pmm_free_frame (uint64_t phys) |
| uint64_t | pmm_free_count (void) |
| uint64_t | pmm_total_count (void) |
| uint64_t | pmm_alloc_contiguous (size_t n_frames) |
| void | pmm_free_contiguous (uint64_t phys, size_t n_frames) |
| void | pmm_ref_frame (uint64_t phys) |
| void | pmm_unref_frame (uint64_t phys) |
pmm_alloc_contiguous() - Allocate @n_frames physically contiguous 4 KiB frames. @n_frames: Number of frames required (must be > 0 and a power of 2 for DMA use).
Linear bitmap scan — O(n). Suitable for infrequent DMA allocations (virtqueues, DMA buffers). For single-frame allocations prefer pmm_alloc_frame().
pmm_alloc_contiguous() - Allocate n_frames physically contiguous frames. @n_frames: Number of consecutive 4 KiB frames required (must be > 0).
Linear scan for the first run of n_frames consecutive free bits. O(n) in the bitmap size — suitable for infrequent DMA allocations.


| uint64_t pmm_alloc_frame | ( | void | ) |
pmm_alloc_frame() - Allocate a free 4 KiB physical frame.
Scans the bitmap for the first non-zero byte (O(1) amortized), then finds the lowest set bit within it. Marks the frame USED (bit=0) and decrements the total_free counter. Frame 0 is never returned (permanently marked USED).
Context: May be called from any non-ISR context. Not ISR-safe.
pmm_alloc_frame() - Return the physical address of a free frame.
Linear scan of g_pmm_bitmap looking for any non-zero byte. Within the found byte, bit-scans to the lowest set bit, clears it (USED), and returns frame_idx * PAGE_SIZE.


pmm_free_contiguous() - Return @n_frames contiguous frames to the free pool. @phys: Physical address of the first frame (PAGE_SIZE-aligned). @n_frames: Number of frames to release.
pmm_free_contiguous() - Return n_frames contiguous frames to the free pool. @phys: Physical address of the first frame (4 KiB-aligned). @n_frames: Number of frames to free.


| uint64_t pmm_free_count | ( | void | ) |
pmm_free_count() - Query the number of currently free physical frames.
Returns the total_free counter maintained incrementally by pmm_alloc_frame and pmm_free_frame. O(1) — does not scan the bitmap.
pmm_free_count() - Return the number of free frames.

| void pmm_free_frame | ( | uint64_t | phys | ) |
pmm_free_frame() - Return a physical frame to the free pool. @phys: Physical address of the frame to free (must be 4 KiB-aligned).
Marks the frame FREE (bit=1) and increments total_free. Guards against double-free: if the frame is already free, the call is a no-op. Frame 0 must never be freed (permanently reserved).
pmm_free_frame() - Mark a physical frame as free. @phys: Physical address of frame (4 KiB-aligned).
Guards against double-free: if the bit is already set, returns without modifying total_free.


| void pmm_init | ( | uint64_t | mb_info_phys | ) |
pmm_init() - Initialise the physical memory manager from Multiboot 2 info. @mb_info_phys: Physical address of the Multiboot 2 information structure.
Parses memory map tags from the Multiboot 2 structure to identify available RAM regions. Marks all available frames FREE in the bitmap (bit=1 means FREE). Explicitly marks frame 0 as USED. Kernelimage frames are also marked USED to prevent the PMM from returning kernel memory.
Context: Must be called once at boot before any call to pmm_alloc_frame.
pmm_init() - Parse Multiboot 2 memory map and initialise the bitmap. @mb_info_phys: Physical address of MB2 struct; KERNEL_VMA added internally.
Two-pass init: Pass 1 — scan mmap to find the highest available physical address, then size and place the bitmap in physical RAM right after the kernel image (within the boot identity map, so the virtual address phys+KERNEL_VMA is immediately valid). Pass 2 — mark available regions free; mark kernel+bitmap frames used.
For a 64 MiB VM the bitmap is ~2 KiB instead of the 128 KiB that a static 4 GiB-ceiling array would require.


| void pmm_ref_frame | ( | uint64_t | phys | ) |
pmm_ref_frame() - Add an extra owner to an already-allocated frame. @phys: Physical address of the frame (must have been returned by pmm_alloc_frame(), which starts every frame's refcount at 1).
Used when a frame becomes shared between two page tables (fork CoW: a read-only text page or a CoW-pending writable page shared between parent and child). Increments the frame's refcount; does not touch the bitmap.
pmm_ref_frame() - Add an extra owner to an already-allocated frame.

| uint64_t pmm_total_count | ( | void | ) |
pmm_total_count() - Query the total number of physical frames discovered at boot.
Returns total_frames, incremented once per frame during pmm_init(). Does not change after boot. O(1).

| void pmm_unref_frame | ( | uint64_t | phys | ) |
pmm_unref_frame() - Drop one owner of a frame; frees it at refcount 0. @phys: Physical address of the frame.
Decrements the frame's refcount. If it reaches 0, the frame is returned to the free pool exactly as pmm_free_frame() would. Safe to call on a frame with refcount 1 (behaves like pmm_free_frame()) — this is the normal case for private (non-CoW-shared) pages.
pmm_unref_frame() - Drop one owner of a frame; frees it at refcount 0.

