1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1676 jpk * Common Development and Distribution License (the "License"). 6 1676 jpk * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 9393 Roger 22 0 stevel /* 23 9160 Sherry * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel /* Copyright (c) 1988 AT&T */ 28 0 stevel /* All Rights Reserved */ 29 0 stevel 30 0 stevel #include <sys/types.h> 31 0 stevel #include <sys/param.h> 32 0 stevel #include <sys/sysmacros.h> 33 0 stevel #include <sys/pcb.h> 34 0 stevel #include <sys/systm.h> 35 0 stevel #include <sys/signal.h> 36 0 stevel #include <sys/cred.h> 37 0 stevel #include <sys/user.h> 38 0 stevel #include <sys/vfs.h> 39 0 stevel #include <sys/vnode.h> 40 0 stevel #include <sys/proc.h> 41 0 stevel #include <sys/time.h> 42 0 stevel #include <sys/file.h> 43 0 stevel #include <sys/priocntl.h> 44 0 stevel #include <sys/procset.h> 45 0 stevel #include <sys/disp.h> 46 0 stevel #include <sys/callo.h> 47 0 stevel #include <sys/callb.h> 48 0 stevel #include <sys/debug.h> 49 0 stevel #include <sys/conf.h> 50 0 stevel #include <sys/bootconf.h> 51 0 stevel #include <sys/utsname.h> 52 0 stevel #include <sys/cmn_err.h> 53 0 stevel #include <sys/vmparam.h> 54 0 stevel #include <sys/modctl.h> 55 0 stevel #include <sys/vm.h> 56 0 stevel #include <sys/callb.h> 57 5107 eota #include <sys/ddi_timer.h> 58 0 stevel #include <sys/kmem.h> 59 0 stevel #include <sys/vmem.h> 60 0 stevel #include <sys/cpuvar.h> 61 0 stevel #include <sys/cladm.h> 62 0 stevel #include <sys/corectl.h> 63 0 stevel #include <sys/exec.h> 64 0 stevel #include <sys/syscall.h> 65 0 stevel #include <sys/reboot.h> 66 0 stevel #include <sys/task.h> 67 0 stevel #include <sys/exacct.h> 68 0 stevel #include <sys/autoconf.h> 69 0 stevel #include <sys/errorq.h> 70 0 stevel #include <sys/class.h> 71 0 stevel #include <sys/stack.h> 72 2712 nn35248 #include <sys/brand.h> 73 8212 Michael #include <sys/mmapobj.h> 74 0 stevel 75 0 stevel #include <vm/as.h> 76 0 stevel #include <vm/seg_kmem.h> 77 0 stevel #include <sys/dc_ki.h> 78 0 stevel 79 0 stevel #include <c2/audit.h> 80 8194 Jack #include <sys/bootprops.h> 81 0 stevel 82 0 stevel /* well known processes */ 83 0 stevel proc_t *proc_sched; /* memory scheduler */ 84 0 stevel proc_t *proc_init; /* init */ 85 0 stevel proc_t *proc_pageout; /* pageout daemon */ 86 0 stevel proc_t *proc_fsflush; /* fsflush daemon */ 87 0 stevel 88 0 stevel pgcnt_t maxmem; /* Maximum available memory in pages. */ 89 0 stevel pgcnt_t freemem; /* Current available memory in pages. */ 90 0 stevel int audit_active; 91 0 stevel int interrupts_unleashed; /* set when we do the first spl0() */ 92 0 stevel 93 0 stevel kmem_cache_t *process_cache; /* kmem cache for proc structures */ 94 0 stevel 95 0 stevel /* 96 0 stevel * Process 0's lwp directory and lwpid hash table. 97 0 stevel */ 98 0 stevel lwpdir_t p0_lwpdir[2]; 99 9393 Roger tidhash_t p0_tidhash[2]; 100 0 stevel lwpent_t p0_lep; 101 0 stevel 102 0 stevel /* 103 0 stevel * Machine-independent initialization code 104 0 stevel * Called from cold start routine as 105 0 stevel * soon as a stack and segmentation 106 0 stevel * have been established. 107 0 stevel * Functions: 108 0 stevel * clear and free user core 109 0 stevel * turn on clock 110 0 stevel * hand craft 0th process 111 0 stevel * call all initialization routines 112 0 stevel * fork - process 0 to schedule 113 0 stevel * - process 1 execute bootstrap 114 0 stevel * - process 2 to page out 115 0 stevel * create system threads 116 0 stevel */ 117 0 stevel 118 0 stevel int cluster_bootflags = 0; 119 0 stevel 120 0 stevel void 121 0 stevel cluster_wrapper(void) 122 0 stevel { 123 0 stevel cluster(); 124 0 stevel panic("cluster() returned"); 125 0 stevel } 126 0 stevel 127 2267 dp char initname[INITNAME_SZ] = "/sbin/init"; /* also referenced by zone0 */ 128 2267 dp char initargs[BOOTARGS_MAX] = ""; /* also referenced by zone0 */ 129 2712 nn35248 extern int64_t lwp_sigmask(int, uint_t, uint_t); 130 0 stevel 131 0 stevel /* 132 2267 dp * Construct a stack for init containing the arguments to it, then 133 2267 dp * pass control to exec_common. 134 0 stevel */ 135 2267 dp int 136 2267 dp exec_init(const char *initpath, const char *args) 137 0 stevel { 138 2267 dp caddr32_t ucp; 139 0 stevel caddr32_t *uap; 140 2267 dp caddr32_t *argv; 141 2267 dp caddr32_t exec_fnamep; 142 2267 dp char *scratchargs; 143 2267 dp int i, sarg; 144 2267 dp size_t argvlen, alen; 145 2267 dp boolean_t in_arg; 146 0 stevel int argc = 0; 147 2267 dp int error = 0, count = 0; 148 0 stevel proc_t *p = ttoproc(curthread); 149 0 stevel klwp_t *lwp = ttolwp(curthread); 150 2712 nn35248 int brand_action; 151 0 stevel 152 2267 dp if (args == NULL) 153 2267 dp args = ""; 154 0 stevel 155 2267 dp alen = strlen(initpath) + 1 + strlen(args) + 1; 156 2267 dp scratchargs = kmem_alloc(alen, KM_SLEEP); 157 2267 dp (void) snprintf(scratchargs, alen, "%s %s", initpath, args); 158 0 stevel 159 0 stevel /* 160 2267 dp * We do a quick two state parse of the string to sort out how big 161 2267 dp * argc should be. 162 0 stevel */ 163 2267 dp in_arg = B_FALSE; 164 2267 dp for (i = 0; i < strlen(scratchargs); i++) { 165 2267 dp if (scratchargs[i] == ' ' || scratchargs[i] == '\0') { 166 2267 dp if (in_arg) { 167 2267 dp in_arg = B_FALSE; 168 2267 dp argc++; 169 2267 dp } 170 2267 dp } else { 171 2267 dp in_arg = B_TRUE; 172 2267 dp } 173 2267 dp } 174 2267 dp argvlen = sizeof (caddr32_t) * (argc + 1); 175 2267 dp argv = kmem_zalloc(argvlen, KM_SLEEP); 176 2267 dp 177 2267 dp /* 178 2267 dp * We pull off a bit of a hack here. We work our way through the 179 2267 dp * args string, putting nulls at the ends of space delimited tokens 180 2267 dp * (boot args don't support quoting at this time). Then we just 181 2267 dp * copy the whole mess to userland in one go. In other words, we 182 2267 dp * transform this: "init -s -r\0" into this on the stack: 183 2267 dp * 184 2267 dp * -0x00 \0 185 2267 dp * -0x01 r 186 2267 dp * -0x02 - <--------. 187 2267 dp * -0x03 \0 | 188 2267 dp * -0x04 s | 189 2267 dp * -0x05 - <------. | 190 2267 dp * -0x06 \0 | | 191 2267 dp * -0x07 t | | 192 2267 dp * -0x08 i | | 193 2267 dp * -0x09 n | | 194 2267 dp * -0x0a i <---. | | 195 2267 dp * -0x10 NULL | | | (argv[3]) 196 2267 dp * -0x14 -----|--|-' (argv[2]) 197 2267 dp * -0x18 ------|--' (argv[1]) 198 2267 dp * -0x1c -------' (argv[0]) 199 2267 dp * 200 2267 dp * Since we know the value of ucp at the beginning of this process, 201 2267 dp * we can trivially compute the argv[] array which we also need to 202 2267 dp * place in userland: argv[i] = ucp - sarg(i), where ucp is the 203 2267 dp * stack ptr, and sarg is the string index of the start of the 204 2267 dp * argument. 205 2267 dp */ 206 2267 dp ucp = (caddr32_t)(uintptr_t)p->p_usrstack; 207 2267 dp 208 2267 dp argc = 0; 209 2267 dp in_arg = B_FALSE; 210 2267 dp sarg = 0; 211 2267 dp 212 2267 dp for (i = 0; i < alen; i++) { 213 2267 dp if (scratchargs[i] == ' ' || scratchargs[i] == '\0') { 214 2267 dp if (in_arg == B_TRUE) { 215 2267 dp in_arg = B_FALSE; 216 2267 dp scratchargs[i] = '\0'; 217 2267 dp argv[argc++] = ucp - (alen - sarg); 218 2267 dp } 219 2267 dp } else if (in_arg == B_FALSE) { 220 2267 dp in_arg = B_TRUE; 221 2267 dp sarg = i; 222 2267 dp } 223 2267 dp } 224 2267 dp ucp -= alen; 225 2267 dp error |= copyout(scratchargs, (caddr_t)(uintptr_t)ucp, alen); 226 2267 dp 227 0 stevel uap = (caddr32_t *)P2ALIGN((uintptr_t)ucp, sizeof (caddr32_t)); 228 2267 dp uap--; /* advance to be below the word we're in */ 229 2267 dp uap -= (argc + 1); /* advance argc words down, plus one for NULL */ 230 2267 dp error |= copyout(argv, uap, argvlen); 231 0 stevel 232 0 stevel if (error != 0) { 233 0 stevel zcmn_err(p->p_zone->zone_id, CE_WARN, 234 0 stevel "Could not construct stack for init.\n"); 235 2267 dp kmem_free(argv, argvlen); 236 2267 dp kmem_free(scratchargs, alen); 237 0 stevel return (EFAULT); 238 0 stevel } 239 2267 dp 240 2267 dp exec_fnamep = argv[0]; 241 2267 dp kmem_free(argv, argvlen); 242 2267 dp kmem_free(scratchargs, alen); 243 0 stevel 244 0 stevel /* 245 0 stevel * Point at the arguments. 246 0 stevel */ 247 0 stevel lwp->lwp_ap = lwp->lwp_arg; 248 2267 dp lwp->lwp_arg[0] = (uintptr_t)exec_fnamep; 249 0 stevel lwp->lwp_arg[1] = (uintptr_t)uap; 250 0 stevel lwp->lwp_arg[2] = NULL; 251 0 stevel curthread->t_post_sys = 1; 252 0 stevel curthread->t_sysnum = SYS_execve; 253 0 stevel 254 2712 nn35248 /* 255 2712 nn35248 * If we are executing init from zsched, we may have inherited its 256 2712 nn35248 * parent process's signal mask. Clear it now so that we behave in 257 2712 nn35248 * the same way as when started from the global zone. 258 2712 nn35248 */ 259 2712 nn35248 (void) lwp_sigmask(SIG_UNBLOCK, 0xffffffff, 0xffffffff); 260 2712 nn35248 261 2712 nn35248 brand_action = ZONE_IS_BRANDED(p->p_zone) ? EBA_BRAND : EBA_NONE; 262 0 stevel again: 263 2267 dp error = exec_common((const char *)(uintptr_t)exec_fnamep, 264 2712 nn35248 (const char **)(uintptr_t)uap, NULL, brand_action); 265 0 stevel 266 0 stevel /* 267 0 stevel * Normally we would just set lwp_argsaved and t_post_sys and 268 0 stevel * let post_syscall reset lwp_ap for us. Unfortunately, 269 0 stevel * exec_init isn't always called from a system call. Instead 270 0 stevel * of making a mess of trap_cleanup, we just reset the args 271 0 stevel * pointer here. 272 0 stevel */ 273 0 stevel reset_syscall_args(); 274 0 stevel 275 0 stevel switch (error) { 276 0 stevel case 0: 277 0 stevel return (0); 278 0 stevel 279 0 stevel case ENOENT: 280 0 stevel zcmn_err(p->p_zone->zone_id, CE_WARN, 281 0 stevel "exec(%s) failed (file not found).\n", initpath); 282 0 stevel return (ENOENT); 283 0 stevel 284 0 stevel case EAGAIN: 285 0 stevel case EINTR: 286 0 stevel ++count; 287 0 stevel if (count < 5) { 288 0 stevel zcmn_err(p->p_zone->zone_id, CE_WARN, 289 0 stevel "exec(%s) failed with errno %d. Retrying...\n", 290 0 stevel initpath, error); 291 0 stevel goto again; 292 0 stevel } 293 0 stevel } 294 0 stevel 295 0 stevel zcmn_err(p->p_zone->zone_id, CE_WARN, 296 0 stevel "exec(%s) failed with errno %d.", initpath, error); 297 0 stevel return (error); 298 2267 dp } 299 2267 dp 300 2267 dp /* 301 2267 dp * This routine does all of the common setup for invoking init; global 302 2267 dp * and non-global zones employ this routine for the functionality which is 303 2267 dp * in common. 304 2267 dp * 305 2267 dp * This program (init, presumably) must be a 32-bit process. 306 2267 dp */ 307 2267 dp int 308 2267 dp start_init_common() 309 2267 dp { 310 2267 dp proc_t *p = curproc; 311 2267 dp ASSERT_STACK_ALIGNED(); 312 2267 dp p->p_zone->zone_proc_initpid = p->p_pid; 313 2267 dp 314 2267 dp p->p_cstime = p->p_stime = p->p_cutime = p->p_utime = 0; 315 2267 dp p->p_usrstack = (caddr_t)USRSTACK32; 316 2267 dp p->p_model = DATAMODEL_ILP32; 317 2267 dp p->p_stkprot = PROT_ZFOD & ~PROT_EXEC; 318 2267 dp p->p_datprot = PROT_ZFOD & ~PROT_EXEC; 319 2267 dp p->p_stk_ctl = INT32_MAX; 320 2267 dp 321 2267 dp p->p_as = as_alloc(); 322 2768 sl108498 p->p_as->a_proc = p; 323 2267 dp p->p_as->a_userlimit = (caddr_t)USERLIMIT32; 324 2267 dp (void) hat_setup(p->p_as->a_hat, HAT_INIT); 325 2267 dp 326 2267 dp init_core(); 327 2267 dp 328 2267 dp init_mstate(curthread, LMS_SYSTEM); 329 2267 dp return (exec_init(p->p_zone->zone_initname, p->p_zone->zone_bootargs)); 330 2267 dp } 331 2267 dp 332 2267 dp /* 333 2267 dp * Start the initial user process for the global zone; once running, if 334 2267 dp * init should subsequently fail, it will be automatically be caught in the 335 2267 dp * exit(2) path, and restarted by restart_init(). 336 2267 dp */ 337 2267 dp static void 338 2267 dp start_init(void) 339 2267 dp { 340 2267 dp proc_init = curproc; 341 2267 dp 342 2267 dp ASSERT(curproc->p_zone->zone_initname != NULL); 343 2267 dp 344 2267 dp if (start_init_common() != 0) 345 2267 dp halt("unix: Could not start init"); 346 2267 dp lwp_rtt(); 347 0 stevel } 348 0 stevel 349 0 stevel void 350 0 stevel main(void) 351 0 stevel { 352 0 stevel proc_t *p = ttoproc(curthread); /* &p0 */ 353 0 stevel int (**initptr)(); 354 0 stevel extern void sched(); 355 0 stevel extern void fsflush(); 356 0 stevel extern int (*init_tbl[])(); 357 0 stevel extern int (*mp_init_tbl[])(); 358 0 stevel extern id_t syscid, defaultcid; 359 0 stevel extern int swaploaded; 360 0 stevel extern int netboot; 361 8194 Jack extern ib_boot_prop_t *iscsiboot_prop; 362 0 stevel extern void vm_init(void); 363 7039 mrj extern void cbe_init_pre(void); 364 0 stevel extern void cbe_init(void); 365 5788 mv143129 extern void clock_tick_init_pre(void); 366 5788 mv143129 extern void clock_tick_init_post(void); 367 0 stevel extern void clock_init(void); 368 0 stevel extern void physio_bufs_init(void); 369 0 stevel extern void pm_cfb_setup_intr(void); 370 0 stevel extern int pm_adjust_timestamps(dev_info_t *, void *); 371 0 stevel extern void start_other_cpus(int); 372 0 stevel extern void sysevent_evc_thrinit(); 373 4667 mh27603 #if defined(__x86) 374 9160 Sherry extern void fastboot_post_startup(void); 375 4667 mh27603 #endif 376 0 stevel /* 377 0 stevel * In the horrible world of x86 in-lines, you can't get symbolic 378 0 stevel * structure offsets a la genassym. This assertion is here so 379 0 stevel * that the next poor slob who innocently changes the offset of 380 0 stevel * cpu_thread doesn't waste as much time as I just did finding 381 0 stevel * out that it's hard-coded in i86/ml/i86.il. Similarly for 382 0 stevel * curcpup. You're welcome. 383 0 stevel */ 384 0 stevel ASSERT(CPU == CPU->cpu_self); 385 0 stevel ASSERT(curthread == CPU->cpu_thread); 386 0 stevel ASSERT_STACK_ALIGNED(); 387 0 stevel 388 0 stevel /* 389 10710 jonathan * Setup root lgroup and leaf lgroup for CPU 0 390 0 stevel */ 391 10710 jonathan lgrp_init(LGRP_INIT_STAGE2); 392 0 stevel 393 4036 praks /* 394 4036 praks * Once 'startup()' completes, the thread_reaper() daemon would be 395 4036 praks * created(in thread_init()). After that, it is safe to create threads 396 4036 praks * that could exit. These exited threads will get reaped. 397 4036 praks */ 398 0 stevel startup(); 399 0 stevel segkmem_gc(); 400 0 stevel callb_init(); 401 7039 mrj cbe_init_pre(); /* x86 must initialize gethrtimef before timer_init */ 402 5107 eota timer_init(); /* timer must be initialized before cyclic starts */ 403 0 stevel cbe_init(); 404 8048 Madhavan callout_init(); /* callout table MUST be init'd after cyclics */ 405 5788 mv143129 clock_tick_init_pre(); 406 0 stevel clock_init(); 407 0 stevel 408 0 stevel /* 409 3446 mrj * On some platforms, clkinitf() changes the timing source that 410 3446 mrj * gethrtime_unscaled() uses to generate timestamps. cbe_init() calls 411 3446 mrj * clkinitf(), so re-initialize the microstate counters after the 412 3446 mrj * timesource has been chosen. 413 3446 mrj */ 414 3446 mrj init_mstate(&t0, LMS_SYSTEM); 415 3446 mrj init_cpu_mstate(CPU, CMS_SYSTEM); 416 3446 mrj 417 3446 mrj /* 418 0 stevel * May need to probe to determine latencies from CPU 0 after 419 0 stevel * gethrtime() comes alive in cbe_init() and before enabling interrupts 420 10710 jonathan * and copy and release any temporary memory allocated with BOP_ALLOC() 421 10710 jonathan * before release_bootstrap() frees boot memory 422 0 stevel */ 423 10710 jonathan lgrp_init(LGRP_INIT_STAGE3); 424 0 stevel 425 0 stevel /* 426 0 stevel * Call all system initialization functions. 427 0 stevel */ 428 0 stevel for (initptr = &init_tbl[0]; *initptr; initptr++) 429 0 stevel (**initptr)(); 430 8194 Jack /* 431 8194 Jack * Load iSCSI boot properties 432 8194 Jack */ 433 8194 Jack ld_ib_prop(); 434 0 stevel /* 435 0 stevel * initialize vm related stuff. 436 0 stevel */ 437 0 stevel vm_init(); 438 0 stevel 439 0 stevel /* 440 0 stevel * initialize buffer pool for raw I/O requests 441 0 stevel */ 442 0 stevel physio_bufs_init(); 443 0 stevel 444 0 stevel ttolwp(curthread)->lwp_error = 0; /* XXX kludge for SCSI driver */ 445 0 stevel 446 0 stevel /* 447 0 stevel * Drop the interrupt level and allow interrupts. At this point 448 0 stevel * the DDI guarantees that interrupts are enabled. 449 0 stevel */ 450 0 stevel (void) spl0(); 451 0 stevel interrupts_unleashed = 1; 452 0 stevel 453 11173 Jonathan /* 454 11173 Jonathan * Create kmem cache for proc structures 455 11173 Jonathan */ 456 11173 Jonathan process_cache = kmem_cache_create("process_cache", sizeof (proc_t), 457 11173 Jonathan 0, NULL, NULL, NULL, NULL, NULL, 0); 458 11173 Jonathan 459 0 stevel vfs_mountroot(); /* Mount the root file system */ 460 0 stevel errorq_init(); /* after vfs_mountroot() so DDI root is ready */ 461 0 stevel cpu_kstat_init(CPU); /* after vfs_mountroot() so TOD is valid */ 462 0 stevel ddi_walk_devs(ddi_root_node(), pm_adjust_timestamps, NULL); 463 0 stevel /* after vfs_mountroot() so hrestime is valid */ 464 0 stevel 465 0 stevel post_startup(); 466 0 stevel swaploaded = 1; 467 0 stevel 468 0 stevel /* 469 5753 gww * Initialize Solaris Audit Subsystem 470 0 stevel */ 471 5753 gww audit_init(); 472 0 stevel 473 0 stevel /* 474 0 stevel * Plumb the protocol modules and drivers only if we are not 475 0 stevel * networked booted, in this case we already did it in rootconf(). 476 0 stevel */ 477 8194 Jack if (netboot == 0 && iscsiboot_prop == NULL) 478 0 stevel (void) strplumb(); 479 0 stevel 480 3446 mrj gethrestime(&PTOU(curproc)->u_start); 481 3446 mrj curthread->t_start = PTOU(curproc)->u_start.tv_sec; 482 0 stevel p->p_mstart = gethrtime(); 483 0 stevel 484 0 stevel /* 485 0 stevel * Perform setup functions that can only be done after root 486 0 stevel * and swap have been set up. 487 0 stevel */ 488 0 stevel consconfig(); 489 10182 bijan #ifndef __sparc 490 10182 bijan release_bootstrap(); 491 10182 bijan #endif 492 5974 jm22469 493 0 stevel /* 494 0 stevel * attach drivers with ddi-forceattach prop 495 0 stevel * This must be done after consconfig() to prevent usb key/mouse 496 0 stevel * from attaching before the upper console stream is plumbed. 497 0 stevel * It must be done early enough to load hotplug drivers (e.g. 498 0 stevel * pcmcia nexus) so that devices enumerated via hotplug is 499 0 stevel * available before I/O subsystem is fully initialized. 500 0 stevel */ 501 0 stevel i_ddi_forceattach_drivers(); 502 0 stevel 503 0 stevel /* 504 0 stevel * Set the scan rate and other parameters of the paging subsystem. 505 0 stevel */ 506 0 stevel setupclock(0); 507 0 stevel 508 0 stevel /* 509 0 stevel * Initialize process 0's lwp directory and lwpid hash table. 510 0 stevel */ 511 0 stevel p->p_lwpdir = p->p_lwpfree = p0_lwpdir; 512 0 stevel p->p_lwpdir->ld_next = p->p_lwpdir + 1; 513 0 stevel p->p_lwpdir_sz = 2; 514 0 stevel p->p_tidhash = p0_tidhash; 515 0 stevel p->p_tidhash_sz = 2; 516 0 stevel p0_lep.le_thread = curthread; 517 0 stevel p0_lep.le_lwpid = curthread->t_tid; 518 0 stevel p0_lep.le_start = curthread->t_start; 519 9393 Roger lwp_hash_in(p, &p0_lep, p0_tidhash, 2, 0); 520 0 stevel 521 0 stevel /* 522 0 stevel * Initialize extended accounting. 523 0 stevel */ 524 0 stevel exacct_init(); 525 0 stevel 526 0 stevel /* 527 0 stevel * Initialize threads of sysevent event channels 528 0 stevel */ 529 0 stevel sysevent_evc_thrinit(); 530 0 stevel 531 0 stevel /* 532 10710 jonathan * This must be done after post_startup() but before 533 0 stevel * start_other_cpus() 534 0 stevel */ 535 10710 jonathan lgrp_init(LGRP_INIT_STAGE4); 536 0 stevel 537 0 stevel /* 538 0 stevel * Perform MP initialization, if any. 539 0 stevel */ 540 0 stevel start_other_cpus(0); 541 10106 Jason 542 10182 bijan #ifdef __sparc 543 10106 Jason /* 544 10106 Jason * Release bootstrap here since PROM interfaces are 545 10106 Jason * used to start other CPUs above. 546 10106 Jason */ 547 10106 Jason release_bootstrap(); 548 10182 bijan #endif 549 0 stevel 550 0 stevel /* 551 0 stevel * Finish lgrp initialization after all CPUS are brought online. 552 0 stevel */ 553 10710 jonathan lgrp_init(LGRP_INIT_STAGE5); 554 0 stevel 555 0 stevel /* 556 0 stevel * After mp_init(), number of cpus are known (this is 557 0 stevel * true for the time being, when there are actually 558 0 stevel * hot pluggable cpus then this scheme would not do). 559 0 stevel * Any per cpu initialization is done here. 560 0 stevel */ 561 0 stevel kmem_mp_init(); 562 0 stevel vmem_update(NULL); 563 0 stevel 564 5788 mv143129 clock_tick_init_post(); 565 5788 mv143129 566 0 stevel for (initptr = &mp_init_tbl[0]; *initptr; initptr++) 567 0 stevel (**initptr)(); 568 0 stevel 569 0 stevel /* 570 4667 mh27603 * These must be called after start_other_cpus 571 0 stevel */ 572 0 stevel pm_cfb_setup_intr(); 573 4667 mh27603 #if defined(__x86) 574 9160 Sherry fastboot_post_startup(); 575 4667 mh27603 #endif 576 0 stevel 577 0 stevel /* 578 0 stevel * Make init process; enter scheduling loop with system process. 579 11173 Jonathan * 580 11173 Jonathan * Note that we manually assign the pids for these processes, for 581 11173 Jonathan * historical reasons. If more pre-assigned pids are needed, 582 11173 Jonathan * FAMOUS_PIDS will have to be updated. 583 0 stevel */ 584 0 stevel 585 0 stevel /* create init process */ 586 11173 Jonathan if (newproc(start_init, NULL, defaultcid, 59, NULL, 587 11173 Jonathan FAMOUS_PID_INIT)) 588 0 stevel panic("main: unable to fork init."); 589 0 stevel 590 0 stevel /* create pageout daemon */ 591 11173 Jonathan if (newproc(pageout, NULL, syscid, maxclsyspri - 1, NULL, 592 11173 Jonathan FAMOUS_PID_PAGEOUT)) 593 0 stevel panic("main: unable to fork pageout()"); 594 0 stevel 595 0 stevel /* create fsflush daemon */ 596 11173 Jonathan if (newproc(fsflush, NULL, syscid, minclsyspri, NULL, 597 11173 Jonathan FAMOUS_PID_FSFLUSH)) 598 0 stevel panic("main: unable to fork fsflush()"); 599 0 stevel 600 0 stevel /* create cluster process if we're a member of one */ 601 0 stevel if (cluster_bootflags & CLUSTER_BOOTED) { 602 11173 Jonathan if (newproc(cluster_wrapper, NULL, syscid, minclsyspri, 603 11173 Jonathan NULL, 0)) { 604 0 stevel panic("main: unable to fork cluster()"); 605 11173 Jonathan } 606 0 stevel } 607 0 stevel 608 0 stevel /* 609 0 stevel * Create system threads (threads are associated with p0) 610 0 stevel */ 611 0 stevel 612 0 stevel /* create module uninstall daemon */ 613 0 stevel /* BugID 1132273. If swapping over NFS need a bigger stack */ 614 0 stevel (void) thread_create(NULL, 0, (void (*)())mod_uninstall_daemon, 615 0 stevel NULL, 0, &p0, TS_RUN, minclsyspri); 616 0 stevel 617 0 stevel (void) thread_create(NULL, 0, seg_pasync_thread, 618 0 stevel NULL, 0, &p0, TS_RUN, minclsyspri); 619 0 stevel 620 0 stevel pid_setmin(); 621 0 stevel 622 3446 mrj bcopy("sched", PTOU(curproc)->u_psargs, 6); 623 3446 mrj bcopy("sched", PTOU(curproc)->u_comm, 5); 624 0 stevel sched(); 625 0 stevel /* NOTREACHED */ 626 0 stevel } 627