xref: /xv6-public/main.c (revision 7837c71b)
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