// The bootstrap sequence is: // // call osinit // call schedinit // make & queue new G // call runtime·mstart // // The new G does: // // call main·init_function // call initdone // call main·main void runtime·schedinit(void) { int32 n; byte *p; runtime·allm = m; m->nomemprof++; runtime·mallocinit(); runtime·goargs(); runtime·goenvs(); // For debugging: // Allocate internal symbol table representation now, // so that we don't need to call malloc when we crash. // runtime·findfunc(0); runtime·gomaxprocs = 1; p = runtime·getenv("GOMAXPROCS"); if(p != nil && (n = runtime·atoi(p)) != 0) runtime·gomaxprocs = n; runtime·sched.mcpumax = runtime·gomaxprocs; runtime·sched.mcount = 1; runtime·sched.predawn = 1; m->nomemprof--; }
// The bootstrap sequence is: // // call osinit // call schedinit // make & queue new G // call runtime·mstart // // The new G calls runtime·main. void runtime·schedinit(void) { int32 n; byte *p; m->nomemprof++; runtime·mprofinit(); runtime·mallocinit(); mcommoninit(m); runtime·goargs(); runtime·goenvs(); // For debugging: // Allocate internal symbol table representation now, // so that we don't need to call malloc when we crash. // runtime·findfunc(0); runtime·gomaxprocs = 1; p = runtime·getenv("GOMAXPROCS"); if(p != nil && (n = runtime·atoi(p)) != 0) { if(n > maxgomaxprocs) n = maxgomaxprocs; runtime·gomaxprocs = n; } // wait for the main goroutine to start before taking // GOMAXPROCS into account. setmcpumax(1); runtime·singleproc = runtime·gomaxprocs == 1; canaddmcpu(); // mcpu++ to account for bootstrap m m->helpgc = 1; // flag to tell schedule() to mcpu-- runtime·sched.grunning++; mstats.enablegc = 1; m->nomemprof--; if(raceenabled) runtime·raceinit(); }
// The bootstrap sequence is: // // call osinit // call schedinit // make & queue new G // call runtime·mstart // // The new G calls runtime·main. void runtime·schedinit(void) { int32 n; byte *p; m->nomemprof++; runtime·mallocinit(); mcommoninit(m); runtime·goargs(); runtime·goenvs(); // For debugging: // Allocate internal symbol table representation now, // so that we don't need to call malloc when we crash. // runtime·findfunc(0); runtime·gomaxprocs = 1; p = runtime·getenv("GOMAXPROCS"); if(p != nil && (n = runtime·atoi(p)) != 0) { if(n > maxgomaxprocs) n = maxgomaxprocs; runtime·gomaxprocs = n; } setmcpumax(runtime·gomaxprocs); runtime·singleproc = runtime·gomaxprocs == 1; canaddmcpu(); // mcpu++ to account for bootstrap m m->helpgc = 1; // flag to tell schedule() to mcpu-- runtime·sched.grunning++; mstats.enablegc = 1; m->nomemprof--; scvg = runtime·newproc1((byte*)runtime·MHeap_Scavenger, nil, 0, 0, runtime·schedinit); }
void main(u32int ax, u32int bx) { vlong hz; memset(edata, 0, end - edata); /* * ilock via i8250enable via i8250console * needs m->machno, sys->machptr[] set, and * also 'up' set to nil. */ cgapost(sizeof(uintptr)*8); memset(m, 0, sizeof(Mach)); m->machno = 0; m->online = 1; m->nixtype = NIXTC; sys->machptr[m->machno] = &sys->mach; m->stack = PTR2UINT(sys->machstk); m->vsvm = sys->vsvmpage; up = nil; active.nonline = 1; active.exiting = 0; active.nbooting = 0; asminit(); multiboot(ax, bx, 0); options(oargc, oargv); crapoptions(); /* * Need something for initial delays * until a timebase is worked out. */ m->cpuhz = 2000000000ll; m->cpumhz = 2000; cgainit(); i8250console("0"); consputs = cgaconsputs; vsvminit(MACHSTKSZ, NIXTC); conf.nmach = 1; fmtinit(); print("\nNIX\n"); if(vflag){ print("&ax = %#p, ax = %#ux, bx = %#ux\n", &ax, ax, bx); multiboot(ax, bx, vflag); } m->perf.period = 1; if((hz = archhz()) != 0ll){ m->cpuhz = hz; m->cyclefreq = hz; m->cpumhz = hz/1000000ll; } /* * Mmuinit before meminit because it * flushes the TLB via m->pml4->pa. */ mmuinit(); ioinit(); kbdinit(); meminit(); confinit(); archinit(); mallocinit(); /* * Acpiinit will cause the first malloc * call to happen. * If the system dies here it's probably due * to malloc not being initialised * correctly, or the data segment is misaligned * (it's amazing how far you can get with * things like that completely broken). */ acpiinit(); umeminit(); trapinit(); printinit(); /* * This is necessary with GRUB and QEMU. * Without it an interrupt can occur at a weird vector, * because the vector base is likely different, causing * havoc. Do it before any APIC initialisation. */ i8259init(32); procinit0(); mpsinit(maxcores); apiconline(); sipi(); timersinit(); kbdenable(); fpuinit(); psinit(conf.nproc); initimage(); links(); devtabreset(); pageinit(); swapinit(); userinit(); nixsquids(); testiccs(); print("schedinit...\n"); schedinit(); }
void main(uint32_t mbmagic, uint32_t mbaddress) { Mach *m = entrym; /* when we get here, entrym is set to core0 mach. */ sys->machptr[m->machno] = m; // Very special case for BSP only. Too many things // assume this is set. wrmsr(GSbase, PTR2UINT(&sys->machptr[m->machno])); if (machp() != m) panic("m and machp() are different!!\n"); assert(sizeof(Mach) <= PGSZ); /* * Check that our data is on the right boundaries. * This works because the immediate value is in code. */ if (x != 0x123456) panic("Data is not set up correctly\n"); memset(edata, 0, end - edata); m = (void *) (KZERO + 1048576 + 11*4096); sys = (void *) (KZERO + 1048576); /* * ilock via i8250enable via i8250console * needs m->machno, sys->machptr[] set, and * also 'up' set to nil. */ cgapost(sizeof(uintptr_t)*8); memset(m, 0, sizeof(Mach)); m->machno = 0; m->online = 1; m->nixtype = NIXTC; sys->machptr[m->machno] = &sys->mach; m->stack = PTR2UINT(sys->machstk); *(uintptr_t*)m->stack = STACKGUARD; m->vsvm = sys->vsvmpage; m->externup = (void *)0; active.nonline = 1; active.exiting = 0; active.nbooting = 0; asminit(); multiboot(mbmagic, mbaddress, 0); options(oargc, oargv); /* * Need something for initial delays * until a timebase is worked out. */ m->cpuhz = 2000000000ll; m->cpumhz = 2000; cgainit(); i8250console("0"); consputs = cgaconsputs; /* It all ends here. */ vsvminit(MACHSTKSZ, NIXTC, m); if (machp() != m) panic("After vsvminit, m and machp() are different"); sys->nmach = 1; fmtinit(); print("\nHarvey\n"); if(vflag){ multiboot(mbmagic, mbaddress, vflag); } m->perf.period = 1; if((hz = archhz()) != 0ll){ m->cpuhz = hz; m->cyclefreq = hz; m->cpumhz = hz/1000000ll; } //iprint("archhz returns 0x%lld\n", hz); //iprint("NOTE: if cpuidhz runs too fast, we get die early with a NULL pointer\n"); //iprint("So, until that's fixed, we bring up AP cores slowly. Sorry!\n"); /* * Mmuinit before meminit because it * flushes the TLB via m->pml4->pa. */ mmuinit(); ioinit(); meminit(); confinit(); archinit(); mallocinit(); /* test malloc. It's easier to find out it's broken here, * not deep in some call chain. * See next note. * void *v = malloc(1234); hi("v "); put64((uint64_t)v); hi("\n"); free(v); hi("free ok\n"); */ /* * Acpiinit will cause the first malloc * call to happen. * If the system dies here it's probably due * to malloc not being initialised * correctly, or the data segment is misaligned * (it's amazing how far you can get with * things like that completely broken). */ if (0){ acpiinit(); hi(" acpiinit();\n");} umeminit(); trapinit(); /* * This is necessary with GRUB and QEMU. * Without it an interrupt can occur at a weird vector, * because the vector base is likely different, causing * havoc. Do it before any APIC initialisation. */ i8259init(32); procinit0(); mpsinit(maxcores); apiconline(); /* Forcing to single core if desired */ if(!nosmp) { sipi(); } teardownidmap(m); timersinit(); fpuinit(); psinit(conf.nproc); initimage(); links(); keybinit(); keybenable(); mouseenable(); devtabreset(); pageinit(); swapinit(); userinit(); /* Forcing to single core if desired */ if(!nosmp) { nixsquids(); testiccs(); } print("CPU Freq. %dMHz\n", m->cpumhz); print("schedinit...\n"); schedinit(); }