#include "types.h" #include "defs.h" #include "param.h" #include "mmu.h" #include "proc.h" #include "x86.h" static void bootothers(void); static void mpmain(void) __attribute__((noreturn)); // Bootstrap processor starts running C code here. int main(void) { mpinit(); // collect info about this machine lapicinit(mpbcpu()); ksegment(); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pminit(); // physical memory for kernel jkstack(); // Jump to mainc on a proper-allocated kernel stack } void mainc(void) { cprintf("cpus %p cpu %p\n", cpus, cpu); cprintf("\ncpu%d: starting xv6\n\n", cpu->id); vminit(); // virtual memory pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table iinit(); // inode cache ideinit(); // disk cprintf("ismp: %d\n", ismp); if(!ismp) timerinit(); // uniprocessor timer userinit(); // first user process // bootothers(); // start other processors XXX fix where to boot from // Finish setting up this processor in mpmain. mpmain(); } // Bootstrap processor gets here after setting up the hardware. // Additional processors start here. static void mpmain(void) { if(cpunum() != mpbcpu()) { ksegment(); cprintf("other cpu\n"); vminit(); lapicinit(cpunum()); } cprintf("cpu%d: mpmain\n", cpu->id); idtinit(); xchg(&cpu->booted, 1); cprintf("cpu%d: scheduling\n", cpu->id); scheduler(); } static void bootothers(void) { extern uchar _binary_bootother_start[], _binary_bootother_size[]; uchar *code; struct cpu *c; char *stack; // Write bootstrap code to unused memory at 0x7000. code = (uchar*)0x7000; memmove(code, _binary_bootother_start, (uint)_binary_bootother_size); for(c = cpus; c < cpus+ncpu; c++){ if(c == cpus+cpunum()) // We've started already. continue; // Fill in %esp, %eip and start code on cpu. stack = kalloc(KSTACKSIZE); *(void**)(code-4) = stack + KSTACKSIZE; *(void**)(code-8) = mpmain; cprintf("lapicstartap\n"); lapicstartap(c->id, (uint)code); cprintf("lapicstartap done\n"); // Wait for cpu to get through bootstrap. while(c->booted == 0) ; cprintf("lapicstartap booted\n"); } }