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