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
kalloc.c
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 
 All Data Structures