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 // 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 || (uint)v < 1024*1024 || (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