ArvernOS
Loading...
Searching...
No Matches
paging.h File Reference
#include <mmu/frame.h>
#include <stdint.h>
#include <sys/types.h>
Include dependency graph for paging.h:

Data Structures

struct  page_table_t
 

Macros

#define PAGING_FLAG_PRESENT   (1 << 0)
 Specifies whether the mapped page is loaded in memory.
 
#define PAGING_FLAG_WRITABLE   (1 << 1)
 Controls whether writes to the mapped frames are allowed.
 
#define PAGING_FLAG_USER_ACCESSIBLE   (1 << 2)
 Controls whether accesses from userspace (i.e. ring 3) are permitted.
 
#define PAGING_FLAG_HUGE_PAGE   (1 << 7)
 Tells whether the mapped page is a huge page.
 
#define PAGING_FLAG_NO_EXECUTE   ((uint64_t)1 << 63)
 Forbids executing code on this page.
 

Functions

void paging_init ()
 Initializes paging to separate virtual and physical memory.
 
page_number_t page_containing_address (uint64_t virtual_address)
 
uint64_t page_start_address (page_number_t page_number)
 
opt_uint64_t translate_page (page_number_t page_number)
 
opt_uint64_t translate (uint64_t virtual_address)
 
void map (page_number_t page_number, uint64_t flags)
 
void map_multiple (page_number_t start_page_number, uint32_t number_of_pages, uint64_t flags)
 
void unmap (page_number_t page_number)
 
void unmap_multiple (page_number_t start_page_number, uint32_t number_of_pages)
 
uint32_t paging_amount_for_byte_size (uint64_t start_address, uint64_t byte_size)
 
void identity_map (uint64_t address, uint64_t flags)
 

Function Documentation

◆ identity_map()

void identity_map ( uint64_t address,
uint64_t flags )

Maps a page (virtual address) to the equivalent frame (physical address).

Parameters
addressthe address to map
flagspaging flags

◆ map()

void map ( page_number_t page_number,
uint64_t flags )

Convenient function to map a page (number) without providing a frame. The frame is automatically allocated.

Parameters
page_numbera page number (not an address)
flagspaging flags

◆ map_multiple()

void map_multiple ( page_number_t start_page_number,
uint32_t number_of_pages,
uint64_t flags )

Maps multiple pages in a row if possible.

Parameters
start_page_numberthe first page of the sequence
number_of_pagesthe amount of pages to map
flagsthe paging flags

◆ page_containing_address()

page_number_t page_containing_address ( uint64_t virtual_address)

Returns a page number given a virtual address.

Parameters
virtual_addressa virtual address (page)
Returns
a page number

◆ page_start_address()

uint64_t page_start_address ( page_number_t page_number)

Returns the virtual start address of a page.

Parameters
page_numbera page number
Returns
a virtual address (page)

◆ paging_amount_for_byte_size()

uint32_t paging_amount_for_byte_size ( uint64_t start_address,
uint64_t byte_size )

Calculates how many pages are needed for a range of addresses.

Parameters
start_addressthe starting virtual address
byte_sizethe amount of bytes
Returns
the amount of pages required for mapping from start_address until start_address + byte_size

◆ paging_init()

void paging_init ( )

Initializes paging to separate virtual and physical memory.

The bootloader (assembly code) already set up a 4-level paging hierarchy that maps every page of our kernel to a physical frame. It does this because paging is mandatory in 64-bit mode on x86_64.

This means that every memory address that we used in our kernel was a virtual address. Accessing the VGA buffer at address 0xb8000 only worked because the bootloader identity mapped that memory page, which means that it mapped the virtual page 0xb8000 to the physical frame 0xb8000.

In addition, this improves safety since illegal memory accesses cause page fault exceptions instead of modifying arbitrary physical memory. That being said, identity mapping clutters the virtual address space and makes it more difficult to find continuous memory regions of larger sizes (like 1000 KiB).

We remap the kernel and other useful sections/addresses in this function, then we enable write protection, the NXE bit and we switch to our own table. This allows us to make everything safer. Memory is still identity mapped, which isn't great but it works for now.

◆ translate()

opt_uint64_t translate ( uint64_t virtual_address)

Translates a virtual address to the corresponding physical address.

Parameters
virtual_addressa virtual address
Returns
a physical address (optional)

◆ translate_page()

opt_uint64_t translate_page ( page_number_t page_number)

Translates a page number to a frame number.

Parameters
page_numbera page number (not an address)
Returns
a frame number (optional)

◆ unmap()

void unmap ( page_number_t page_number)

Unmaps (free) a page.

Parameters
page_numbera page number (not an address)

◆ unmap_multiple()

void unmap_multiple ( page_number_t start_page_number,
uint32_t number_of_pages )

Unmaps multiple consecutive pages.

Parameters
start_page_numberthe first page of the sequence
number_of_pagesthe amount of pages to unmap