Virtual memory spaces are a bit more tricky than the physical memory space.
To understand them, we have to understand first, that the physical memory space is divided into so-called **pages** / **page frames**.
These pages have a size of 4KB.
A virtual memory space is a table of page mappings.
Per default there are no pages mapped to such a table.
When the OS maps a page to a **page table**, it says:
"This page is now accessible from this virtual space, at this address".
When the Computer is in paging mode, only mapped pages are accessible.
Now every Process gets its own page table and tada: we have successfully isolated the processes from each other,
because every process can only access the data that it needs to access.
# `VIRTUAL_ADDRESS_MAX` - macro
The highest mappable virtual address.
4 level page maps have a maximum address space of 256TB.
# `page_map_flag_E` - enum
- **Present** - This indicates if the entry is used or should be ignored. Automatically set when mapping a page.
- **Read & Write** - A mapped Page is always readable. This flag allows writing to that page.
- **User Super** - If set, user mode access to the page is allowed.
- **Write Through** - Enables _Write Through Caching_ for this page.
- **Cache Disabled** - If this bit is set, the page won't be cached.
- **Accessed** - Set by the CPU, when this PDE or PTE was read. Won't be reset by the CPU.
- **Dirty** - Set when the page has been modified.
- **Larger Pages** - When this bit is set in a PDE or PTE, the entry points to a 1GB or 2MB page.
- **Custom 1 - 3** - Not used in NoxOS.
- **No Execute** - When this bit is set, the CPU won't execute code that lies in that page.
# `page_map_T` - struct [page aligned]
This struct contains 512 entries.
These entries contain an address and flags.
The addresses link like this:
- **PML4** --> **Page Directory** or _1GB Page_
- **Page Directory** --> **Page Table** or _2MB Page_
- **Page Table** --> _4KB Page_
A pointer to a [page_map_T](https://nerdcult.net/projects/noxos/docs/codebase/mm/page_map.h/#page_map_t---struct-page-aligned) can be loaded into `cr3` to load this pagemap.
# `page_map_create()` - function (page_map_T*)
Allocates a [page_map_T](https://nerdcult.net/projects/noxos/docs/codebase/mm/page_map.h/#page_map_t---struct-page-aligned) and returns a pointer to it.
The page map is populated with the mappings for the kernel executable and the loaded IDT.
# `page_map_fetch_current()` - function (page_map_T*) [ASM implementation]
This function will return the page map, that is currently loaded.
To achieve this, it just reads the `cr3` register.
# `page_map_load(page_map*)` - function (void) [ASM implementation]
Loads the given page map.
To achieve this, it writes the `cr3` register.
# `page_map_map_memory(page_map*, virtual_address, physical_address, flags)` - function (void)
This maps **_physical_address_** to **_virtual_address_** in **_page_map_**.
The **_flags_** will be applied to the page mapping / page table entry.
It always applies the _Present_ flag automatically.
# `page_map_unmap_memory(page_map*, virtual_address)` - function (void)
Removes a page mapping from the **_page_map_**.
Page map structure intern pages won't be checked if they're still needed or not.
# `page_map_get_physical_address(page_map*, virtual_address)` - function (void*)
Returns the physical address of the page, that is mapped to **_virtual_address_**.
# `page_map_destruct(page_map*)` - function (void)
Clears a page map and frees all page map structure intern pages.
# `page_map_dump_info(page_map)` - function (void)
Logs information about **_page_map_**, including a map of all mapped regions.
A region is a block of continuously mapped pages.
# `page_map_entry_set_flags(entry, uint64_t flags)` - function (void)
This will set the provided flags to a page map entry.
# `page_map_entry_get_flag(entry, page_map_flag_E flag)` - function (bool)
Returns if the given flag is set in the page map entry, or not.
# `page_map_entry_set_address(entry, void* address)` - function (void)
This will set the provided address to a page map entry.
# `page_map_entry_get_address(entry)` - function (void*)
This will read and return the address set in the page map entry.
# `paging_init()` - function (void)
Initializes paging.
This reads the current page map set by the kernel and writes it to [g_kernel_page_map](https://nerdcult.net/projects/noxos/docs/codebase/mm/page_map.h/#g_kernel_page_map---global-variable).
# `g_kernel_page_map` - global variable
The kernels page map. This page map is provided by the bootloader and read from `cr3` at [paging_init](https://nerdcult.net/projects/noxos/docs/codebase/mm/page_map.h/#paging_init---function-void).