8 static void bootothers(void);
9 static void mpmain(void);
10 void jmpkstack(void) __attribute__((noreturn
));
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.
19 mpinit(); // collect info about this machine
21 seginit(); // set up segments
22 kinit(); // initialize memory allocator
23 jmpkstack(); // call mainc() on a properly-allocated stack
33 panic("jmpkstack kalloc");
34 top
= kstack
+ PGSIZE
;
35 asm volatile("movl %0,%%esp; call mainc" : : "r" (top
));
39 // Set up hardware and software.
40 // Runs only on the boostrap processor.
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
57 timerinit(); // uniprocessor timer
58 userinit(); // first user process
59 bootothers(); // start other processors
61 // Finish setting up this processor in mpmain.
65 // Common CPU setup code.
66 // Bootstrap CPU comes here from mainc().
67 // Other CPUs jump here from bootother.S.
71 if(cpunum() != mpbcpu()){
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.
86 extern uchar _binary_bootother_start
[], _binary_bootother_size
[];
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.
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.
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)