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 #include "types.h" 00002 #include "defs.h" 00003 #include "param.h" 00004 #include "memlayout.h" 00005 #include "mmu.h" 00006 #include "proc.h" 00007 #include "x86.h" 00008 00009 static void startothers(void); 00010 static void mpmain(void) __attribute__((noreturn)); 00011 extern pde_t *kpgdir; 00012 extern char end[]; // first address after kernel loaded from ELF file 00013 00014 // Bootstrap processor starts running C code here. 00015 // Allocate a real stack and switch to it, first 00016 // doing some setup required for memory allocator to work. 00017 int 00018 main(void) 00019 { 00020 kinit1(end, P2V(4*1024*1024)); // phys page allocator 00021 kvmalloc(); // kernel page table 00022 mpinit(); // collect info about this machine 00023 lapicinit(mpbcpu()); 00024 seginit(); // set up segments 00025 cprintf("\ncpu%d: starting xv6\n\n", cpu->id); 00026 picinit(); // interrupt controller 00027 ioapicinit(); // another interrupt controller 00028 consoleinit(); // I/O devices & their interrupts 00029 uartinit(); // serial port 00030 pinit(); // process table 00031 tvinit(); // trap vectors 00032 binit(); // buffer cache 00033 fileinit(); // file table 00034 iinit(); // inode cache 00035 ideinit(); // disk 00036 if(!ismp) 00037 timerinit(); // uniprocessor timer 00038 startothers(); // start other processors 00039 kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() 00040 userinit(); // first user process 00041 // Finish setting up this processor in mpmain. 00042 mpmain(); 00043 } 00044 00045 // Other CPUs jump here from entryother.S. 00046 static void 00047 mpenter(void) 00048 { 00049 switchkvm(); 00050 seginit(); 00051 lapicinit(cpunum()); 00052 mpmain(); 00053 } 00054 00055 // Common CPU setup code. 00056 static void 00057 mpmain(void) 00058 { 00059 cprintf("cpu%d: starting\n", cpu->id); 00060 idtinit(); // load idt register 00061 xchg(&cpu->started, 1); // tell startothers() we're up 00062 scheduler(); // start running processes 00063 } 00064 00065 pde_t entrypgdir[]; // For entry.S 00066 00067 // Start the non-boot (AP) processors. 00068 static void 00069 startothers(void) 00070 { 00071 extern uchar _binary_entryother_start[], _binary_entryother_size[]; 00072 uchar *code; 00073 struct cpu *c; 00074 char *stack; 00075 00076 // Write entry code to unused memory at 0x7000. 00077 // The linker has placed the image of entryother.S in 00078 // _binary_entryother_start. 00079 code = p2v(0x7000); 00080 memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); 00081 00082 for(c = cpus; c < cpus+ncpu; c++){ 00083 if(c == cpus+cpunum()) // We've started already. 00084 continue; 00085 00086 // Tell entryother.S what stack to use, where to enter, and what 00087 // pgdir to use. We cannot use kpgdir yet, because the AP processor 00088 // is running in low memory, so we use entrypgdir for the APs too. 00089 stack = kalloc(); 00090 *(void**)(code-4) = stack + KSTACKSIZE; 00091 *(void**)(code-8) = mpenter; 00092 *(int**)(code-12) = (void *) v2p(entrypgdir); 00093 00094 lapicstartap(c->id, v2p(code)); 00095 00096 // wait for cpu to finish mpmain() 00097 while(c->started == 0) 00098 ; 00099 } 00100 } 00101 00102 // Boot page table used in entry.S and entryother.S. 00103 // Page directories (and page tables), must start on a page boundary, 00104 // hence the "__aligned__" attribute. 00105 // Use PTE_PS in page directory entry to enable 4Mbyte pages. 00106 __attribute__((__aligned__(PGSIZE))) 00107 pde_t entrypgdir[NPDENTRIES] = { 00108 // Map VA's [0, 4MB) to PA's [0, 4MB) 00109 [0] = (0) | PTE_P | PTE_W | PTE_PS, 00110 // Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB) 00111 [KERNBASE>>PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS, 00112 }; 00113 00114 //PAGEBREAK! 00115 // Blank page. 00116