Xv6 with picoc & Linkage editor
v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
|
00001 // Physical memory allocator, intended to allocate 00002 // memory for user processes, kernel stacks, page table pages, 00003 // and pipe buffers. Allocates 4096-byte pages. 00004 00005 #include "types.h" 00006 #include "defs.h" 00007 #include "param.h" 00008 #include "memlayout.h" 00009 #include "mmu.h" 00010 #include "spinlock.h" 00011 00012 void freerange(void *vstart, void *vend); 00013 extern char end[]; // first address after kernel loaded from ELF file 00014 00015 struct run { 00016 struct run *next; 00017 }; 00018 00019 struct { 00020 struct spinlock lock; 00021 int use_lock; 00022 struct run *freelist; 00023 } kmem; 00024 00025 // Initialization happens in two phases. 00026 // 1. main() calls kinit1() while still using entrypgdir to place just 00027 // the pages mapped by entrypgdir on free list. 00028 // 2. main() calls kinit2() with the rest of the physical pages 00029 // after installing a full page table that maps them on all cores. 00030 void 00031 kinit1(void *vstart, void *vend) 00032 { 00033 initlock(&kmem.lock, "kmem"); 00034 kmem.use_lock = 0; 00035 freerange(vstart, vend); 00036 } 00037 00038 void 00039 kinit2(void *vstart, void *vend) 00040 { 00041 freerange(vstart, vend); 00042 kmem.use_lock = 1; 00043 } 00044 00045 void 00046 freerange(void *vstart, void *vend) 00047 { 00048 char *p; 00049 p = (char*)PGROUNDUP((uint)vstart); 00050 for(; p + PGSIZE <= (char*)vend; p += PGSIZE) 00051 kfree(p); 00052 } 00053 00054 //PAGEBREAK: 21 00055 // Free the page of physical memory pointed at by v, 00056 // which normally should have been returned by a 00057 // call to kalloc(). (The exception is when 00058 // initializing the allocator; see kinit above.) 00059 void 00060 kfree(char *v) 00061 { 00062 struct run *r; 00063 00064 if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) 00065 panic("kfree"); 00066 00067 // Fill with junk to catch dangling refs. 00068 memset(v, 1, PGSIZE); 00069 00070 if(kmem.use_lock) 00071 acquire(&kmem.lock); 00072 r = (struct run*)v; 00073 r->next = kmem.freelist; 00074 kmem.freelist = r; 00075 if(kmem.use_lock) 00076 release(&kmem.lock); 00077 } 00078 00079 // Allocate one 4096-byte page of physical memory. 00080 // Returns a pointer that the kernel can use. 00081 // Returns 0 if the memory cannot be allocated. 00082 char* 00083 kalloc(void) 00084 { 00085 struct run *r; 00086 00087 if(kmem.use_lock) 00088 acquire(&kmem.lock); 00089 r = kmem.freelist; 00090 if(r) 00091 kmem.freelist = r->next; 00092 if(kmem.use_lock) 00093 release(&kmem.lock); 00094 return (char*)r; 00095 } 00096