1 #include "types.h" 2 #include "param.h" 3 #include "mmu.h" 4 #include "proc.h" 5 #include "defs.h" 6 #include "x86.h" 7 #include "traps.h" 8 #include "syscall.h" 9 #include "elf.h" 10 #include "param.h" 11 12 extern char edata[], end[]; 13 extern int acpu; 14 extern char _binary_user1_start[], _binary_user1_size[]; 15 extern char _binary_usertests_start[], _binary_usertests_size[]; 16 extern char _binary_userfs_start[], _binary_userfs_size[]; 17 18 char buf[512]; 19 20 int 21 main() 22 { 23 struct proc *p; 24 25 if (acpu) { 26 cprintf("an application processor\n"); 27 release_spinlock(&kernel_lock); 28 acquire_spinlock(&kernel_lock); 29 idtinit(); // CPU's idt 30 lapic_init(cpu()); 31 curproc[cpu()] = &proc[0]; // XXX 32 swtch(); 33 } 34 acpu = 1; 35 // clear BSS 36 memset(edata, 0, end - edata); 37 38 cprintf("\nxV6\n\n"); 39 40 pic_init(); // initialize PIC 41 mp_init(); // multiprocessor 42 kinit(); // physical memory allocator 43 tvinit(); // trap vectors 44 idtinit(); // CPU's idt 45 46 // create fake process zero 47 p = &proc[0]; 48 curproc[cpu()] = p; 49 p->state = WAITING; 50 p->sz = 4 * PAGE; 51 p->mem = kalloc(p->sz); 52 memset(p->mem, 0, p->sz); 53 p->kstack = kalloc(KSTACKSIZE); 54 p->tf = (struct Trapframe *) (p->kstack + KSTACKSIZE - sizeof(struct Trapframe)); 55 memset(p->tf, 0, sizeof(struct Trapframe)); 56 p->tf->tf_es = p->tf->tf_ds = p->tf->tf_ss = (SEG_UDATA << 3) | 3; 57 p->tf->tf_cs = (SEG_UCODE << 3) | 3; 58 p->tf->tf_eflags = FL_IF; 59 p->pid = 0; 60 p->ppid = 0; 61 setupsegs(p); 62 63 // become interruptable 64 write_eflags(read_eflags() | FL_IF); 65 66 // turn on timer and enable interrupts on the local APIC 67 lapic_timerinit(); 68 lapic_enableintr(); 69 70 p = newproc(); 71 // load_icode(p, _binary_usertests_start, (unsigned) _binary_usertests_size); 72 load_icode(p, _binary_userfs_start, (unsigned) _binary_userfs_size); 73 74 swtch(); 75 76 return 0; 77 } 78 79 void 80 load_icode(struct proc *p, uint8_t *binary, unsigned size) 81 { 82 int i; 83 struct Elf *elf; 84 struct Proghdr *ph; 85 86 // Check magic number on binary 87 elf = (struct Elf*) binary; 88 cprintf("elf %x magic %x\n", elf, elf->e_magic); 89 if (elf->e_magic != ELF_MAGIC) 90 panic("load_icode: not an ELF binary"); 91 92 p->tf->tf_eip = elf->e_entry; 93 p->tf->tf_esp = p->sz; 94 95 // Map and load segments as directed. 96 ph = (struct Proghdr*) (binary + elf->e_phoff); 97 for (i = 0; i < elf->e_phnum; i++, ph++) { 98 if (ph->p_type != ELF_PROG_LOAD) 99 continue; 100 cprintf("va %x memsz %d\n", ph->p_va, ph->p_memsz); 101 if (ph->p_va + ph->p_memsz < ph->p_va) 102 panic("load_icode: overflow in elf header segment"); 103 if (ph->p_va + ph->p_memsz >= p->sz) 104 panic("load_icode: icode wants to be above UTOP"); 105 106 // Load/clear the segment 107 memcpy(p->mem + ph->p_va, binary + ph->p_offset, ph->p_filesz); 108 memset(p->mem + ph->p_va + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz); 109 } 110 } 111