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