added base src
[xv6-db.git] / main.c
blob11a940094b6865bc5f7ece2b385076bb9cf47515
1 #include "types.h"
2 #include "defs.h"
3 #include "param.h"
4 #include "mmu.h"
5 #include "proc.h"
6 #include "x86.h"
8 static void bootothers(void);
9 static void mpmain(void);
10 void jmpkstack(void) __attribute__((noreturn));
11 void mainc(void);
13 // Bootstrap processor starts running C code here.
14 // Allocate a real stack and switch to it, first
15 // doing some setup required for memory allocator to work.
16 int
17 main(void)
19 mpinit(); // collect info about this machine
20 lapicinit(mpbcpu());
21 seginit(); // set up segments
22 kinit(); // initialize memory allocator
23 jmpkstack(); // call mainc() on a properly-allocated stack
26 void
27 jmpkstack(void)
29 char *kstack, *top;
31 kstack = kalloc();
32 if(kstack == 0)
33 panic("jmpkstack kalloc");
34 top = kstack + PGSIZE;
35 asm volatile("movl %0,%%esp; call mainc" : : "r" (top));
36 panic("jmpkstack");
39 // Set up hardware and software.
40 // Runs only on the boostrap processor.
41 void
42 mainc(void)
44 cprintf("\ncpu%d: starting xv6\n\n", cpu->id);
45 picinit(); // interrupt controller
46 ioapicinit(); // another interrupt controller
47 consoleinit(); // I/O devices & their interrupts
48 uartinit(); // serial port
49 kvmalloc(); // initialize the kernel page table
50 pinit(); // process table
51 tvinit(); // trap vectors
52 binit(); // buffer cache
53 fileinit(); // file table
54 iinit(); // inode cache
55 ideinit(); // disk
56 if(!ismp)
57 timerinit(); // uniprocessor timer
58 userinit(); // first user process
59 bootothers(); // start other processors
61 // Finish setting up this processor in mpmain.
62 mpmain();
65 // Common CPU setup code.
66 // Bootstrap CPU comes here from mainc().
67 // Other CPUs jump here from bootother.S.
68 static void
69 mpmain(void)
71 if(cpunum() != mpbcpu()){
72 seginit();
73 lapicinit(cpunum());
75 vmenable(); // turn on paging
76 cprintf("cpu%d: starting\n", cpu->id);
77 idtinit(); // load idt register
78 xchg(&cpu->booted, 1); // tell bootothers() we're up
79 scheduler(); // start running processes
82 // Start the non-boot processors.
83 static void
84 bootothers(void)
86 extern uchar _binary_bootother_start[], _binary_bootother_size[];
87 uchar *code;
88 struct cpu *c;
89 char *stack;
91 // Write bootstrap code to unused memory at 0x7000.
92 // The linker has placed the image of bootother.S in
93 // _binary_bootother_start.
94 code = (uchar*)0x7000;
95 memmove(code, _binary_bootother_start, (uint)_binary_bootother_size);
97 for(c = cpus; c < cpus+ncpu; c++){
98 if(c == cpus+cpunum()) // We've started already.
99 continue;
101 // Tell bootother.S what stack to use and the address of mpmain;
102 // it expects to find these two addresses stored just before
103 // its first instruction.
104 stack = kalloc();
105 *(void**)(code-4) = stack + KSTACKSIZE;
106 *(void**)(code-8) = mpmain;
108 lapicstartap(c->id, (uint)code);
110 // Wait for cpu to finish mpmain()
111 while(c->booted == 0)
116 // Blank page.