Header: kernel/include/kernel/paging.h
Source: kernel/arch/i386/mm/paging.c
Enables the x86 32-bit paging unit and provides a runtime region-mapping function used by the heap and VESA framebuffer drivers to access memory outside the initial boot window.
OSDev references:
paging_init() identity-maps the first 256 MiB of physical memory
(physical address = virtual address) using 4 MiB PSE large pages.
Before loading CR3, CR4.PSE (bit 4) is set so the processor honours the
PS bit in PDE entries. Each of the 64 large-page PDE entries maps one
aligned 4 MiB region directly - no intermediate page table is needed.
This is the 32-bit equivalent of the 2 MiB large pages used by x86-64
long-mode kernels.
All pages in this range are supervisor-only and writable.
This window covers:
0xB8000).A static pool of 32 extra 4 KiB page tables (extra_page_tables) handles
post-boot mapping requests for addresses above 256 MiB. Each page
table covers 4 MiB of virtual address space, so the pool can map up to
128 MiB of additional regions. This is enough for the 16 MiB kernel
heap and the typical VESA framebuffer.
Requests that fall within the 256 MiB large-page window are detected by
checking the PAGE_LARGE flag in the relevant PDE and silently skipped.
paging_initvoid paging_init(void);
CR4.PSE (bit 4) to enable 4 MiB large pages.page_fault_handler on ISR 14.paging_map_regionvoid paging_map_region(uint32_t phys_start, uint32_t size);
Identity-map the physical address range [phys_start, phys_start + size).
Pages that fall within a large-page PDE entry (already covered by the
256 MiB boot window) are silently skipped. If the page-table pool is
exhausted the function returns without mapping anything further.
| Parameter | Description |
|---|---|
phys_start |
Physical start address. Need not be page-aligned; the function rounds down. |
size |
Length in bytes. Need not be page-aligned; the function rounds up. |
Called by:
heap_init() - to map the 16 MiB heap region.vesa_tty_init() - to map the VESA linear framebuffer before the first pixel write.acpi_init() (via acpi_map_table()) - to map RSDT, FADT, and DSDT.A simple panic handler is installed on ISR 14. It reads the faulting address
from CR2, prints it alongside the error code, then calls PANIC("Page fault").
The error code bits indicate:
See the Page Fault OSDev article for the full error-code description.
fork() (slice 15). Per-frame refcounts in
pmm.c; the software VMM_PTE_COW bit (PTE bit 9) marks shared
pages read-only at clone time; the #PF handler in
arch/i386/debug/debug.c resolves the fault by either flipping
the bit back to RW (sole owner, refcount==1) or allocating a fresh
frame + memcpy + decrementing the shared refcount. CR0.WP is
enabled at paging_init so kernel writes also honour the RO bit
(required to make COW work uniformly across user and kernel access
paths). See vmm_clone_pd_cow in arch/i386/mm/vmm.c.