27#define PAGE(addr) (pages[(addr)/PAGE_SIZE])
31#define TRACKED(addr) ((addr)/PAGE_SIZE < pages_nr)
169 size_t nr = (endaddr - vaddr) /
PAGE_SIZE;
243 panic(
"mm: out of boot memory");
263 if (start < e && end > s)
268 paddr_t r[3][2] = {{0, 0}, {0, 0}, {0, 0}};
285 for (
int i = 0; i < 3; ++i)
286 if (r[i][1] && start < r[i][1] && end > r[i][0])
298 boot->
mmap[i].
start <= start && start + size <= boot->mmap[i].end)
315 panic(
"mm: no room for the page structures after the kernel");
393 printk(
"kernel: only the first %ld MiB are used\n", (
uint64_t) (ARCH_RAM_MAX >> 20));
403 printk(
"kernel: %ld MiB of memory, up to %p\n", ram >> 20,
ram_end);
void mm_page_decref(paddr_t paddr)
Drops a reference to a page of RAM.
struct vm_page * mm_page_alloc(void)
Allocates a free page of physical memory.
int mm_page_map(struct pmap *pmap, vaddr_t vaddr, paddr_t paddr, int flags)
Maps a page into 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.
size_t mm_page_ref(paddr_t paddr)
Returns how many references a page of RAM has.
void mm_page_dealloc(paddr_t paddr)
Frees a page of physical memory, back to the zone it came from.
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_page_incref(paddr_t paddr)
Adds a reference to a page of RAM.
void mm_setup(struct boot *boot)
Sets up physical memory at boot, from the boot loader's memory map: the page structures,...
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
void buddy_free(int zone, paddr_t paddr, size_t size)
Frees a block that buddy_alloc() gave.
void buddy_set_unusable(paddr_t paddr, size_t size)
Marks a range of physical memory as not free, at boot, before the first allocation: the kernel,...
paddr_t buddy_alloc(int zone, size_t size)
Allocates a block of physical memory from a zone, rounded up to a power of two pages.
uintptr_t buddy_zone_offset[]
#define BUDDY_ZONE_NORMAL
int buddy_setup(size_t total_mem)
Sets up the allocator at boot: a bitmap for each zone and order, every top-order block of RAM free,...
int mm_page_unmap(struct pmap *pmap, vaddr_t vaddr)
Unmaps a page from an address space.
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,...
void * mm_boot_alloc(size_t size, size_t align)
Allocates boot memory, zeroed, before the buddy allocator is set up.
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 mappin...
static paddr_t boot_mem_next
static struct vm_page * pages
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,...
static paddr_t boot_mem_end
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 paddr_t boot_mem_start
int pmap_add(struct pmap *pmap, vaddr_t va, paddr_t pa, uint32_t flags)
Maps a page in an address space, replacing what was mapped there.
paddr_t arch_page_get_mapping(struct pmap *pmap, vaddr_t vaddr)
Finds the page mapped at a virtual address of an address space.
static paddr_t ram_end(void)
Returns the end of the RAM that the boot loader found.
void arch_mm_setup(void)
Finishes setting up memory at boot, once mm_setup() has set up the page structures and the buddy allo...
void pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t eva)
Unmaps the pages of a range of an address space, and flushes them from the TLBs that may have them.
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
unsigned long long int uint64_t
An address space's page tables, on x86.
A page of physical memory (pages[] has one for every page of RAM).
paddr_t paddr
its physical address