noxos (docs): merged 'mm' docs from .wiki

This commit is contained in:
antifallobst 2023-03-16 11:04:14 +01:00
parent be3fc4fbf3
commit 3e4fadbeb4
6 changed files with 173 additions and 13 deletions

View File

@ -3,7 +3,7 @@ title: "heap.h"
summary: "dynamic memory allocator"
---
#### `heap_segment_T` - struct
# `heap_segment_T` - struct
This header lies in memory, directly before the accessible buffer of the related segment.
| Name | Type | Description |
@ -15,7 +15,7 @@ This header lies in memory, directly before the accessible buffer of the related
| prev | [heap_segment_T](https://nerdcult.net/projects/noxos/docs/codebase/mm/heap.h/#heap_segment_t---struct)* | The previous segment in the heap |
#### `heap_T` - struct
# `heap_T` - struct
| Name | Type | Description |
|--------------|---------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|
@ -23,23 +23,23 @@ This header lies in memory, directly before the accessible buffer of the related
| end | void* | The current end of the heaps segment pool (growing upwards) |
| last_segment | [heap_segment_T](https://nerdcult.net/projects/noxos/docs/codebase/mm/heap.h/#heap_segment_t---struct)* | The current last segment in the heaps segment pool |
#### `heap_init(heap*, base)` - function (void)
# `heap_init(heap*, base)` - function (void)
Initializes **_heap_** at **_base_** (virtual address).
It will automatically map some page frames to that address.
#### `heap_memory_allocate(heap*, size)` - function (void)
# `heap_memory_allocate(heap*, size)` - function (void)
Returns a pointer to a free usable memory location, that has at least the given **_size_**.
It will return `NULL` and log an error, if the heap is corrupted.
Because this function iterates over the entire heap to find a free segment, it is kinda slow.
#### `heap_memory_free(heap*, address)` - function (void)
Frees a with [heap_memory_allocate](https://nerdcult.net/projects/noxos/docs/codebase/mm/heap.h/#heap_memory_allocateheap-size---function-void)* created heap segment, and makes it usable again.
# `heap_memory_free(heap*, address)` - function (void)
Frees a with [heap_memory_allocate](https://nerdcult.net/projects/noxos/docs/codebase/mm/heap.h/#heap_memory_allocateheap-size---function-void) created heap segment, and makes it usable again.
Does nothing, if the address doesn't point to a valid heap segment.
#### `heap_dump_segments(heap*)` - function (void)
# `heap_dump_segments(heap*)` - function (void)
Logs a complete list, of all heap segments.
Useful, when debugging / testing the heap.
#### `heap_destruct(heap*)` - function (void)
# `heap_destruct(heap*)` - function (void)
Invalidates all segments of a heap, frees all used page frames and unmaps them.

View File

@ -0,0 +1,10 @@
---
title: "memory_map.h"
summary: "functions to parse the memory map provided by the bootloader"
---
# `memory_map_get_total_memory_size(boot_info*)` - function (uint64_t)
Calculates the total amount of memory available, by iterating over the memory map.
The size is stored in a static variable, so no matter how often you call this function, the size will only be calculated once.
The total amount of memory is returned in bytes.

View File

@ -0,0 +1,47 @@
---
title: "page_frame.h"
summary: "physical memory management"
---
# `PFRAME_SIZE` - macro
The size of one page (4KB).
# `page_frame_manager_T` - struct
| Name | Type | Description |
|-------------------|----------|------------------------------------------------------------------------------------|
| free_memory | uint64_t | The amount of free/usable memory in bytes |
| reserved_memory | uint64_t | The amount of reserved memory in bytes |
| used_memory | uint64_t | The amount of memory used by noxos in bytes |
| page_bitmap_index | uint64_t | The index to the first free page |
| page_bitmap | bitmap_T | A huge bitmap, that stores, which pages are claimable and which are already in use |
| blocked | bool | Thread safety guard |
#### `pframe_manager_init()` - function (void)
Initializes the page frame manager, needs to be called once at kernel init.
#### `pframe_reserve(address)` - function (void) [Thread Safe]
Blocks a page, so it can't be requested or anything else.
If the page is already blocked by anything else, e.g. by a request, it won't be reserved.
#### `pframe_reserve_multi(address, n)` - function (void) [Thread Safe]
Reserves the page at the given address, plus *n* pages after that page.
#### `pframe_unreserve(address)` - function (void) [Thread Safe]
Unreserves a reserved page and makes it accessible again.
#### `pframe_unreserve_multi(address, n)` - function (void) [Thread Safe]
Unreserves the page at the given address, plus *n* pages after that page.
#### `pframe_request()` - function (void*) [Thread Safe]
Returns the physical address of a page.
This is kind of the low level version of `memory_allocate`.
#### `pframe_free(address)` - function (void) [Thread Safe]
Needs a valid page address produced by [pframe_request](https://nerdcult.net/projects/noxos/docs/codebase/mm/page_frame.h/#pframe_request---function-void-thread-safe) as argument.
Invalidates the address and frees it, so it can be requested again.
This is kind of the low level version of `memory_free`.
#### `pframe_free_multi(address, n)` - function (void) [Thread Safe]
Frees the page at the given address, plus *n* pages after that page.

View File

@ -0,0 +1,92 @@
---
title: "page_map.h"
summary: "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](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).

View File

@ -18,19 +18,19 @@ See _General Concepts / Memory Layout_(todo: add reference) and _General Concept
| `MEM_REGION_KERNEL_THREAD_BASE` | 0xFFFFFF0000000000 | The kernel processes' _Thread Data_ regions |
| `MEM_REGION_KERNELEXEC` | 0xFFFFFFFF80000000 | The kernel executable is mapped here |
#### `MEM_REGION_THREAD_OFFSET` - macro
# `MEM_REGION_THREAD_OFFSET` - macro
This time the threads id specifies its offset in its processes' _Thread Data_ region.
#### `KERNEL_START_ADDRESS` - macro
# `KERNEL_START_ADDRESS` - macro
Returns the address of [_kernel_start](https://nerdcult.net/projects/noxos/docs/codebase/mm/region.h/#_kernel_start---global-variable).
#### `KERNEL_END_ADDRESS` - macro
# `KERNEL_END_ADDRESS` - macro
Returns the address of [_kernel_end](https://nerdcult.net/projects/noxos/docs/codebase/mm/region.h/#_kernel_end---global-variable).
#### `_kernel_start` - global variable
# `_kernel_start` - global variable
This symbol is inserted by the linker at the beginning of the kernel.
To access its value use [KERNEL_START_ADDRESS](https://nerdcult.net/projects/noxos/docs/codebase/mm/region.h/#kernel_start_address---macro).
#### `_kernel_end` - global variable
# `_kernel_end` - global variable
This symbol is inserted by the linker at the end of the kernel.
To access its value use [KERNEL_END_ADDRESS](https://nerdcult.net/projects/noxos/docs/codebase/mm/region.h/#kernel_end_address---macro).

View File

@ -0,0 +1,11 @@
---
title: "stack.h"
summary: "functions to extract data from the call stack"
---
# `stack_dump_call_info(rip, symbol)` - function (void)
Logs information about a call.
Give this function the **_rip_** of the call and the related **_symbol_**, to make it happy.
# `stack_trace_call_stack(rbp)` - function (void)
Analyses the stack and recursively dumps information about all calls until it hits a call to `_start` or fails to resolve the calls symbol name.