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 // defined by the kernel linker script in kernel.ld 15 16 struct run { 17 struct run *next; 18 }; 19 20 struct { 21 struct spinlock lock; 22 int use_lock; 23 struct run *freelist; 24 } kmem; 25 26 // Initialization happens in two phases. 27 // 1. main() calls kinit1() while still using entrypgdir to place just 28 // the pages mapped by entrypgdir on free list. 29 // 2. main() calls kinit2() with the rest of the physical pages 30 // after installing a full page table that maps them on all cores. 31 void 32 kinit1(void *vstart, void *vend) 33 { 34 initlock(&kmem.lock, "kmem"); 35 kmem.use_lock = 0; 36 freerange(vstart, vend); 37 } 38 39 void 40 kinit2(void *vstart, void *vend) 41 { 42 freerange(vstart, vend); 43 kmem.use_lock = 1; 44 } 45 46 void 47 freerange(void *vstart, void *vend) 48 { 49 char *p; 50 p = (char*)PGROUNDUP((uint)vstart); 51 for(; p + PGSIZE <= (char*)vend; p += PGSIZE) 52 kfree(p); 53 } 54 55 //PAGEBREAK: 21 56 // Free the page of physical memory pointed at by v, 57 // which normally should have been returned by a 58 // call to kalloc(). (The exception is when 59 // initializing the allocator; see kinit above.) 60 void 61 kfree(char *v) 62 { 63 struct run *r; 64 65 if((uint)v % PGSIZE || v < end || V2P(v) >= PHYSTOP) 66 panic("kfree"); 67 68 // Fill with junk to catch dangling refs. 69 memset(v, 1, PGSIZE); 70 71 if(kmem.use_lock) 72 acquire(&kmem.lock); 73 r = (struct run*)v; 74 r->next = kmem.freelist; 75 kmem.freelist = r; 76 if(kmem.use_lock) 77 release(&kmem.lock); 78 } 79 80 // Allocate one 4096-byte page of physical memory. 81 // Returns a pointer that the kernel can use. 82 // Returns 0 if the memory cannot be allocated. 83 char* 84 kalloc(void) 85 { 86 struct run *r; 87 88 if(kmem.use_lock) 89 acquire(&kmem.lock); 90 r = kmem.freelist; 91 if(r) 92 kmem.freelist = r->next; 93 if(kmem.use_lock) 94 release(&kmem.lock); 95 return (char*)r; 96 } 97 98