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