96 lines
4.5 KiB
Markdown
96 lines
4.5 KiB
Markdown
# page_map.h
|
|
|
|
Virtual memory management.
|
|
|
|
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 can be loaded into `cr3` to load this pagemap.
|
|
|
|
# `page_map_create()` - function (page_map_T*)
|
|
Allocates a page_map_T 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_check_memory(page_map*, virtual_address)` - function (bool)
|
|
Check if there is a page mapped at **_virtual_address_** in **_page_map_**.
|
|
Returns _true_ if there is a page mapped and _false_ if 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.
|
|
|
|
# `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.
|