The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/startup.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991,1990,1989,1988 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        startup.c,v $
   29  * Revision 2.27  93/11/17  17:24:45  dbg
   30  *      Remove ancient timestamp facility.
   31  *      [93/06/18            dbg]
   32  * 
   33  *      Remove call to mapable_time_init.
   34  *      [93/06/07            dbg]
   35  * 
   36  *      Break up thread lock.
   37  *      [93/05/26            dbg]
   38  * 
   39  *      Declare continuations as returning 'no_return'.
   40  *      Call idle_thread_create to build idle threads.
   41  *      Call kernel_reply_kmsg_init.
   42  *      Initialize system clock after finding devices, since we now
   43  *      probe for the clock.
   44  *      Changes for selectable scheduler policies.
   45  *      [93/05/21            dbg]
   46  * 
   47  * Revision 2.26  93/05/15  18:55:03  mrt
   48  *      machparam.h -> machspl.h
   49  * 
   50  * Revision 2.25  93/01/14  17:36:31  danner
   51  *      Invoke printf_init() for multiP interlock setup.
   52  *      [92/12/01            af]
   53  * 
   54  * Revision 2.24  92/08/03  17:39:15  jfriedl
   55  *      removed silly prototypes
   56  *      [92/08/02            jfriedl]
   57  * 
   58  * Revision 2.23  92/05/21  17:15:47  jfriedl
   59  *      tried prototypes.
   60  *      [92/05/20            jfriedl]
   61  * 
   62  * Revision 2.22  92/01/27  16:43:18  rpd
   63  *      Fixed to finish vm/ipc initialization before calling machine_init.
   64  *      [92/01/25            rpd]
   65  * 
   66  * Revision 2.21  92/01/14  16:44:57  rpd
   67  *      Split vm_mem_init into vm_mem_bootstrap and vm_mem_init.
   68  *      [91/12/29            rpd]
   69  * 
   70  * Revision 2.20  91/09/12  16:38:00  bohman
   71  *      Changed launch_first_thread() to set active_stacks[] before
   72  *      starting the first thread.
   73  *      [91/09/11  17:08:23  bohman]
   74  * 
   75  * Revision 2.19  91/08/28  11:14:37  jsb
   76  *      Start NORMA ipc and vm systems before user bootstrap.
   77  *      [91/08/15  08:33:05  jsb]
   78  * 
   79  * Revision 2.18  91/08/03  18:18:59  jsb
   80  *      Changed NORMA specific startup again.
   81  *      [91/07/24  22:32:51  jsb]
   82  * 
   83  * Revision 2.17  91/07/31  17:48:00  dbg
   84  *      Remove interrupt_stack_alloc - not all multiprocessors use it.
   85  * 
   86  *      Revised scheduling state machine.
   87  *      [91/07/30  17:05:11  dbg]
   88  * 
   89  * Revision 2.16  91/06/17  15:47:15  jsb
   90  *      Renamed NORMA conditionals.
   91  *      [91/06/17  10:51:38  jsb]
   92  * 
   93  * Revision 2.15  91/06/06  17:07:27  jsb
   94  *      Changed NORMA_IPC specific startup.
   95  *      [91/05/14  09:19:55  jsb]
   96  * 
   97  * Revision 2.14  91/05/18  14:33:30  rpd
   98  *      Added argument to kernel_thread.
   99  *      [91/04/03            rpd]
  100  * 
  101  * Revision 2.13  91/05/14  16:47:00  mrt
  102  *      Correcting copyright
  103  * 
  104  * Revision 2.12  91/03/16  14:51:45  rpd
  105  *      Updated for new kmem_alloc interface.
  106  *      [91/03/03            rpd]
  107  *      Removed thread_swappable.
  108  *      [91/01/18            rpd]
  109  * 
  110  * Revision 2.11  91/02/05  17:29:18  mrt
  111  *      Changed to new Mach copyright
  112  *      [91/02/01  16:17:40  mrt]
  113  * 
  114  * Revision 2.10  91/01/08  15:17:00  rpd
  115  *      Swapin the startup thread and idle threads.
  116  *      [90/11/20            rpd]
  117  * 
  118  *      Removed swapout_thread.
  119  *      [90/11/11            rpd]
  120  * 
  121  * Revision 2.9  90/10/12  18:07:34  rpd
  122  *      Fixed call to thread_bind in start_kernel_threads.
  123  *      Fix from Philippe Bernadat.
  124  *      [90/10/10            rpd]
  125  * 
  126  * Revision 2.8  90/09/28  16:55:37  jsb
  127  *      Added NORMA_IPC support.
  128  *      [90/09/28  14:05:00  jsb]
  129  * 
  130  * Revision 2.7  90/09/09  14:32:47  rpd
  131  *      Fixed setup_main to call pset_sys_init.
  132  *      [90/08/30            rpd]
  133  * 
  134  * Revision 2.6  90/08/27  22:03:40  dbg
  135  *      Pass processor argument to choose_thread.
  136  *      Rename cpu_start to cpu_launch_first_thread to avoid conflict
  137  *      with processor code.
  138  *      [90/07/17            dbg]
  139  * 
  140  * Revision 2.5  90/06/02  14:56:12  rpd
  141  *      Start sched_thread.  On multiprocessors, start action_thread
  142  *      instead of shutdown_thread.
  143  *      [90/04/28            rpd]
  144  *      Updated to new scheduling technology.
  145  *      [90/03/26  22:19:00  rpd]
  146  * 
  147  * Revision 2.4  90/01/11  11:44:11  dbg
  148  *      If multiprocessor, start shutdown thread.  If uniprocessor,
  149  *      don't allocate interrupt stacks.
  150  *      [89/12/19            dbg]
  151  * 
  152  *      Add call to start other CPUs if multiprocessor.
  153  *      [89/12/01            dbg]
  154  * 
  155  * Revision 2.3  89/09/08  11:26:32  dbg
  156  *      Move kalloc initialization to vm_init.
  157  *      [89/09/06            dbg]
  158  * 
  159  *      Move bootstrap initialization to kern/bootstrap.c.  Initialize
  160  *      device service here.
  161  *      [89/08/02            dbg]
  162  * 
  163  *      Initialize kalloc package.
  164  *      [89/07/11            dbg]
  165  * 
  166  * Revision 2.2  89/08/05  16:07:22  rwd
  167  *      Call mappable_time_init.
  168  *      [89/08/04  18:31:35  rwd]
  169  * 
  170  * 23-May-89  David Golub (dbg) at Carnegie-Mellon University
  171  *      Thread creation must be done by a running thread;
  172  *      thread_setrun (called by thread_resume & kernel_thread) may look
  173  *      at current thread.
  174  *
  175  * 19-May-89  David Golub (dbg) at Carnegie-Mellon University
  176  *      Don't export first_task and first_thread; they don't last very
  177  *      long.
  178  *
  179  * 15-Aug-88  David Golub (dbg) at Carnegie-Mellon University
  180  *      Initial threads are now part of the kernel task, not first-task.
  181  *      Create the bootstrap task as a kernel task.
  182  *
  183  *  8-Aug-88  David Golub (dbg) at Carnegie-Mellon University
  184  *      Modified for stand-alone MACH kernel.
  185  *
  186  *  1-Jul-88  David Golub (dbg) at Carnegie-Mellon University
  187  *      Created.
  188  *
  189  */
  190 
  191 /*
  192  *      Mach kernel startup.
  193  */
  194 
  195 
  196 #include <xpr_debug.h>
  197 #include <cpus.h>
  198 #include <mach_host.h>
  199 #include <norma_ipc.h>
  200 #include <norma_vm.h>
  201 
  202 #include <mach/boolean.h>
  203 #include <mach/machine.h>
  204 #include <mach/task_special_ports.h>
  205 #include <mach/vm_param.h>
  206 
  207 #include <ipc/ipc_init.h>
  208 
  209 #include <kern/clock.h>
  210 #include <kern/cpu_number.h>
  211 #include <kern/kern_io.h>
  212 #include <kern/kern_kmsg.h>
  213 #include <kern/mach_timer.h>
  214 #include <kern/machine.h>
  215 #include <kern/processor.h>
  216 #include <kern/sched.h>
  217 #include <kern/sched_prim.h>
  218 #include <kern/task.h>
  219 #include <kern/thread.h>
  220 #include <kern/thread_swap.h>
  221 #include <kern/time_out.h>
  222 #include <kern/timer.h>
  223 #include <kern/xpr.h>
  224 #include <kern/zalloc.h>
  225 
  226 #include <sched_policy/standard.h>
  227 
  228 #include <vm/vm_kern.h>
  229 #include <vm/vm_map.h>
  230 #include <vm/vm_object.h>
  231 #include <vm/vm_page.h>
  232 #include <machine/machspl.h>
  233 #include <machine/pmap.h>
  234 #include <sys/version.h>
  235 
  236 
  237 /*
  238  *      Initialization routines in various subsystems.
  239  */
  240 
  241 extern void     vm_mem_init(void);
  242 extern void     vm_mem_bootstrap(void);
  243 
  244 extern no_return idle_thread(void);
  245 extern no_return vm_pageout(void);
  246 extern no_return reaper_thread(void);
  247 extern no_return swapin_thread(void);
  248 
  249 extern void     bootstrap_create(void);
  250 extern void     device_service_create(void);
  251 extern void     idle_thread_create(processor_t);
  252 
  253 no_return cpu_launch_first_thread(thread_t);    /* forward */
  254 no_return start_kernel_threads(void);           /* forward */
  255 
  256 extern no_return load_context(thread_t);
  257 
  258 /*
  259  *      Running in virtual memory, on the interrupt stack.
  260  *      Does not return.  Dispatches initial thread.
  261  *
  262  *      Assumes that master_cpu is set.
  263  */
  264 no_return setup_main(void)
  265 {
  266         thread_t                startup_thread;
  267 
  268         /*
  269          *      Allow printing and panics
  270          */
  271         printf_init();
  272         panic_init();
  273 
  274         /*
  275          *      Get VM running as soon as possible
  276          */
  277         vm_mem_bootstrap();             /* can do 'zinit' now */
  278 
  279         /*
  280          *      Initialize the low-level scheduling packages
  281          */
  282         sched_init();
  283         ast_init();
  284 #if     NCPUS > 1
  285         action_thread_init();           /* action queue */
  286 #endif
  287 
  288         /*
  289          *      Initialize packages that need VM and zones
  290          */
  291         sched_policy_init();            /* set up scheduling policies */
  292         pset_sys_bootstrap();           /* first pset: needs scheduling
  293                                            policies and quanta */
  294         ipc_bootstrap();                /* IPC system */
  295 
  296         /*
  297          *      Initialize packages that need IPC ports
  298          */
  299         vm_mem_init();                  /* rest of VM - needs IPC */
  300         ipc_init();                     /* rest of IPC - needs full VM */
  301         kernel_reply_kmsg_init();       /* kernel reply messages */
  302 
  303         /*
  304          * As soon as the virtual memory system is up, we record
  305          * that this CPU is using the kernel pmap.
  306          */
  307         PMAP_ACTIVATE_KERNEL(master_cpu);
  308 
  309         /*
  310          *      Set up all of the timers
  311          */
  312         init_timers();                  /* internal timers */
  313         mach_timer_init();              /* user-visible timers */
  314 
  315 #if     XPR_DEBUG
  316         xprbootstrap();
  317 #endif  /* XPR_DEBUG */
  318 
  319         /*
  320          *      Call machine-dependent initialization.
  321          *      This configures devices, among other things.
  322          */
  323         machine_init();
  324 
  325         machine_info.max_cpus = NCPUS;
  326         machine_info.memory_size = mem_size;
  327         machine_info.avail_cpus = 0;
  328         machine_info.major_version = KERNEL_MAJOR_VERSION;
  329         machine_info.minor_version = KERNEL_MINOR_VERSION;
  330 
  331         /*
  332          *      Initialize the task, thread, and processor set subsystems.
  333          */
  334         task_init();
  335         thread_init();
  336         swapper_init();
  337 #if     MACH_HOST
  338         pset_sys_init();
  339 #endif  /* MACH_HOST */
  340 
  341         /*
  342          *      Initialize the periodic scheduling calculations.
  343          */
  344         init_sched_calculations();
  345         
  346         /*
  347          *      Create a kernel thread to start the other kernel
  348          *      threads.  Thread_resume (from kernel_thread) calls
  349          *      thread_setrun, which may look at current thread;
  350          *      we must avoid this, since there is no current thread.
  351          */
  352 
  353         /*
  354          *      Enable the fixed priority policy on the default
  355          *      processor set.
  356          */
  357         (void) processor_set_policy_add(&default_pset, POLICY_FIXEDPRI,
  358                                         0, 0);
  359 
  360         /*
  361          *      Set fixed-priority as the default for the
  362          *      kernel task.
  363          */
  364     {
  365         struct policy_param_fixedpri    param;
  366 
  367         param.priority = FP_BASEPRI_SYSTEM;
  368         param.no_preempt = TRUE;
  369 
  370         (void) task_set_default_policy(kernel_task, &default_pset,
  371                                         POLICY_FIXEDPRI,
  372                                         (policy_param_t)&param,
  373                                         POLICY_PARAM_FIXEDPRI_COUNT,
  374                                         FALSE);
  375     }
  376 
  377         /*
  378          * Create the thread, and point it at the routine.
  379          */
  380         (void) thread_create(kernel_task, &startup_thread);
  381         thread_start(startup_thread, start_kernel_threads);
  382 
  383         /*
  384          * Give it a kernel stack.
  385          */
  386         thread_doswapin(startup_thread);
  387 
  388         /*
  389          * Pretend it is already running, and resume it.
  390          * Since it looks as if it is running, thread_resume
  391          * will not try to put it on the run queues.
  392          *
  393          * We can do all of this without locking, because nothing
  394          * else is running yet.
  395          */
  396         startup_thread->state |= TH_RUN;
  397         (void) thread_resume(startup_thread);
  398 
  399         /*
  400          * Start the thread.
  401          */
  402         cpu_launch_first_thread(startup_thread);
  403         /*NOTREACHED*/
  404 }
  405 
  406 /*
  407  * Now running in a thread.  Create the rest of the kernel threads
  408  * and the bootstrap task.
  409  */
  410 no_return start_kernel_threads(void)
  411 {
  412         register int    i;
  413 
  414         /*
  415          *      Create the idle threads and the other
  416          *      service threads.
  417          */
  418         for (i = 0; i < NCPUS; i++) {
  419             if (machine_slot[i].is_cpu) {
  420                 idle_thread_create(cpu_to_processor(i));
  421             }
  422         }
  423 
  424         (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
  425         (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
  426 
  427 #if     NCPUS > 1
  428         /*
  429          *      Create the shutdown thread.
  430          */
  431         (void) kernel_thread(kernel_task, action_thread, (char *) 0);
  432 
  433         /*
  434          *      Allow other CPUs to run.
  435          */
  436         start_other_cpus();
  437 #endif  /* NCPUS > 1 */
  438 
  439         /*
  440          *      Create the device service.
  441          */
  442         device_service_create();
  443 
  444         /*
  445          *      Initialize NORMA ipc system.
  446          */
  447 #if     NORMA_IPC
  448         norma_ipc_init();
  449 #endif  /* NORMA_IPC */
  450 
  451         /*
  452          *      Initialize NORMA vm system.
  453          */
  454 #if     NORMA_VM
  455         norma_vm_init();
  456 #endif  /* NORMA_VM */
  457 
  458         /*
  459          *      Start the user bootstrap.
  460          */
  461         bootstrap_create();
  462 
  463 #if     XPR_DEBUG
  464         xprinit();              /* XXX */
  465 #endif  /* XPR_DEBUG */
  466 
  467         /*
  468          *      Become the pageout daemon.
  469          */
  470         (void) spl0();
  471         vm_pageout();
  472         /*NOTREACHED*/
  473 }
  474 
  475 #if     NCPUS > 1
  476 
  477 /*
  478  *      Do system initialization for other processors.
  479  */
  480 no_return slave_main(void)
  481 {
  482         /*
  483          *      Do machine_specific initialization.
  484          */
  485         slave_machine_init();
  486 
  487         /*
  488          *      Run the processor`s idle thread first.
  489          */
  490         cpu_launch_first_thread(current_processor()->idle_thread);
  491 }
  492 #endif  /* NCPUS > 1 */
  493 
  494 /*
  495  *      Start up the first thread on a CPU.
  496  *      First thread is supplied.
  497  */
  498 no_return cpu_launch_first_thread(
  499         register thread_t       th)
  500 {
  501         register int    mycpu;
  502 
  503         mycpu = cpu_number();
  504 
  505         cpu_up(mycpu);
  506 
  507         start_timer(&kernel_timer[mycpu]);
  508 
  509         (void) splhigh();
  510 
  511         enable_clock_interrupts();      /* needs an active thread */
  512         PMAP_ACTIVATE_KERNEL(mycpu);
  513 
  514         active_threads[mycpu] = th;
  515         active_stacks[mycpu] = th->kernel_stack;
  516         thread_sched_lock(th);
  517         th->state &= ~TH_UNINT;
  518         thread_sched_unlock(th);
  519         timer_switch(&th->system_timer);
  520 
  521         PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu);
  522 
  523         load_context(th);
  524         /*NOTREACHED*/
  525 }

Cache object: 31d3cf70ddacc838e9337da07e46ff5d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.