Newer
Older

Frans Kaashoek
committed
static void enterothers(void);
// Allocate a real stack and switch to it, first
// doing some setup required for memory allocator to work.

Frans Kaashoek
committed
kvmalloc(); // kernel page table
mpinit(); // collect info about this machine
seginit(); // set up segments
cprintf("\ncpu%d: starting xv6\n\n", cpu->id);
picinit(); // interrupt controller
ioapicinit(); // another interrupt controller
consoleinit(); // I/O devices & their interrupts
uartinit(); // serial port

Frans Kaashoek
committed
enterothers(); // start other processors (must come before kinit; must use boot_alloc)
kinit(); // initialize memory allocator
userinit(); // first user process (must come after kinit)

Frans Kaashoek
committed
// Other CPUs jump here from entryother.S.
seginit();
lapicinit(cpunum());
mpmain();
}
// Common CPU setup code.
static void
mpmain(void)
{

Frans Kaashoek
committed
xchg(&cpu->booted, 1); // tell enterothers() we're up
// Start the non-boot processors.

Frans Kaashoek
committed
enterothers(void)

Frans Kaashoek
committed
extern uchar _binary_entryother_start[], _binary_entryother_size[];
// Write bootstrap code to unused memory at 0x7000.

Frans Kaashoek
committed
// The linker has placed the image of entryother.S in
// _binary_entryother_start.

Frans Kaashoek
committed
memmove(code, _binary_entryother_start, (uint)_binary_entryother_size);

Frans Kaashoek
committed
// Tell entryother.S what stack to use, the address of mpboot and pgdir;
// We cannot use kpgdir yet, because the AP processor is running in low
// memory, so we use bootpgdir for the APs too. kalloc can return addresses
// above 4Mbyte (the machine may have much more physical memory than 4Mbyte), which
// aren't mapped by bootpgdir, so we must allocate a stack using boot_alloc();
// This introduces the constraint that xv6 cannot use kalloc until after these
// last boot_alloc invocations.
*(int**)(code-12) = (void *) v2p(bootpgdir);
// wait for cpu to finish mpmain()

Frans Kaashoek
committed
// Boot page table used in multiboot.S and entryother.S.

Frans Kaashoek
committed
// Page directories (and page tables), must start on a page boundary,
// hence the "__aligned__" attribute. Also, because of restrictions
// related to linking and static initializers, we use "x + PTE_P"
// here, rather than the more standard "x | PTE_P". Everywhere else
// you should use "|" to combine flags.
// Use PTE_PS in page directory entry to enable 4Mbyte pages.

Frans Kaashoek
committed
pte_t dev_pgtable[NPTENTRIES];
pte_t entry_pgtable[NPTENTRIES];

Frans Kaashoek
committed
__attribute__((__aligned__(PGSIZE)))
pde_t bootpgdir[NPDENTRIES] = {
// Map VA's [0, 4MB) to PA's [0, 4MB)
[0]

Frans Kaashoek
committed
// Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB)
[KERNBASE>>PDXSHIFT]

Frans Kaashoek
committed
};