kalloc.c (2092B)
1 // Physical memory allocator, intended to allocate 2 // memory for user processes, kernel stacks, page table pages, 3 // and pipe buffers. Allocates 4096-byte pages. 4 5 #include "types.h" 6 #include "defs.h" 7 #include "param.h" 8 #include "memlayout.h" 9 #include "mmu.h" 10 #include "spinlock.h" 11 12 void freerange(void *vstart, void *vend); 13 extern char end[]; // first address after kernel loaded from ELF file 14 15 struct run { 16 struct run *next; 17 }; 18 19 struct { 20 struct spinlock lock; 21 int use_lock; 22 struct run *freelist; 23 } kmem; 24 25 // Initialization happens in two phases. 26 // 1. main() calls kinit1() while still using entrypgdir to place just 27 // the pages mapped by entrypgdir on free list. 28 // 2. main() calls kinit2() with the rest of the physical pages 29 // after installing a full page table that maps them on all cores. 30 void 31 kinit1(void *vstart, void *vend) 32 { 33 initlock(&kmem.lock, "kmem"); 34 kmem.use_lock = 0; 35 freerange(vstart, vend); 36 } 37 38 void 39 kinit2(void *vstart, void *vend) 40 { 41 freerange(vstart, vend); 42 kmem.use_lock = 1; 43 } 44 45 void 46 freerange(void *vstart, void *vend) 47 { 48 char *p; 49 p = (char*)PGROUNDUP((uintp)vstart); 50 for(; p + PGSIZE <= (char*)vend; p += PGSIZE) 51 kfree(p); 52 } 53 54 //PAGEBREAK: 21 55 // Free the page of physical memory pointed at by v, 56 // which normally should have been returned by a 57 // call to kalloc(). (The exception is when 58 // initializing the allocator; see kinit above.) 59 void 60 kfree(char *v) 61 { 62 struct run *r; 63 64 if((uintp)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) 65 panic("kfree"); 66 67 // Fill with junk to catch dangling refs. 68 memset(v, 1, PGSIZE); 69 70 if(kmem.use_lock) 71 acquire(&kmem.lock); 72 r = (struct run*)v; 73 r->next = kmem.freelist; 74 kmem.freelist = r; 75 if(kmem.use_lock) 76 release(&kmem.lock); 77 } 78 79 // Allocate one 4096-byte page of physical memory. 80 // Returns a pointer that the kernel can use. 81 // Returns 0 if the memory cannot be allocated. 82 char* 83 kalloc(void) 84 { 85 struct run *r; 86 87 if(kmem.use_lock) 88 acquire(&kmem.lock); 89 r = kmem.freelist; 90 if(r) 91 kmem.freelist = r->next; 92 if(kmem.use_lock) 93 release(&kmem.lock); 94 return (char*)r; 95 } 96