Fix PMM: switch to Multiboot2 boot protocol and add documentation (AI)
- Changed grub.cfg from 'multiboot' to 'multiboot2' command. The PMM parses Multiboot2 tag structures, but GRUB was booting with Multiboot1 protocol, causing the memory map parsing to silently fail (all memory stayed marked as used, leading to OOM on every allocation). - Fixed BITMAP_SIZE calculation to properly round up instead of truncating, ensuring the last few pages of the address space are covered. - Fixed sign comparison warning in bitmap init loop. - Added debug output to PMM init (mem_upper, region count) for diagnostics. - Removed stale Multiboot1 magic constant and (void)addr cast from kernel.c. - Added documentation for the interrupt subsystem and PMM in docs/. - Checked off 'Implement a PIC handler' and 'Create a physical memory allocator' in the task list. Tested: kernel boots in QEMU with both 4MB and 128MB RAM, PMM correctly allocates from NORMAL zone (0x01000000) and DMA zone (0x00001000).
This commit is contained in:
63
docs/pmm.md
Normal file
63
docs/pmm.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Physical Memory Manager (PMM)
|
||||
|
||||
## Overview
|
||||
|
||||
The PMM manages physical page frames using a bitmap allocator. It tracks which 4 KiB pages of physical RAM are free or in use, and supports allocating pages from different memory zones.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Bitmap Allocator
|
||||
|
||||
Each bit in a global bitmap corresponds to one 4 KiB physical page frame:
|
||||
- **Bit = 1** → page is in use (allocated or reserved)
|
||||
- **Bit = 0** → page is free
|
||||
|
||||
The bitmap covers the entire 32-bit physical address space (up to 4 GiB), requiring 128 KiB of storage in BSS.
|
||||
|
||||
### Memory Zones
|
||||
|
||||
The allocator supports zone-based allocation to satisfy constraints from different subsystems:
|
||||
|
||||
| Zone | Range | Purpose |
|
||||
|---|---|---|
|
||||
| `PMM_ZONE_DMA` | 0 – 16 MiB | ISA DMA-compatible memory |
|
||||
| `PMM_ZONE_NORMAL` | 16 MiB – 4 GiB | General-purpose allocation |
|
||||
|
||||
When `PMM_ZONE_NORMAL` is requested but no pages are available above 16 MiB (e.g., on systems with less than 16 MiB of RAM), the allocator falls back to `PMM_ZONE_DMA`.
|
||||
|
||||
Page 0 (address 0x00000000) is always marked as used to prevent returning NULL as a valid physical address.
|
||||
|
||||
### Initialization
|
||||
|
||||
1. The entire bitmap is initialized to "all used" (0xFFFFFFFF).
|
||||
2. The Multiboot2 memory map is parsed to discover available RAM regions.
|
||||
3. Available regions are marked as free in the bitmap.
|
||||
4. The kernel's own memory (between `_kernel_start` and `_kernel_end` linker symbols) is re-marked as used.
|
||||
5. The Multiboot2 info structure itself is marked as used.
|
||||
|
||||
### Linker Symbols
|
||||
|
||||
The linker script exports `_kernel_start` and `_kernel_end` symbols so the PMM knows which physical pages the kernel occupies and must not allocate.
|
||||
|
||||
## API
|
||||
|
||||
```c
|
||||
void init_pmm(uint32_t multiboot_addr);
|
||||
phys_addr_t pmm_alloc_page(pmm_zone_t zone);
|
||||
void pmm_free_page(phys_addr_t addr);
|
||||
```
|
||||
|
||||
- `init_pmm` — Parse Multiboot2 info and build the free-page bitmap.
|
||||
- `pmm_alloc_page` — Allocate a single 4 KiB page from the specified zone. Returns 0 on OOM.
|
||||
- `pmm_free_page` — Return a page to the free pool.
|
||||
|
||||
## Key Files
|
||||
|
||||
- `src/pmm.c` / `src/pmm.h` — Allocator implementation and zone definitions.
|
||||
- `src/linker.ld` — Exports `_kernel_start` / `_kernel_end`.
|
||||
|
||||
## Limitations
|
||||
|
||||
- First-fit allocation (linear scan) — O(n) per allocation.
|
||||
- No per-zone free counts or statistics yet.
|
||||
- Does not handle memory hot-plug or ACPI reclaim regions.
|
||||
Reference in New Issue
Block a user