| static void startothers(void); | |
| static void mpmain(void) __attribute__((noreturn)); | |
| extern pde_t *kpgdir; | |
| extern char end[]; // first address after kernel loaded from ELF file | |
| // Bootstrap processor starts running C code here. | |
| // Allocate a real stack and switch to it, first | |
| // doing some setup required for memory allocator to work. | |
| int | |
| main(void) | |
| { | |
| kinit1(end, P2V(4*1024*1024)); // phys page allocator | |
| kvmalloc(); // kernel page table | |
| mpinit(); // detect other processors | |
| lapicinit(); // interrupt controller | |
| seginit(); // segment descriptors | |
| picinit(); // disable pic | |
| ioapicinit(); // another interrupt controller | |
| consoleinit(); // console hardware | |
| uartinit(); // serial port | |
| pinit(); // process table | |
| tvinit(); // trap vectors | |
| binit(); // buffer cache | |
| buf_test_init(); | |
| fileinit(); // file table | |
| ideinit(); // disk | |
| startothers(); // start other processors | |
| kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() | |
| userinit(); // first user process | |
| sharedMemoryInit(); | |
| mpmain(); // finish this processor's setup | |
| } | |
| // Other CPUs jump here from entryother.S. | |
| static void | |
| mpenter(void) | |
| { | |
| switchkvm(); | |
| seginit(); | |
| lapicinit(); | |
| mpmain(); | |
| } | |
| // Common CPU setup code. | |
| static void | |
| mpmain(void) | |
| { | |
| cprintf("cpu%d: starting %d\n", cpuid(), cpuid()); | |
| idtinit(); // load idt register | |
| xchg(&(mycpu()->started), 1); // tell startothers() we're up | |
| scheduler(); // start running processes | |
| } | |
| pde_t entrypgdir[]; // For entry.S | |
| // Start the non-boot (AP) processors. | |
| static void | |
| startothers(void) | |
| { | |
| extern uchar _binary_entryother_start[], _binary_entryother_size[]; | |
| uchar *code; | |
| struct cpu *c; | |
| char *stack; | |
| // Write entry code to unused memory at 0x7000. | |
| // The linker has placed the image of entryother.S in | |
| // _binary_entryother_start. | |
| code = P2V(0x7000); | |
| memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); | |
| for(c = cpus; c < cpus+ncpu; c++){ | |
| if(c == mycpu()) // We've started already. | |
| continue; | |
| // Tell entryother.S what stack to use, where to enter, and what | |
| // pgdir to use. We cannot use kpgdir yet, because the AP processor | |
| // is running in low memory, so we use entrypgdir for the APs too. | |
| stack = kalloc(); | |
| *(void**)(code-4) = stack + KSTACKSIZE; | |
| *(void(**)(void))(code-8) = mpenter; | |
| *(int**)(code-12) = (void *) V2P(entrypgdir); | |
| lapicstartap(c->apicid, V2P(code)); | |
| // wait for cpu to finish mpmain() | |
| while(c->started == 0) | |
| ; | |
| } | |
| } | |
| // The boot page table used in entry.S and entryother.S. | |
| // Page directories (and page tables) must start on page boundaries, | |
| // hence the __aligned__ attribute. | |
| // PTE_PS in a page directory entry enables 4Mbyte pages. | |
| __attribute__((__aligned__(PGSIZE))) | |
| pde_t entrypgdir[NPDENTRIES] = { | |
| // Map VA's [0, 4MB) to PA's [0, 4MB) | |
| [0] = (0) | PTE_P | PTE_W | PTE_PS, | |
| // Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB) | |
| [KERNBASE>>PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS, | |
| }; | |
| //PAGEBREAK! | |
| // Blank page. | |
| //PAGEBREAK! | |
| // Blank page. | |
| //PAGEBREAK! | |
| // Blank page. | |
Xet Storage Details
- Size:
- 3.31 kB
- Xet hash:
- 693c92e29a77deb737cab30689f4c80c3dfa844565e48092a4be8cfe6c9007ca
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.