kernel/kalloc.c
82 lines
1// Physical memory allocator, for user processes,2// kernel stacks, page-table pages,3// and pipe buffers. Allocates whole 4096-byte pages.45#include "types.h"6#include "param.h"7#include "memlayout.h"8#include "spinlock.h"9#include "riscv.h"10#include "defs.h"1112void freerange(void *pa_start, void *pa_end);1314extern char end[]; // first address after kernel.15 // defined by kernel.ld.1617struct run {18 struct run *next;19};2021struct {22 struct spinlock lock;23 struct run *freelist;24} kmem;2526void27kinit()28{29 initlock(&kmem.lock, "kmem");30 freerange(end, (void*)PHYSTOP);31}3233void34freerange(void *pa_start, void *pa_end)35{36 char *p;37 p = (char*)PGROUNDUP((uint64)pa_start);38 for(; p + PGSIZE <= (char*)pa_end; p += PGSIZE)39 kfree(p);40}4142// Free the page of physical memory pointed at by pa,43// which normally should have been returned by a44// call to kalloc(). (The exception is when45// initializing the allocator; see kinit above.)46void47kfree(void *pa)48{49 struct run *r;5051 if(((uint64)pa % PGSIZE) != 0 || (char*)pa < end || (uint64)pa >= PHYSTOP)52 panic("kfree");5354 // Fill with junk to catch dangling refs.55 memset(pa, 1, PGSIZE);5657 r = (struct run*)pa;5859 acquire(&kmem.lock);60 r->next = kmem.freelist;61 kmem.freelist = r;62 release(&kmem.lock);63}6465// Allocate one 4096-byte page of physical memory.66// Returns a pointer that the kernel can use.67// Returns 0 if the memory cannot be allocated.68void *69kalloc(void)70{71 struct run *r;7273 acquire(&kmem.lock);74 r = kmem.freelist;75 if(r)76 kmem.freelist = r->next;77 release(&kmem.lock);7879 if(r)80 memset((char*)r, 5, PGSIZE); // fill with junk81 return (void*)r;82}83