Implement paging subsystem with identity mapping and kernel heap (AI)
- Created two-level x86 paging (page directory + page tables) with 4 KiB pages.
- Identity maps all detected physical memory in two phases:
1) Static: first 16 MiB using 4 BSS-allocated page tables (avoids
chicken-and-egg with PMM bitmap in BSS).
2) Dynamic: memory above 16 MiB using PMM-allocated page tables,
created before paging is enabled so physical addresses still work.
- Provides kernel heap at 0xD0000000–0xF0000000 for virtual page allocation.
- API: paging_map_page, paging_unmap_page, paging_alloc_page, paging_free_page,
paging_get_physical.
- Added pmm_get_memory_size() to expose detected RAM for paging init.
- Kernel tests paging by allocating a virtual page, writing 0xDEADBEEF, and
reading it back, then freeing it.
- Added documentation in docs/paging.md.
Tested: boots and passes paging test with both 4 MiB and 128 MiB RAM in QEMU.
This commit is contained in:
75
docs/paging.md
Normal file
75
docs/paging.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Paging Subsystem
|
||||
|
||||
## Overview
|
||||
|
||||
The paging subsystem manages virtual memory using the x86 two-level paging scheme (no PAE). It provides identity mapping for all physical memory and a kernel heap region for dynamic virtual page allocation.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Page Table Structure
|
||||
|
||||
x86 32-bit paging uses two levels:
|
||||
|
||||
| Level | Entries | Each Entry Maps | Total Coverage |
|
||||
|---|---|---|---|
|
||||
| Page Directory | 1024 | 4 MiB (one page table) | 4 GiB |
|
||||
| Page Table | 1024 | 4 KiB (one page) | 4 MiB |
|
||||
|
||||
Each entry is a 32-bit value containing a 20-bit physical page frame number and 12 bits of flags.
|
||||
|
||||
### Identity Mapping
|
||||
|
||||
During initialization, all detected physical memory is identity-mapped (virtual address = physical address). This is done in two phases:
|
||||
|
||||
1. **Static mapping (first 16 MiB):** Four page tables are statically allocated in BSS. This avoids a chicken-and-egg problem since the PMM bitmap itself resides in this region.
|
||||
|
||||
2. **Dynamic mapping (above 16 MiB):** Additional page tables are allocated from the PMM *before* paging is enabled (so physical addresses are still directly accessible). These cover all remaining detected physical memory.
|
||||
|
||||
### Kernel Heap
|
||||
|
||||
The kernel heap region occupies virtual addresses `0xD0000000` through `0xF0000000` (768 MiB).
|
||||
|
||||
When `paging_alloc_page()` is called:
|
||||
1. A physical page is allocated from the PMM.
|
||||
2. A page table entry is created mapping the next free virtual address to the physical page.
|
||||
3. The virtual address is returned.
|
||||
|
||||
When `paging_free_page()` is called:
|
||||
1. The physical address is looked up via the page table entry.
|
||||
2. The virtual mapping is removed.
|
||||
3. The physical page is returned to the PMM.
|
||||
|
||||
### TLB Management
|
||||
|
||||
- Single-page invalidations use `invlpg`.
|
||||
- Full TLB flushes use CR3 reload.
|
||||
|
||||
## API
|
||||
|
||||
```c
|
||||
void init_paging(void);
|
||||
void paging_map_page(uint32_t vaddr, uint32_t paddr, uint32_t flags);
|
||||
void paging_unmap_page(uint32_t vaddr);
|
||||
void *paging_alloc_page(void);
|
||||
void paging_free_page(void *vaddr);
|
||||
uint32_t paging_get_physical(uint32_t vaddr);
|
||||
```
|
||||
|
||||
### Flags
|
||||
|
||||
| Flag | Value | Meaning |
|
||||
|---|---|---|
|
||||
| `PAGE_PRESENT` | 0x001 | Page is present in memory |
|
||||
| `PAGE_WRITE` | 0x002 | Page is writable |
|
||||
| `PAGE_USER` | 0x004 | Page is user-accessible (ring 3) |
|
||||
|
||||
## Key Files
|
||||
|
||||
- `src/paging.c` / `src/paging.h` — Implementation and API.
|
||||
- `src/pmm.c` / `src/pmm.h` — Physical page allocation backing.
|
||||
|
||||
## Design Decisions
|
||||
|
||||
- **No higher-half kernel yet:** The kernel runs at its physical load address (1 MiB) with identity mapping. Higher-half mapping (0xC0000000) can be added later without changing the paging API.
|
||||
- **Static + dynamic page tables:** The first 16 MiB uses BSS-allocated tables to bootstrap, while memory above 16 MiB uses PMM-allocated tables. This keeps BSS usage bounded at ~16 KiB regardless of total RAM.
|
||||
- **Sequential heap allocation:** The heap grows upward linearly. No free-list reuse of freed virtual addresses is implemented yet.
|
||||
Reference in New Issue
Block a user