Expand description
§Lazy Paging
The lazy paging or demand paging is an another policy for the
paging, which used by modern operating systems. Unlike the EagerPager
that you implemented in project 2, the LazyPager defers physical page
allocation until a page fault occurs. This method optimizes memory usage by
mapping memory pages on demand, rather than preallocating them.
Instead of allocating physical memory during the mmap call, the OS records
metadata about the mapping and waits to allocate physical memory until
the first page fault on that region. When a page fault occurs, the
kernel allocates and maps the required physical page.
In other words, page table entries are created only when accessed.
§Page Fault in KeOS
The main function responsible for handling page faults lies in
Task::page_fault. This resolves the page fault reason into
PageFaultReason by reading the cr2, which contains faulting address,
and decoding the error code on the interrupt stack.
It then delegates the page fault handling into the
LazyPager::handle_page_fault. This method is responsible to look up the
lazy mapping metadata recorded during the mmap and determine whether the
fault is bogus fault or not. If the address is valid, it should allocate a
new physical page and maps the page into page table. Otherwise, killing the
current process by returning the KernelError.
§VmAreaStruct
The VmAreaStruct represents a range of virtual addresses that share the
same memory permissions, similar to the Linux kernel’s struct vm_area_struct. It serves as the core metadata structure for memory-mapped
regions created via mmap, capturing the virtual range and the method
for populating that region’s contents on access.
Each VmAreaStruct is associated with an implementation of the
MmLoader trait, which defines how the contents of a page should be
supplied when the region is accessed. This trait-based abstraction
enables the kernel to support multiple types of memory mappings in a uniform
way. For instance, file-backed mappings use a FileBackedLoader, which
reads contents from a file, while anonymous mappings use an AnonLoader,
which typically supplies zero-filled pages. Each loader implementation can
maintain its own internal state, supporting extensibility and encapsulates
the complexity of mapping behavior within each loader.
The MmLoader trait provides a single method, load, which is called
during demand paging when a page fault occurs at an address within the
associated VmAreaStruct. The method must return a fully initialized
Page object corresponding to that virtual address. The returned page is
then mapped into the page table by the pager.
This loader-based architecture provides a clean separation of concerns:
VmAreaStruct tracks regions and permissions, while MmLoader
encapsulates how pages are provisioned. This allows KeOS to support flexible
and efficient memory models while maintaining clean abstractions.
§Implementation Requirements
You need to implement the followings:
LazyPagerLazyPager::newLazyPager::mmapLazyPager::munmapLazyPager::get_user_pageLazyPager::access_okPageFaultReason::is_demand_paging_faultLazyPager::do_lazy_loadVmAreaStructFileBackedLoaderFileBackedLoader::load
After implement the functionalities, move on to the next section.
Structs§
- Anon
Loader - A loader for anonymous memory regions.
- File
Backed Loader - A loader for file-backed memory regions.
- Lazy
Pager - The
LazyPagerstructure implements lazy paging, where memory pages are mapped only when accessed (on page fault), instead of duringmmapcalls. - Page
Fault Reason - Represents the reason for a page fault in a virtual memory system.
- VmArea
Struct - Represents a memory-mapped region within a process’s virtual address space,
corresponding to the Linux kernel’s
struct vm_area_struct.
Traits§
- MmLoader
- A trait for loading the contents of a virtual memory page on demand.