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