noxos (docs): merged 'mm' docs from .wiki
This commit is contained in:
parent
be3fc4fbf3
commit
3e4fadbeb4
|
@ -3,7 +3,7 @@ title: "heap.h"
|
||||||
summary: "dynamic memory allocator"
|
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.
|
This header lies in memory, directly before the accessible buffer of the related segment.
|
||||||
|
|
||||||
| Name | Type | Description |
|
| 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 |
|
| 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 |
|
| 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) |
|
| 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 |
|
| 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).
|
Initializes **_heap_** at **_base_** (virtual address).
|
||||||
It will automatically map some page frames to that 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_**.
|
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.
|
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.
|
Because this function iterates over the entire heap to find a free segment, it is kinda slow.
|
||||||
|
|
||||||
#### `heap_memory_free(heap*, address)` - function (void)
|
# `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.
|
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.
|
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.
|
Logs a complete list, of all heap segments.
|
||||||
Useful, when debugging / testing the heap.
|
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.
|
Invalidates all segments of a heap, frees all used page frames and unmaps them.
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
|
@ -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).
|
|
@ -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_KERNEL_THREAD_BASE` | 0xFFFFFF0000000000 | The kernel processes' _Thread Data_ regions |
|
||||||
| `MEM_REGION_KERNELEXEC` | 0xFFFFFFFF80000000 | The kernel executable is mapped here |
|
| `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.
|
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).
|
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).
|
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.
|
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).
|
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.
|
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).
|
To access its value use [KERNEL_END_ADDRESS](https://nerdcult.net/projects/noxos/docs/codebase/mm/region.h/#kernel_end_address---macro).
|
||||||
|
|
|
@ -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.
|
Reference in New Issue