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 "mmu.h" 9 #include "spinlock.h" 10 11 struct run { 12 struct run *next; 13 }; 14 15 struct { 16 struct spinlock lock; 17 struct run *freelist; 18 } kmem; 19 20 extern char end[]; // first address after kernel loaded from ELF file 21 22 // Initialize free list of physical pages. 23 void 24 kinit(void) 25 { 26 initlock(&kmem.lock, "kmem"); 27 char *p = (char*)PGROUNDUP((uint)end); 28 for( ; p + PGSIZE - 1 < (char*) PHYSTOP; p += PGSIZE) 29 kfree(p); 30 } 31 32 //PAGEBREAK: 21 33 // Free the page of physical memory pointed at by v, 34 // which normally should have been returned by a 35 // call to kalloc(). (The exception is when 36 // initializing the allocator; see kinit above.) 37 void 38 kfree(char *v) 39 { 40 struct run *r; 41 42 if(((uint) v) % PGSIZE || v < end || (uint)v >= PHYSTOP) 43 panic("kfree"); 44 45 // Fill with junk to catch dangling refs. 46 memset(v, 1, PGSIZE); 47 48 acquire(&kmem.lock); 49 r = (struct run *) v; 50 r->next = kmem.freelist; 51 kmem.freelist = r; 52 release(&kmem.lock); 53 } 54 55 // Allocate one 4096-byte page of physical memory. 56 // Returns a pointer that the kernel can use. 57 // Returns 0 if the memory cannot be allocated. 58 char* 59 kalloc() 60 { 61 struct run *r; 62 63 acquire(&kmem.lock); 64 r = kmem.freelist; 65 if(r) 66 kmem.freelist = r->next; 67 release(&kmem.lock); 68 return (char*) r; 69 } 70 71