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