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) 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.26  93/05/15  18:55:03  mrt
   30  *      machparam.h -> machspl.h
   31  * 
   32  * Revision 2.25  93/01/14  17:36:31  danner
   33  *      Invoke printf_init() for multiP interlock setup.
   34  *      [92/12/01            af]
   35  * 
   36  * Revision 2.24  92/08/03  17:39:15  jfriedl
   37  *      removed silly prototypes
   38  *      [92/08/02            jfriedl]
   39  * 
   40  * Revision 2.23  92/05/21  17:15:47  jfriedl
   41  *      tried prototypes.
   42  *      [92/05/20            jfriedl]
   43  * 
   44  * Revision 2.22  92/01/27  16:43:18  rpd
   45  *      Fixed to finish vm/ipc initialization before calling machine_init.
   46  *      [92/01/25            rpd]
   47  * 
   48  * Revision 2.21  92/01/14  16:44:57  rpd
   49  *      Split vm_mem_init into vm_mem_bootstrap and vm_mem_init.
   50  *      [91/12/29            rpd]
   51  * 
   52  * Revision 2.20  91/09/12  16:38:00  bohman
   53  *      Changed launch_first_thread() to set active_stacks[] before
   54  *      starting the first thread.
   55  *      [91/09/11  17:08:23  bohman]
   56  * 
   57  * Revision 2.19  91/08/28  11:14:37  jsb
   58  *      Start NORMA ipc and vm systems before user bootstrap.
   59  *      [91/08/15  08:33:05  jsb]
   60  * 
   61  * Revision 2.18  91/08/03  18:18:59  jsb
   62  *      Changed NORMA specific startup again.
   63  *      [91/07/24  22:32:51  jsb]
   64  * 
   65  * Revision 2.17  91/07/31  17:48:00  dbg
   66  *      Remove interrupt_stack_alloc - not all multiprocessors use it.
   67  * 
   68  *      Revised scheduling state machine.
   69  *      [91/07/30  17:05:11  dbg]
   70  * 
   71  * Revision 2.16  91/06/17  15:47:15  jsb
   72  *      Renamed NORMA conditionals.
   73  *      [91/06/17  10:51:38  jsb]
   74  * 
   75  * Revision 2.15  91/06/06  17:07:27  jsb
   76  *      Changed NORMA_IPC specific startup.
   77  *      [91/05/14  09:19:55  jsb]
   78  * 
   79  * Revision 2.14  91/05/18  14:33:30  rpd
   80  *      Added argument to kernel_thread.
   81  *      [91/04/03            rpd]
   82  * 
   83  * Revision 2.13  91/05/14  16:47:00  mrt
   84  *      Correcting copyright
   85  * 
   86  * Revision 2.12  91/03/16  14:51:45  rpd
   87  *      Updated for new kmem_alloc interface.
   88  *      [91/03/03            rpd]
   89  *      Removed thread_swappable.
   90  *      [91/01/18            rpd]
   91  * 
   92  * Revision 2.11  91/02/05  17:29:18  mrt
   93  *      Changed to new Mach copyright
   94  *      [91/02/01  16:17:40  mrt]
   95  * 
   96  * Revision 2.10  91/01/08  15:17:00  rpd
   97  *      Swapin the startup thread and idle threads.
   98  *      [90/11/20            rpd]
   99  * 
  100  *      Removed swapout_thread.
  101  *      [90/11/11            rpd]
  102  * 
  103  * Revision 2.9  90/10/12  18:07:34  rpd
  104  *      Fixed call to thread_bind in start_kernel_threads.
  105  *      Fix from Philippe Bernadat.
  106  *      [90/10/10            rpd]
  107  * 
  108  * Revision 2.8  90/09/28  16:55:37  jsb
  109  *      Added NORMA_IPC support.
  110  *      [90/09/28  14:05:00  jsb]
  111  * 
  112  * Revision 2.7  90/09/09  14:32:47  rpd
  113  *      Fixed setup_main to call pset_sys_init.
  114  *      [90/08/30            rpd]
  115  * 
  116  * Revision 2.6  90/08/27  22:03:40  dbg
  117  *      Pass processor argument to choose_thread.
  118  *      Rename cpu_start to cpu_launch_first_thread to avoid conflict
  119  *      with processor code.
  120  *      [90/07/17            dbg]
  121  * 
  122  * Revision 2.5  90/06/02  14:56:12  rpd
  123  *      Start sched_thread.  On multiprocessors, start action_thread
  124  *      instead of shutdown_thread.
  125  *      [90/04/28            rpd]
  126  *      Updated to new scheduling technology.
  127  *      [90/03/26  22:19:00  rpd]
  128  * 
  129  * Revision 2.4  90/01/11  11:44:11  dbg
  130  *      If multiprocessor, start shutdown thread.  If uniprocessor,
  131  *      don't allocate interrupt stacks.
  132  *      [89/12/19            dbg]
  133  * 
  134  *      Add call to start other CPUs if multiprocessor.
  135  *      [89/12/01            dbg]
  136  * 
  137  * Revision 2.3  89/09/08  11:26:32  dbg
  138  *      Move kalloc initialization to vm_init.
  139  *      [89/09/06            dbg]
  140  * 
  141  *      Move bootstrap initialization to kern/bootstrap.c.  Initialize
  142  *      device service here.
  143  *      [89/08/02            dbg]
  144  * 
  145  *      Initialize kalloc package.
  146  *      [89/07/11            dbg]
  147  * 
  148  * Revision 2.2  89/08/05  16:07:22  rwd
  149  *      Call mappable_time_init.
  150  *      [89/08/04  18:31:35  rwd]
  151  * 
  152  * 23-May-89  David Golub (dbg) at Carnegie-Mellon University
  153  *      Thread creation must be done by a running thread;
  154  *      thread_setrun (called by thread_resume & kernel_thread) may look
  155  *      at current thread.
  156  *
  157  * 19-May-89  David Golub (dbg) at Carnegie-Mellon University
  158  *      Don't export first_task and first_thread; they don't last very
  159  *      long.
  160  *
  161  * 15-Aug-88  David Golub (dbg) at Carnegie-Mellon University
  162  *      Initial threads are now part of the kernel task, not first-task.
  163  *      Create the bootstrap task as a kernel task.
  164  *
  165  *  8-Aug-88  David Golub (dbg) at Carnegie-Mellon University
  166  *      Modified for stand-alone MACH kernel.
  167  *
  168  *  1-Jul-88  David Golub (dbg) at Carnegie-Mellon University
  169  *      Created.
  170  *
  171  */
  172 
  173 /*
  174  *      Mach kernel startup.
  175  */
  176 
  177 
  178 #include <xpr_debug.h>
  179 #include <cpus.h>
  180 #include <mach_host.h>
  181 #include <norma_ipc.h>
  182 #include <norma_vm.h>
  183 
  184 #include <mach/boolean.h>
  185 #include <mach/machine.h>
  186 #include <mach/task_special_ports.h>
  187 #include <mach/vm_param.h>
  188 #include <ipc/ipc_init.h>
  189 #include <kern/cpu_number.h>
  190 #include <kern/processor.h>
  191 #include <kern/sched_prim.h>
  192 #include <kern/task.h>
  193 #include <kern/thread.h>
  194 #include <kern/thread_swap.h>
  195 #include <kern/time_out.h>
  196 #include <kern/timer.h>
  197 #include <kern/zalloc.h>
  198 #include <vm/vm_kern.h>
  199 #include <vm/vm_map.h>
  200 #include <vm/vm_object.h>
  201 #include <vm/vm_page.h>
  202 #include <machine/machspl.h>
  203 #include <machine/pmap.h>
  204 #include <sys/version.h>
  205 
  206 
  207 
  208 extern void     vm_mem_init();
  209 extern void     vm_mem_bootstrap();
  210 extern void     init_timeout();
  211 extern void     machine_init();
  212 
  213 extern void     idle_thread();
  214 extern void     vm_pageout();
  215 extern void     reaper_thread();
  216 extern void     swapin_thread();
  217 extern void     sched_thread();
  218 
  219 extern void     bootstrap_create();
  220 extern void     device_service_create();
  221 
  222 void cpu_launch_first_thread();         /* forward */
  223 void start_kernel_threads();    /* forward */
  224 
  225 #if     NCPUS > 1
  226 extern void     start_other_cpus();
  227 extern void     action_thread();
  228 #endif  NCPUS > 1
  229 
  230 /*
  231  *      Running in virtual memory, on the interrupt stack.
  232  *      Does not return.  Dispatches initial thread.
  233  *
  234  *      Assumes that master_cpu is set.
  235  */
  236 void setup_main()
  237 {
  238         thread_t                startup_thread;
  239 
  240         panic_init();
  241         printf_init();
  242 
  243         sched_init();
  244         vm_mem_bootstrap();
  245         ipc_bootstrap();
  246         vm_mem_init();
  247         ipc_init();
  248 
  249         /*
  250          * As soon as the virtual memory system is up, we record
  251          * that this CPU is using the kernel pmap.
  252          */
  253         PMAP_ACTIVATE_KERNEL(master_cpu);
  254 
  255         init_timers();
  256         init_timeout();
  257 
  258 #if     XPR_DEBUG
  259         xprbootstrap();
  260 #endif  XPR_DEBUG
  261 
  262         timestamp_init();
  263 
  264         mapable_time_init();
  265 
  266         machine_init();
  267 
  268         machine_info.max_cpus = NCPUS;
  269         machine_info.memory_size = mem_size;
  270         machine_info.avail_cpus = 0;
  271         machine_info.major_version = KERNEL_MAJOR_VERSION;
  272         machine_info.minor_version = KERNEL_MINOR_VERSION;
  273 
  274         /*
  275          *      Initialize the IPC, task, and thread subsystems.
  276          */
  277         task_init();
  278         thread_init();
  279         swapper_init();
  280 #if     MACH_HOST
  281         pset_sys_init();
  282 #endif  MACH_HOST
  283 
  284         /*
  285          *      Kick off the time-out driven routines by calling
  286          *      them the first time.
  287          */
  288         recompute_priorities();
  289         compute_mach_factor();
  290         
  291         /*
  292          *      Create a kernel thread to start the other kernel
  293          *      threads.  Thread_resume (from kernel_thread) calls
  294          *      thread_setrun, which may look at current thread;
  295          *      we must avoid this, since there is no current thread.
  296          */
  297 
  298         /*
  299          * Create the thread, and point it at the routine.
  300          */
  301         (void) thread_create(kernel_task, &startup_thread);
  302         thread_start(startup_thread, start_kernel_threads);
  303 
  304         /*
  305          * Give it a kernel stack.
  306          */
  307         thread_doswapin(startup_thread);
  308 
  309         /*
  310          * Pretend it is already running, and resume it.
  311          * Since it looks as if it is running, thread_resume
  312          * will not try to put it on the run queues.
  313          *
  314          * We can do all of this without locking, because nothing
  315          * else is running yet.
  316          */
  317         startup_thread->state |= TH_RUN;
  318         (void) thread_resume(startup_thread);
  319 
  320         /*
  321          * Start the thread.
  322          */
  323         cpu_launch_first_thread(startup_thread);
  324         /*NOTREACHED*/
  325 }
  326 
  327 /*
  328  * Now running in a thread.  Create the rest of the kernel threads
  329  * and the bootstrap task.
  330  */
  331 void start_kernel_threads()
  332 {
  333         register int    i;
  334 
  335         /*
  336          *      Create the idle threads and the other
  337          *      service threads.
  338          */
  339         for (i = 0; i < NCPUS; i++) {
  340             if (machine_slot[i].is_cpu) {
  341                 thread_t        th;
  342 
  343                 (void) thread_create(kernel_task, &th);
  344                 thread_bind(th, cpu_to_processor(i));
  345                 thread_start(th, idle_thread);
  346                 thread_doswapin(th);
  347                 (void) thread_resume(th);
  348             }
  349         }
  350 
  351         (void) kernel_thread(kernel_task, reaper_thread, (char *) 0);
  352         (void) kernel_thread(kernel_task, swapin_thread, (char *) 0);
  353         (void) kernel_thread(kernel_task, sched_thread, (char *) 0);
  354 
  355 #if     NCPUS > 1
  356         /*
  357          *      Create the shutdown thread.
  358          */
  359         (void) kernel_thread(kernel_task, action_thread, (char *) 0);
  360 
  361         /*
  362          *      Allow other CPUs to run.
  363          */
  364         start_other_cpus();
  365 #endif  NCPUS > 1
  366 
  367         /*
  368          *      Create the device service.
  369          */
  370         device_service_create();
  371 
  372         /*
  373          *      Initialize NORMA ipc system.
  374          */
  375 #if     NORMA_IPC
  376         norma_ipc_init();
  377 #endif  NORMA_IPC
  378 
  379         /*
  380          *      Initialize NORMA vm system.
  381          */
  382 #if     NORMA_VM
  383         norma_vm_init();
  384 #endif  NORMA_VM
  385 
  386         /*
  387          *      Start the user bootstrap.
  388          */
  389         bootstrap_create();
  390 
  391 #if     XPR_DEBUG
  392         xprinit();              /* XXX */
  393 #endif  XPR_DEBUG
  394 
  395         /*
  396          *      Become the pageout daemon.
  397          */
  398         (void) spl0();
  399         vm_pageout();
  400         /*NOTREACHED*/
  401 }
  402 
  403 #if     NCPUS > 1
  404 
  405 extern void     slave_machine_init();
  406 
  407 void slave_main()
  408 {
  409         slave_machine_init();
  410 
  411         cpu_launch_first_thread(THREAD_NULL);
  412 }
  413 #endif  NCPUS > 1
  414 
  415 /*
  416  *      Start up the first thread on a CPU.
  417  *      First thread is specified for the master CPU.
  418  */
  419 void cpu_launch_first_thread(th)
  420         register thread_t       th;
  421 {
  422         register int    mycpu;
  423 
  424         mycpu = cpu_number();
  425 
  426         cpu_up(mycpu);
  427 
  428         start_timer(&kernel_timer[mycpu]);
  429 
  430         /*
  431          * Block all interrupts for choose_thread.
  432          */
  433         (void) splhigh();
  434 
  435         if (th == THREAD_NULL)
  436             th = choose_thread(cpu_to_processor(mycpu));
  437         if (th == THREAD_NULL)
  438             panic("cpu_launch_first_thread");
  439 
  440         startrtclock();         /* needs an active thread */
  441         PMAP_ACTIVATE_KERNEL(mycpu);
  442 
  443         active_threads[mycpu] = th;
  444         active_stacks[mycpu] = th->kernel_stack;
  445         thread_lock(th);
  446         th->state &= ~TH_UNINT;
  447         thread_unlock(th);
  448         timer_switch(&th->system_timer);
  449 
  450         PMAP_ACTIVATE_USER(vm_map_pmap(th->task->map), th, mycpu);
  451 
  452         load_context(th);
  453         /*NOTREACHED*/
  454 }

Cache object: 5f2e2f8cf82f9257b3c95cb92892638f


[ 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.