AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
mm.c File Reference

Physical memory: setting it up at boot, and the pages of it. More...

#include <core/system.h>
#include <core/panic.h>
#include <core/arch.h>
#include <core/string.h>
#include <boot/boot.h>
#include <mm/pmap.h>
#include <mm/mm.h>
#include <mm/vm.h>
#include <mm/buddy.h>
#include <sys/sched.h>

Go to the source code of this file.

Macros

#define PAGE(addr)
#define TRACKED(addr)

Functions

void mm_page_incref (paddr_t paddr)
 Adds a reference to a page of RAM.
void mm_page_decref (paddr_t paddr)
 Drops a reference to a page of RAM.
size_t mm_page_ref (paddr_t paddr)
 Returns how many references a page of RAM has.
struct vm_page * mm_page_alloc (void)
 Allocates a free page of physical memory.
void mm_page_dealloc (paddr_t paddr)
 Frees a page of physical memory, back to the zone it came from.
int mm_page_map (struct pmap *pmap, vaddr_t vaddr, paddr_t paddr, int flags)
 Maps a page into an address space.
int mm_page_unmap (struct pmap *pmap, vaddr_t vaddr)
 Unmaps a page from an address space.
int mm_map (struct pmap *pmap, paddr_t paddr, vaddr_t vaddr, size_t size, int flags)
 Maps a range of an address space, page by page.
void mm_unmap_full (struct pmap *pmap, vaddr_t vaddr, size_t size)
 Unmaps every page of a range of an address space.
void * mm_boot_alloc (size_t size, size_t align)
 Allocates boot memory, zeroed, before the buddy allocator is set up.
static paddr_t boot_left (struct boot *boot, paddr_t start, size_t size)
 Returns the end of whatever the boot loader left in memory (modules, the kernel's symbols, the command line) that overlaps [start, start + size), or 0 if nothing does.
static int boot_usable (struct boot *boot, paddr_t start, size_t size)
 Returns whether [start, start + size) is all in one usable region of the boot loader's memory map.
static void boot_mem_place (struct boot *boot, size_t size)
 Places the boot memory: at the first place after the kernel that is RAM, free, and in the boot mapping.
static void mm_mark_unusable (struct boot *boot, paddr_t ram_end)
 Marks as used what isn't usable RAM below ram_end: the regions the memory map reserves, and the gaps between its regions.
void mm_setup (struct boot *boot)
 Sets up physical memory at boot, from the boot loader's memory map: the page structures, the buddy allocator, and what isn't free (the kernel, the modules, the reserved regions, page 0).

Variables

static struct vm_page * pages
static size_t pages_nr
static paddr_t boot_mem_start
static paddr_t boot_mem_next
static paddr_t boot_mem_end

Detailed Description

Physical memory: setting it up at boot, and the pages of it.

Every page of RAM has a struct vm_page, in pages[], with its reference count. mm_page_alloc() takes free pages from the buddy allocator (mm/buddy.c), and mm_setup() sets both up from the boot loader's memory map. See docs/kernel/memory.md.

Definition in file mm.c.

Macro Definition Documentation

◆ PAGE

#define PAGE ( addr)
Value:
(pages[(addr)/PAGE_SIZE])
#define PAGE_SIZE
Definition system.h:7
static struct vm_page * pages
Definition mm.c:25

Definition at line 27 of file mm.c.

Referenced by mm_page_alloc(), mm_page_decref(), mm_page_incref(), and mm_page_ref().

◆ TRACKED

#define TRACKED ( addr)
Value:
((addr)/PAGE_SIZE < pages_nr)
static size_t pages_nr
Definition mm.c:26

Definition at line 31 of file mm.c.

Referenced by mm_page_decref(), mm_page_incref(), and mm_page_ref().

Function Documentation

◆ boot_left()

paddr_t boot_left ( struct boot * boot,
paddr_t start,
size_t size )
static

Returns the end of whatever the boot loader left in memory (modules, the kernel's symbols, the command line) that overlaps [start, start + size), or 0 if nothing does.

Definition at line 255 of file mm.c.

References boot_left(), boot::cmdline, LMA, boot::modules, boot::modules_count, module_t::paddr, elf32_shdr::sh_addr, elf32_shdr::sh_size, module_t::size, boot::strtab, and boot::symtab.

Referenced by boot_left(), and boot_mem_place().

◆ boot_mem_place()

void boot_mem_place ( struct boot * boot,
size_t size )
static

Places the boot memory: at the first place after the kernel that is RAM, free, and in the boot mapping.

Panics if there's none.

Definition at line 306 of file mm.c.

References ARCH_BOOT_MAPPED, boot_left(), boot_mem_end, boot_mem_next, boot_mem_place(), boot_mem_start, boot_usable(), kernel_end, PAGE_ROUND, and panic.

Referenced by boot_mem_place(), and mm_setup().

◆ boot_usable()

int boot_usable ( struct boot * boot,
paddr_t start,
size_t size )
static

Returns whether [start, start + size) is all in one usable region of the boot loader's memory map.

Definition at line 294 of file mm.c.

References boot_usable(), boot::mmap, boot::mmap_count, MMAP_USABLE, mmap_t::start, and mmap_t::type.

Referenced by boot_mem_place(), and boot_usable().

◆ mm_boot_alloc()

void * mm_boot_alloc ( size_t size,
size_t align )

Allocates boot memory, zeroed, before the buddy allocator is set up.

Running out panics: the kernel can't boot without it.

Parameters
sizethe size wanted, in bytes
alignits alignment, a power of two
Returns
its kernel address

Definition at line 238 of file mm.c.

References boot_mem_end, boot_mem_next, memset(), mm_boot_alloc(), vm_page::paddr, panic, and VMA.

Referenced by alloc(), mm_boot_alloc(), and mm_setup().

◆ mm_map()

int mm_map ( struct pmap * pmap,
paddr_t paddr,
vaddr_t vaddr,
size_t size,
int flags )

Maps a range of an address space, page by page.

Pages that are mapped already are left as they are.

Parameters
pmapthe address space's page tables
paddrthe physical address to map, or 0 to map new pages of memory
vaddrthe virtual address
sizethe size of the range, in bytes (rounded to whole pages)
flagsthe mappings' permissions (VM_*)
Returns
0, or -ENOMEM if there was no memory for a page or a page table; the pages mapped before that stay mapped

Definition at line 161 of file mm.c.

References arch_page_get_mapping(), mm_map(), mm_page_alloc(), mm_page_dealloc(), mm_page_map(), vm_page::paddr, PAGE_ALIGN, PAGE_ROUND, and PAGE_SIZE.

Referenced by mm_map(), and vm_map().

◆ mm_mark_unusable()

void mm_mark_unusable ( struct boot * boot,
paddr_t ram_end )
static

Marks as used what isn't usable RAM below ram_end: the regions the memory map reserves, and the gaps between its regions.

Definition at line 323 of file mm.c.

References buddy_set_unusable(), mmap_t::end, MIN, mm_mark_unusable(), boot::mmap, boot::mmap_count, MMAP_USABLE, ram_end(), mmap_t::start, and mmap_t::type.

Referenced by mm_mark_unusable(), and mm_setup().

◆ mm_page_alloc()

struct vm_page * mm_page_alloc ( void )

Allocates a free page of physical memory.

Running out of memory is an error that the caller handles like any other, not a panic: a process's page fault kills it, a system call returns ENOMEM, a network frame is dropped. Only what the kernel can't boot without panics.

Returns
the page's structure, zeroed but for its address, or NULL if there is no free page

Definition at line 78 of file mm.c.

References buddy_alloc(), BUDDY_ZONE_DMA, BUDDY_ZONE_NORMAL, memset(), mm_page_alloc(), NULL, vm_page::paddr, PAGE, and PAGE_SIZE.

Referenced by kvmem_alloc(), mm_map(), mm_page_alloc(), netbuf_alloc(), page_get(), pf_anon(), pf_object(), pf_present(), pf_zero(), sigcode_in(), slab_page_alloc(), table_alloc(), table_alloc(), table_alloc(), and vnode_page_in().

◆ mm_page_dealloc()

void mm_page_dealloc ( paddr_t paddr)

◆ mm_page_decref()

void mm_page_decref ( paddr_t paddr)

Drops a reference to a page of RAM.

A page past RAM is left alone.

Parameters
paddrthe page's physical address

Definition at line 50 of file mm.c.

References mm_page_decref(), vm_page::paddr, PAGE, and TRACKED.

Referenced by mm_page_decref(), netbuf_free(), pf_present(), pmap_remove_all(), tables_free(), and tables_free().

◆ mm_page_incref()

void mm_page_incref ( paddr_t paddr)

Adds a reference to a page of RAM.

A page past RAM (device memory, such as a framebuffer) has no reference count, and is left alone.

Parameters
paddrthe page's physical address

Definition at line 39 of file mm.c.

References mm_page_incref(), vm_page::paddr, PAGE, and TRACKED.

Referenced by mm_page_incref(), netbuf_alloc(), pf_anon(), and pf_object().

◆ mm_page_map()

int mm_page_map ( struct pmap * pmap,
vaddr_t vaddr,
paddr_t paddr,
int flags )

Maps a page into an address space.

The page's references are the vm objects' that hold it, not the mappings', so this doesn't add one.

Parameters
pmapthe address space's page tables
vaddrthe virtual address, page-aligned
paddrthe page's physical address, page-aligned
flagsthe mapping's permissions (VM_*)
Returns
0, -EINVAL for an address that can't be mapped page by page, or -ENOMEM if there was no memory for a page table

Definition at line 122 of file mm.c.

References mm_page_map(), vm_page::paddr, and pmap_add().

Referenced by mm_map(), mm_page_map(), pf_anon(), pf_object(), pf_present(), and pf_zero().

◆ mm_page_ref()

size_t mm_page_ref ( paddr_t paddr)

Returns how many references a page of RAM has.

Parameters
paddrthe page's physical address
Returns
its reference count, or 0 for a page past RAM

Definition at line 62 of file mm.c.

References mm_page_ref(), vm_page::paddr, PAGE, and TRACKED.

Referenced by mm_page_ref(), and netbuf_free().

◆ mm_page_unmap()

int mm_page_unmap ( struct pmap * pmap,
vaddr_t vaddr )

Unmaps a page from an address space.

Parameters
pmapthe address space's page tables
vaddrthe page's virtual address
Returns
0, or -EINVAL if no page is mapped there

Definition at line 134 of file mm.c.

References arch_page_get_mapping(), mm_page_unmap(), vm_page::paddr, PAGE_SIZE, and pmap_remove().

Referenced by mm_page_unmap(), and mm_unmap_full().

◆ mm_setup()

void mm_setup ( struct boot * boot)

Sets up physical memory at boot, from the boot loader's memory map: the page structures, the buddy allocator, and what isn't free (the kernel, the modules, the reserved regions, page 0).

Then the architecture sets up its page tables (arch_mm_setup()).

Parameters
bootwhat the boot loader passed (see boot/boot.h)

Definition at line 365 of file mm.c.

References arch_mm_setup(), boot_mem_next, boot_mem_place(), boot_mem_start, BUDDY_MAX_BS, buddy_set_unusable(), buddy_setup(), mmap_t::end, k_total_mem, MAX, MIN, mm_boot_alloc(), mm_mark_unusable(), mm_setup(), boot::mmap, boot::mmap_count, MMAP_USABLE, boot::modules, boot::modules_count, module_t::paddr, PAGE_ROUND, PAGE_SIZE, pages, pages_nr, printk(), ram_end(), module_t::size, mmap_t::start, boot::total_mem, and mmap_t::type.

Referenced by aarch64_init(), mm_setup(), and x86_cpu_init().

◆ mm_unmap_full()

void mm_unmap_full ( struct pmap * pmap,
vaddr_t vaddr,
size_t size )

Unmaps every page of a range of an address space.

Parameters
pmapthe address space's page tables
vaddrthe range's start
sizeits size, in bytes (rounded to whole pages)

Definition at line 208 of file mm.c.

References mm_page_unmap(), mm_unmap_full(), PAGE_ALIGN, PAGE_ROUND, and PAGE_SIZE.

Referenced by mm_unmap_full(), and vm_unmap_full().

Variable Documentation

◆ boot_mem_end

paddr_t boot_mem_end
static

Definition at line 228 of file mm.c.

Referenced by boot_mem_place(), and mm_boot_alloc().

◆ boot_mem_next

paddr_t boot_mem_next
static

Definition at line 228 of file mm.c.

Referenced by boot_mem_place(), mm_boot_alloc(), and mm_setup().

◆ boot_mem_start

paddr_t boot_mem_start
static

Definition at line 228 of file mm.c.

Referenced by boot_mem_place(), and mm_setup().

◆ pages

struct vm_page* pages
static

Definition at line 25 of file mm.c.

Referenced by mm_setup().

◆ pages_nr

size_t pages_nr
static

Definition at line 26 of file mm.c.

Referenced by mm_setup().