1/*
2 * Copyright (c) 1995 Terrence R. Lambert
3 * All rights reserved.
4 *
5 * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 * (c) UNIX System Laboratories, Inc.
8 * All or some portions of this file are derived from material licensed
9 * to the University of California by American Telephone and Telegraph
10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11 * the permission of UNIX System Laboratories, Inc.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 *
41 * @(#)init_main.c 8.9 (Berkeley) 1/21/94
42 * $Id: init_main.c,v 1.116 1999/04/29 22:51:59 dt Exp $
43 */
44
45#include "opt_devfs.h"
46
47#include <sys/param.h>
48#include <sys/file.h>
49#include <sys/filedesc.h>
50#include <sys/kernel.h>
51#include <sys/mount.h>
52#include <sys/sysctl.h>
53#include <sys/proc.h>
54#include <sys/resourcevar.h>
55#include <sys/signalvar.h>
56#include <sys/systm.h>
57#include <sys/vnode.h>
58#include <sys/sysent.h>
59#include <sys/reboot.h>
60#include <sys/sysproto.h>
61#include <sys/vmmeter.h>
62#include <sys/unistd.h>
63#include <sys/malloc.h>
64
65#include <machine/cpu.h>
66
67#include <vm/vm.h>
68#include <vm/vm_param.h>
69#include <vm/vm_prot.h>
70#include <sys/lock.h>
71#include <vm/pmap.h>
72#include <vm/vm_map.h>
73#include <sys/user.h>
74#include <sys/copyright.h>
75
76extern struct linker_set sysinit_set; /* XXX */
77
78extern void __main __P((void));
79extern void main __P((void *framep));
80
81/* Components of the first process -- never freed. */
82static struct session session0;
83static struct pgrp pgrp0;
84struct proc proc0;
85static struct pcred cred0;
86static struct procsig procsig0;
87static struct filedesc0 filedesc0;
88static struct plimit limit0;
89static struct vmspace vmspace0;
90struct proc *initproc;
91
92int cmask = CMASK;
93extern struct user *proc0paddr;
94
95struct vnode *rootvp;
96int boothowto = 0; /* initialized so that it can be patched */
97
98struct timeval boottime;
99SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
100 &boottime, timeval, "System boottime");
101
102/*
103 * Promiscuous argument pass for start_init()
104 *
105 * This is a kludge because we use a return from main() rather than a call
106 * to a new routine in locore.s to kick the kernel alive from locore.s.
107 */
108static void *init_framep;
109
110
111#if __GNUC__ >= 2
112void __main() {}
113#endif
114
115
116/*
117 * This ensures that there is at least one entry so that the sysinit_set
118 * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never
119 * executed.
120 */
121SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
122
123/*
124 * The sysinit table itself. Items are checked off as the are run.
125 * If we want to register new sysinit types, add them to newsysinit.
126 */
127struct sysinit **sysinit = (struct sysinit **)sysinit_set.ls_items;
128struct sysinit **newsysinit;
129
130/*
131 * Merge a new sysinit set into the current set, reallocating it if
132 * necessary. This can only be called after malloc is running.
133 */
134void
135sysinit_add(set)
136 struct sysinit **set;
137{
138 struct sysinit **newset;
139 struct sysinit **sipp;
140 struct sysinit **xipp;
141 int count = 0;
142
143 if (newsysinit)
144 for (sipp = newsysinit; *sipp; sipp++)
145 count++;
146 else
147 for (sipp = sysinit; *sipp; sipp++)
148 count++;
149 for (sipp = set; *sipp; sipp++)
150 count++;
151 count++; /* Trailing NULL */
152 newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
153 if (newset == NULL)
154 panic("cannot malloc for sysinit");
155 xipp = newset;
156 if (newsysinit)
157 for (sipp = newsysinit; *sipp; sipp++)
158 *xipp++ = *sipp;
159 else
160 for (sipp = sysinit; *sipp; sipp++)
161 *xipp++ = *sipp;
162 for (sipp = set; *sipp; sipp++)
163 *xipp++ = *sipp;
164 *xipp = NULL;
165 if (newsysinit)
166 free(newsysinit, M_TEMP);
167 newsysinit = newset;
168}
169
170/*
171 * System startup; initialize the world, create process 0, mount root
172 * filesystem, and fork to create init and pagedaemon. Most of the
173 * hard work is done in the lower-level initialization routines including
174 * startup(), which does memory initialization and autoconfiguration.
175 *
176 * This allows simple addition of new kernel subsystems that require
177 * boot time initialization. It also allows substitution of subsystem
178 * (for instance, a scheduler, kernel profiler, or VM system) by object
179 * module. Finally, it allows for optional "kernel threads".
180 */
181void
182main(framep)
183 void *framep;
184{
185
186 register struct sysinit **sipp; /* system initialization*/
187 register struct sysinit **xipp; /* interior loop of sort*/
188 register struct sysinit *save; /* bubble*/
189
190 /*
191 * Copy the locore.s frame pointer for proc0, this is forked into
192 * all other processes.
193 */
194 init_framep = framep;
195
196restart:
197 /*
198 * Perform a bubble sort of the system initialization objects by
199 * their subsystem (primary key) and order (secondary key).
200 */
201 for (sipp = sysinit; *sipp; sipp++) {
202 for (xipp = sipp + 1; *xipp; xipp++) {
203 if ((*sipp)->subsystem < (*xipp)->subsystem ||
204 ((*sipp)->subsystem == (*xipp)->subsystem &&
205 (*sipp)->order < (*xipp)->order))
206 continue; /* skip*/
207 save = *sipp;
208 *sipp = *xipp;
209 *xipp = save;
210 }
211 }
212
213 /*
214 * Traverse the (now) ordered list of system initialization tasks.
215 * Perform each task, and continue on to the next task.
216 *
217 * The last item on the list is expected to be the scheduler,
218 * which will not return.
219 */
220 for (sipp = sysinit; *sipp; sipp++) {
221
222 if ((*sipp)->subsystem == SI_SUB_DUMMY)
223 continue; /* skip dummy task(s)*/
224
225 if ((*sipp)->subsystem == SI_SUB_DONE)
226 continue;
227
228 switch( (*sipp)->type) {
229 case SI_TYPE_DEFAULT:
230 /* no special processing*/
231 (*((*sipp)->func))((*sipp)->udata);
232 break;
233
234 case SI_TYPE_KTHREAD:
235 /* kernel thread*/
236 if (fork1(&proc0, RFMEM|RFFDG|RFPROC))
237 panic("fork kernel thread");
238 cpu_set_fork_handler(pfind(proc0.p_retval[0]),
239 (*sipp)->func, (*sipp)->udata);
240 break;
241
242 case SI_TYPE_KPROCESS:
243 if (fork1(&proc0, RFFDG|RFPROC))
244 panic("fork kernel process");
245 cpu_set_fork_handler(pfind(proc0.p_retval[0]),
246 (*sipp)->func, (*sipp)->udata);
247 break;
248
249 default:
250 panic("init_main: unrecognized init type");
251 }
252
253 /* Check off the one we're just done */
254 (*sipp)->subsystem = SI_SUB_DONE;
255
256 /* Check if we've installed more sysinit items via KLD */
257 if (newsysinit != NULL) {
258 if (sysinit != (struct sysinit **)sysinit_set.ls_items)
259 free(sysinit, M_TEMP);
260 sysinit = newsysinit;
261 newsysinit = NULL;
262 goto restart;
263 }
264 }
265
266 panic("Shouldn't get here!");
267 /* NOTREACHED*/
268}
269
270
271/*
272 * Start a kernel process. This is called after a fork() call in
273 * main() in the file kern/init_main.c.
274 *
275 * This function is used to start "internal" daemons.
276 */
277/* ARGSUSED*/
278void
279kproc_start(udata)
280 const void *udata;
281{
282 const struct kproc_desc *kp = udata;
283 struct proc *p = curproc;
284
285#ifdef DIAGNOSTIC
286 printf("Start pid=%d <%s>\n",p->p_pid, kp->arg0);
287#endif
288
289 /* save a global descriptor, if desired*/
290 if( kp->global_procpp != NULL)
291 *kp->global_procpp = p;
292
293 /* this is a non-swapped system process*/
294 p->p_flag |= P_INMEM | P_SYSTEM;
295
296 /* set up arg0 for 'ps', et al*/
297 strcpy( p->p_comm, kp->arg0);
298
299 /* call the processes' main()...*/
300 (*kp->func)();
301
302 /* NOTREACHED */
303 panic("kproc_start: %s", kp->arg0);
304}
305
306
307/*
308 ***************************************************************************
309 ****
310 **** The following SYSINIT's belong elsewhere, but have not yet
311 **** been moved.
312 ****
313 ***************************************************************************
314 */
315#ifdef OMIT
316/*
317 * Handled by vfs_mountroot (bad idea) at this time... should be
318 * done the same as 4.4Lite2.
319 */
320SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
321#endif /* OMIT*/
322
323static void print_caddr_t __P((void *data));
324static void
325print_caddr_t(data)
326 void *data;
327{
328 printf("%s", (char *)data);
329}
330SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
331
332
333/*
334 ***************************************************************************
335 ****
336 **** The two following SYSINT's are proc0 specific glue code. I am not
337 **** convinced that they can not be safely combined, but their order of
338 **** operation has been maintained as the same as the original init_main.c
339 **** for right now.
340 ****
341 **** These probably belong in init_proc.c or kern_proc.c, since they
342 **** deal with proc0 (the fork template process).
343 ****
344 ***************************************************************************
345 */
346/* ARGSUSED*/
347static void proc0_init __P((void *dummy));
348static void
349proc0_init(dummy)
350 void *dummy;
351{
352 register struct proc *p;
353 register struct filedesc0 *fdp;
354 register unsigned i;
355
356 p = &proc0;
357
358 /*
359 * Initialize process and pgrp structures.
360 */
361 procinit();
362
363 /*
364 * Initialize sleep queue hash table
365 */
366 sleepinit();
367
368 /*
369 * additional VM structures
370 */
371 vm_init2();
372
373 /*
374 * Create process 0 (the swapper).
375 */
376 LIST_INSERT_HEAD(&allproc, p, p_list);
377 p->p_pgrp = &pgrp0;
378 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
379 LIST_INIT(&pgrp0.pg_members);
380 LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
381
382 pgrp0.pg_session = &session0;
383 session0.s_count = 1;
384 session0.s_leader = p;
385
386 p->p_sysent = &aout_sysvec;
387
388 p->p_flag = P_INMEM | P_SYSTEM;
389 p->p_stat = SRUN;
390 p->p_nice = NZERO;
391 p->p_rtprio.type = RTP_PRIO_NORMAL;
392 p->p_rtprio.prio = 0;
393
394/*
395 * Link for kernel based threads
396 */
397 p->p_peers = 0;
398 p->p_leader = p;
399
400 bcopy("swapper", p->p_comm, sizeof ("swapper"));
401
402 /* Create credentials. */
403 cred0.p_refcnt = 1;
404 p->p_cred = &cred0;
405 p->p_ucred = crget();
406 p->p_ucred->cr_ngroups = 1; /* group 0 */
407
408 /* Don't jail it */
409 p->p_prison = 0;
410
411 /* Create procsig. */
412 p->p_procsig = &procsig0;
413 p->p_procsig->ps_refcnt = 1;
414
415 /* Create the file descriptor table. */
416 fdp = &filedesc0;
417 p->p_fd = &fdp->fd_fd;
418 fdp->fd_fd.fd_refcnt = 1;
419 fdp->fd_fd.fd_cmask = cmask;
420 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
421 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
422 fdp->fd_fd.fd_nfiles = NDFILE;
423
424 /* Create the limits structures. */
425 p->p_limit = &limit0;
426 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
427 limit0.pl_rlimit[i].rlim_cur =
428 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
429 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
430 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
431 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
432 limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
433 i = ptoa(cnt.v_free_count);
434 limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
435 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
436 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
437 limit0.p_cpulimit = RLIM_INFINITY;
438 limit0.p_refcnt = 1;
439
440
441 /* Allocate a prototype map so we have something to fork. */
442 pmap_pinit0(vmspace_pmap(&vmspace0));
443 p->p_vmspace = &vmspace0;
444 vmspace0.vm_refcnt = 1;
445 vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
446 trunc_page(VM_MAXUSER_ADDRESS));
447 vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
448 p->p_addr = proc0paddr; /* XXX */
449
450#ifndef __alpha__ /* XXX what is this? */
451#define INCOMPAT_LITES2
452#ifdef INCOMPAT_LITES2
453 /*
454 * proc0 needs to have a coherent frame base in its stack.
455 */
456 cpu_set_init_frame(p, init_framep); /* XXX! */
457#endif /* INCOMPAT_LITES2*/
458#endif
459
460 /*
461 * We continue to place resource usage info and signal
462 * actions in the user struct so they're pageable.
463 */
464 p->p_stats = &p->p_addr->u_stats;
465 p->p_sigacts = &p->p_addr->u_sigacts;
466
467 /*
468 * Charge root for one process.
469 */
470 (void)chgproccnt(0, 1);
471
472 /*
473 * Initialize the current process pointer (curproc) before
474 * any possible traps/probes to simplify trap processing.
475 */
476 SET_CURPROC(p);
477
478}
479SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
480
481/* ARGSUSED*/
482static void proc0_post __P((void *dummy));
483static void
484proc0_post(dummy)
485 void *dummy;
486{
487 struct timespec ts;
488
489 /*
490 * Now we can look at the time, having had a chance to verify the
491 * time from the file system. Pretend that proc0 started now.
492 */
493 microtime(&proc0.p_stats->p_start);
494 proc0.p_runtime = 0;
495 microuptime(&switchtime);
496 switchticks = ticks;
497
498 /*
499 * Give the ``random'' number generator a thump.
500 * XXX: Does read_random() contain enough bits to be used here ?
501 */
502 nanotime(&ts);
503 srandom(ts.tv_sec ^ ts.tv_nsec);
504
505 /* Initialize signal state for process 0. */
506 siginit(&proc0);
507}
508SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
509
510
511
512
513/*
514 ***************************************************************************
515 ****
516 **** The following SYSINIT's and glue code should be moved to the
517 **** respective files on a per subsystem basis.
518 ****
519 ***************************************************************************
520 */
521
522/* ARGSUSED */
523static void root_conf __P((void *dummy));
524static void
525root_conf(dummy)
526 void *dummy;
527{
528 cpu_rootconf();
529}
530SYSINIT(root_conf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, root_conf, NULL)
531
532/* ARGSUSED*/
533static void xxx_vfs_root_fdtab __P((void *dummy));
534static void
535xxx_vfs_root_fdtab(dummy)
536 void *dummy;
537{
538 register struct filedesc0 *fdp = &filedesc0;
539
540 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
541 if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
542 panic("cannot find root vnode");
543 fdp->fd_fd.fd_cdir = rootvnode;
544 VREF(fdp->fd_fd.fd_cdir);
545 VOP_UNLOCK(rootvnode, 0, &proc0);
546 fdp->fd_fd.fd_rdir = rootvnode;
547}
548SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
549
550
551/*
552 ***************************************************************************
553 ****
554 **** The following code probably belongs in another file, like
555 **** kern/init_init.c. It is here for two reasons only:
556 ****
557 **** 1) This code returns to startup the system; this is
558 **** abnormal for a kernel thread.
559 **** 2) This code promiscuously uses init_frame
560 ****
561 ***************************************************************************
562 */
563
564static void kthread_init __P((const void *dummy));
565SYSINIT_KP(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
566
567
568extern void prepare_usermode __P((void));
569static void start_init __P((struct proc *p));
570
571/* ARGSUSED*/
572static void
573kthread_init(dummy)
574 const void *dummy;
575{
576 /* Create process 1 (init(8)). */
577 start_init(curproc);
578
579 prepare_usermode();
580
581 /*
582 * This returns to the fork trampoline, then to user mode.
583 */
584 return;
585}
586
587
588/*
589 * List of paths to try when searching for "init".
590 */
591static char init_path[MAXPATHLEN] =
592 "/sbin/init;/sbin/oinit;/sbin/init.bak;/stand/sysinstall";
593SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0, "");
594
595/*
596 * Start the initial user process; try exec'ing each pathname in init_path.
597 * The program is invoked with one argument containing the boot flags.
598 */
599static void
600start_init(p)
601 struct proc *p;
602{
603 vm_offset_t addr;
604 struct execve_args args;
605 int options, error;
606 char *var, *path, *next, *s;
607 char *ucp, **uap, *arg0, *arg1;
608
609 initproc = p;
610
611 /*
612 * Need just enough stack to hold the faked-up "execve()" arguments.
613 */
614 addr = trunc_page(USRSTACK - PAGE_SIZE);
615 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
616 FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
617 panic("init: couldn't allocate argument space");
618 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
619 p->p_vmspace->vm_ssize = 1;
620
621 if ((var = getenv("init_path")) != NULL) {
622 strncpy(init_path, var, MAXPATHLEN);
623 init_path[sizeof init_path - 1] = 0;
624 }
625
626 for (path = init_path; path != '\0'; path = next) {
627 while (*path == ';')
628 path++;
629 if (path == '\0')
630 break;
631 for (next = path; *next != '\0' && *next != ';'; next++)
632 /* nothing */ ;
633 if (bootverbose)
634 printf("start_init: trying %.*s\n", (int)(next - path),
635 path);
636
637 /*
638 * Move out the boot flag argument.
639 */
640 options = 0;
641 ucp = (char *)USRSTACK;
642 (void)subyte(--ucp, 0); /* trailing zero */
643 if (boothowto & RB_SINGLE) {
644 (void)subyte(--ucp, 's');
645 options = 1;
646 }
647#ifdef notyet
648 if (boothowto & RB_FASTBOOT) {
649 (void)subyte(--ucp, 'f');
650 options = 1;
651 }
652#endif
653
654#ifdef BOOTCDROM
655 (void)subyte(--ucp, 'C');
656 options = 1;
657#endif
658 if (options == 0)
659 (void)subyte(--ucp, '-');
660 (void)subyte(--ucp, '-'); /* leading hyphen */
661 arg1 = ucp;
662
663 /*
664 * Move out the file name (also arg 0).
665 */
666 (void)subyte(--ucp, 0);
667 for (s = next - 1; s >= path; s--)
668 (void)subyte(--ucp, *s);
669 arg0 = ucp;
670
671 /*
672 * Move out the arg pointers.
673 */
674 uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
675 (void)suword((caddr_t)--uap, (long)0); /* terminator */
676 (void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
677 (void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
678
679 /*
680 * Point at the arguments.
681 */
682 args.fname = arg0;
683 args.argv = uap;
684 args.envv = NULL;
685
686 /*
687 * Now try to exec the program. If can't for any reason
688 * other than it doesn't exist, complain.
689 *
690 * Otherwise return to main() which returns to btext
691 * which completes the system startup.
692 */
693 if ((error = execve(p, &args)) == 0)
694 return;
695 if (error != ENOENT)
696 printf("exec %.*s: error %d\n", (int)(next - path),
697 path, error);
698 }
699 printf("init: not found\n");
700 panic("no init");
701}
2 * Copyright (c) 1995 Terrence R. Lambert
3 * All rights reserved.
4 *
5 * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 * (c) UNIX System Laboratories, Inc.
8 * All or some portions of this file are derived from material licensed
9 * to the University of California by American Telephone and Telegraph
10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11 * the permission of UNIX System Laboratories, Inc.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 *
41 * @(#)init_main.c 8.9 (Berkeley) 1/21/94
42 * $Id: init_main.c,v 1.116 1999/04/29 22:51:59 dt Exp $
43 */
44
45#include "opt_devfs.h"
46
47#include <sys/param.h>
48#include <sys/file.h>
49#include <sys/filedesc.h>
50#include <sys/kernel.h>
51#include <sys/mount.h>
52#include <sys/sysctl.h>
53#include <sys/proc.h>
54#include <sys/resourcevar.h>
55#include <sys/signalvar.h>
56#include <sys/systm.h>
57#include <sys/vnode.h>
58#include <sys/sysent.h>
59#include <sys/reboot.h>
60#include <sys/sysproto.h>
61#include <sys/vmmeter.h>
62#include <sys/unistd.h>
63#include <sys/malloc.h>
64
65#include <machine/cpu.h>
66
67#include <vm/vm.h>
68#include <vm/vm_param.h>
69#include <vm/vm_prot.h>
70#include <sys/lock.h>
71#include <vm/pmap.h>
72#include <vm/vm_map.h>
73#include <sys/user.h>
74#include <sys/copyright.h>
75
76extern struct linker_set sysinit_set; /* XXX */
77
78extern void __main __P((void));
79extern void main __P((void *framep));
80
81/* Components of the first process -- never freed. */
82static struct session session0;
83static struct pgrp pgrp0;
84struct proc proc0;
85static struct pcred cred0;
86static struct procsig procsig0;
87static struct filedesc0 filedesc0;
88static struct plimit limit0;
89static struct vmspace vmspace0;
90struct proc *initproc;
91
92int cmask = CMASK;
93extern struct user *proc0paddr;
94
95struct vnode *rootvp;
96int boothowto = 0; /* initialized so that it can be patched */
97
98struct timeval boottime;
99SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
100 &boottime, timeval, "System boottime");
101
102/*
103 * Promiscuous argument pass for start_init()
104 *
105 * This is a kludge because we use a return from main() rather than a call
106 * to a new routine in locore.s to kick the kernel alive from locore.s.
107 */
108static void *init_framep;
109
110
111#if __GNUC__ >= 2
112void __main() {}
113#endif
114
115
116/*
117 * This ensures that there is at least one entry so that the sysinit_set
118 * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never
119 * executed.
120 */
121SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
122
123/*
124 * The sysinit table itself. Items are checked off as the are run.
125 * If we want to register new sysinit types, add them to newsysinit.
126 */
127struct sysinit **sysinit = (struct sysinit **)sysinit_set.ls_items;
128struct sysinit **newsysinit;
129
130/*
131 * Merge a new sysinit set into the current set, reallocating it if
132 * necessary. This can only be called after malloc is running.
133 */
134void
135sysinit_add(set)
136 struct sysinit **set;
137{
138 struct sysinit **newset;
139 struct sysinit **sipp;
140 struct sysinit **xipp;
141 int count = 0;
142
143 if (newsysinit)
144 for (sipp = newsysinit; *sipp; sipp++)
145 count++;
146 else
147 for (sipp = sysinit; *sipp; sipp++)
148 count++;
149 for (sipp = set; *sipp; sipp++)
150 count++;
151 count++; /* Trailing NULL */
152 newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
153 if (newset == NULL)
154 panic("cannot malloc for sysinit");
155 xipp = newset;
156 if (newsysinit)
157 for (sipp = newsysinit; *sipp; sipp++)
158 *xipp++ = *sipp;
159 else
160 for (sipp = sysinit; *sipp; sipp++)
161 *xipp++ = *sipp;
162 for (sipp = set; *sipp; sipp++)
163 *xipp++ = *sipp;
164 *xipp = NULL;
165 if (newsysinit)
166 free(newsysinit, M_TEMP);
167 newsysinit = newset;
168}
169
170/*
171 * System startup; initialize the world, create process 0, mount root
172 * filesystem, and fork to create init and pagedaemon. Most of the
173 * hard work is done in the lower-level initialization routines including
174 * startup(), which does memory initialization and autoconfiguration.
175 *
176 * This allows simple addition of new kernel subsystems that require
177 * boot time initialization. It also allows substitution of subsystem
178 * (for instance, a scheduler, kernel profiler, or VM system) by object
179 * module. Finally, it allows for optional "kernel threads".
180 */
181void
182main(framep)
183 void *framep;
184{
185
186 register struct sysinit **sipp; /* system initialization*/
187 register struct sysinit **xipp; /* interior loop of sort*/
188 register struct sysinit *save; /* bubble*/
189
190 /*
191 * Copy the locore.s frame pointer for proc0, this is forked into
192 * all other processes.
193 */
194 init_framep = framep;
195
196restart:
197 /*
198 * Perform a bubble sort of the system initialization objects by
199 * their subsystem (primary key) and order (secondary key).
200 */
201 for (sipp = sysinit; *sipp; sipp++) {
202 for (xipp = sipp + 1; *xipp; xipp++) {
203 if ((*sipp)->subsystem < (*xipp)->subsystem ||
204 ((*sipp)->subsystem == (*xipp)->subsystem &&
205 (*sipp)->order < (*xipp)->order))
206 continue; /* skip*/
207 save = *sipp;
208 *sipp = *xipp;
209 *xipp = save;
210 }
211 }
212
213 /*
214 * Traverse the (now) ordered list of system initialization tasks.
215 * Perform each task, and continue on to the next task.
216 *
217 * The last item on the list is expected to be the scheduler,
218 * which will not return.
219 */
220 for (sipp = sysinit; *sipp; sipp++) {
221
222 if ((*sipp)->subsystem == SI_SUB_DUMMY)
223 continue; /* skip dummy task(s)*/
224
225 if ((*sipp)->subsystem == SI_SUB_DONE)
226 continue;
227
228 switch( (*sipp)->type) {
229 case SI_TYPE_DEFAULT:
230 /* no special processing*/
231 (*((*sipp)->func))((*sipp)->udata);
232 break;
233
234 case SI_TYPE_KTHREAD:
235 /* kernel thread*/
236 if (fork1(&proc0, RFMEM|RFFDG|RFPROC))
237 panic("fork kernel thread");
238 cpu_set_fork_handler(pfind(proc0.p_retval[0]),
239 (*sipp)->func, (*sipp)->udata);
240 break;
241
242 case SI_TYPE_KPROCESS:
243 if (fork1(&proc0, RFFDG|RFPROC))
244 panic("fork kernel process");
245 cpu_set_fork_handler(pfind(proc0.p_retval[0]),
246 (*sipp)->func, (*sipp)->udata);
247 break;
248
249 default:
250 panic("init_main: unrecognized init type");
251 }
252
253 /* Check off the one we're just done */
254 (*sipp)->subsystem = SI_SUB_DONE;
255
256 /* Check if we've installed more sysinit items via KLD */
257 if (newsysinit != NULL) {
258 if (sysinit != (struct sysinit **)sysinit_set.ls_items)
259 free(sysinit, M_TEMP);
260 sysinit = newsysinit;
261 newsysinit = NULL;
262 goto restart;
263 }
264 }
265
266 panic("Shouldn't get here!");
267 /* NOTREACHED*/
268}
269
270
271/*
272 * Start a kernel process. This is called after a fork() call in
273 * main() in the file kern/init_main.c.
274 *
275 * This function is used to start "internal" daemons.
276 */
277/* ARGSUSED*/
278void
279kproc_start(udata)
280 const void *udata;
281{
282 const struct kproc_desc *kp = udata;
283 struct proc *p = curproc;
284
285#ifdef DIAGNOSTIC
286 printf("Start pid=%d <%s>\n",p->p_pid, kp->arg0);
287#endif
288
289 /* save a global descriptor, if desired*/
290 if( kp->global_procpp != NULL)
291 *kp->global_procpp = p;
292
293 /* this is a non-swapped system process*/
294 p->p_flag |= P_INMEM | P_SYSTEM;
295
296 /* set up arg0 for 'ps', et al*/
297 strcpy( p->p_comm, kp->arg0);
298
299 /* call the processes' main()...*/
300 (*kp->func)();
301
302 /* NOTREACHED */
303 panic("kproc_start: %s", kp->arg0);
304}
305
306
307/*
308 ***************************************************************************
309 ****
310 **** The following SYSINIT's belong elsewhere, but have not yet
311 **** been moved.
312 ****
313 ***************************************************************************
314 */
315#ifdef OMIT
316/*
317 * Handled by vfs_mountroot (bad idea) at this time... should be
318 * done the same as 4.4Lite2.
319 */
320SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
321#endif /* OMIT*/
322
323static void print_caddr_t __P((void *data));
324static void
325print_caddr_t(data)
326 void *data;
327{
328 printf("%s", (char *)data);
329}
330SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
331
332
333/*
334 ***************************************************************************
335 ****
336 **** The two following SYSINT's are proc0 specific glue code. I am not
337 **** convinced that they can not be safely combined, but their order of
338 **** operation has been maintained as the same as the original init_main.c
339 **** for right now.
340 ****
341 **** These probably belong in init_proc.c or kern_proc.c, since they
342 **** deal with proc0 (the fork template process).
343 ****
344 ***************************************************************************
345 */
346/* ARGSUSED*/
347static void proc0_init __P((void *dummy));
348static void
349proc0_init(dummy)
350 void *dummy;
351{
352 register struct proc *p;
353 register struct filedesc0 *fdp;
354 register unsigned i;
355
356 p = &proc0;
357
358 /*
359 * Initialize process and pgrp structures.
360 */
361 procinit();
362
363 /*
364 * Initialize sleep queue hash table
365 */
366 sleepinit();
367
368 /*
369 * additional VM structures
370 */
371 vm_init2();
372
373 /*
374 * Create process 0 (the swapper).
375 */
376 LIST_INSERT_HEAD(&allproc, p, p_list);
377 p->p_pgrp = &pgrp0;
378 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
379 LIST_INIT(&pgrp0.pg_members);
380 LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
381
382 pgrp0.pg_session = &session0;
383 session0.s_count = 1;
384 session0.s_leader = p;
385
386 p->p_sysent = &aout_sysvec;
387
388 p->p_flag = P_INMEM | P_SYSTEM;
389 p->p_stat = SRUN;
390 p->p_nice = NZERO;
391 p->p_rtprio.type = RTP_PRIO_NORMAL;
392 p->p_rtprio.prio = 0;
393
394/*
395 * Link for kernel based threads
396 */
397 p->p_peers = 0;
398 p->p_leader = p;
399
400 bcopy("swapper", p->p_comm, sizeof ("swapper"));
401
402 /* Create credentials. */
403 cred0.p_refcnt = 1;
404 p->p_cred = &cred0;
405 p->p_ucred = crget();
406 p->p_ucred->cr_ngroups = 1; /* group 0 */
407
408 /* Don't jail it */
409 p->p_prison = 0;
410
411 /* Create procsig. */
412 p->p_procsig = &procsig0;
413 p->p_procsig->ps_refcnt = 1;
414
415 /* Create the file descriptor table. */
416 fdp = &filedesc0;
417 p->p_fd = &fdp->fd_fd;
418 fdp->fd_fd.fd_refcnt = 1;
419 fdp->fd_fd.fd_cmask = cmask;
420 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
421 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
422 fdp->fd_fd.fd_nfiles = NDFILE;
423
424 /* Create the limits structures. */
425 p->p_limit = &limit0;
426 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
427 limit0.pl_rlimit[i].rlim_cur =
428 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
429 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
430 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
431 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
432 limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
433 i = ptoa(cnt.v_free_count);
434 limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
435 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
436 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
437 limit0.p_cpulimit = RLIM_INFINITY;
438 limit0.p_refcnt = 1;
439
440
441 /* Allocate a prototype map so we have something to fork. */
442 pmap_pinit0(vmspace_pmap(&vmspace0));
443 p->p_vmspace = &vmspace0;
444 vmspace0.vm_refcnt = 1;
445 vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
446 trunc_page(VM_MAXUSER_ADDRESS));
447 vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
448 p->p_addr = proc0paddr; /* XXX */
449
450#ifndef __alpha__ /* XXX what is this? */
451#define INCOMPAT_LITES2
452#ifdef INCOMPAT_LITES2
453 /*
454 * proc0 needs to have a coherent frame base in its stack.
455 */
456 cpu_set_init_frame(p, init_framep); /* XXX! */
457#endif /* INCOMPAT_LITES2*/
458#endif
459
460 /*
461 * We continue to place resource usage info and signal
462 * actions in the user struct so they're pageable.
463 */
464 p->p_stats = &p->p_addr->u_stats;
465 p->p_sigacts = &p->p_addr->u_sigacts;
466
467 /*
468 * Charge root for one process.
469 */
470 (void)chgproccnt(0, 1);
471
472 /*
473 * Initialize the current process pointer (curproc) before
474 * any possible traps/probes to simplify trap processing.
475 */
476 SET_CURPROC(p);
477
478}
479SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
480
481/* ARGSUSED*/
482static void proc0_post __P((void *dummy));
483static void
484proc0_post(dummy)
485 void *dummy;
486{
487 struct timespec ts;
488
489 /*
490 * Now we can look at the time, having had a chance to verify the
491 * time from the file system. Pretend that proc0 started now.
492 */
493 microtime(&proc0.p_stats->p_start);
494 proc0.p_runtime = 0;
495 microuptime(&switchtime);
496 switchticks = ticks;
497
498 /*
499 * Give the ``random'' number generator a thump.
500 * XXX: Does read_random() contain enough bits to be used here ?
501 */
502 nanotime(&ts);
503 srandom(ts.tv_sec ^ ts.tv_nsec);
504
505 /* Initialize signal state for process 0. */
506 siginit(&proc0);
507}
508SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
509
510
511
512
513/*
514 ***************************************************************************
515 ****
516 **** The following SYSINIT's and glue code should be moved to the
517 **** respective files on a per subsystem basis.
518 ****
519 ***************************************************************************
520 */
521
522/* ARGSUSED */
523static void root_conf __P((void *dummy));
524static void
525root_conf(dummy)
526 void *dummy;
527{
528 cpu_rootconf();
529}
530SYSINIT(root_conf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, root_conf, NULL)
531
532/* ARGSUSED*/
533static void xxx_vfs_root_fdtab __P((void *dummy));
534static void
535xxx_vfs_root_fdtab(dummy)
536 void *dummy;
537{
538 register struct filedesc0 *fdp = &filedesc0;
539
540 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
541 if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
542 panic("cannot find root vnode");
543 fdp->fd_fd.fd_cdir = rootvnode;
544 VREF(fdp->fd_fd.fd_cdir);
545 VOP_UNLOCK(rootvnode, 0, &proc0);
546 fdp->fd_fd.fd_rdir = rootvnode;
547}
548SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
549
550
551/*
552 ***************************************************************************
553 ****
554 **** The following code probably belongs in another file, like
555 **** kern/init_init.c. It is here for two reasons only:
556 ****
557 **** 1) This code returns to startup the system; this is
558 **** abnormal for a kernel thread.
559 **** 2) This code promiscuously uses init_frame
560 ****
561 ***************************************************************************
562 */
563
564static void kthread_init __P((const void *dummy));
565SYSINIT_KP(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
566
567
568extern void prepare_usermode __P((void));
569static void start_init __P((struct proc *p));
570
571/* ARGSUSED*/
572static void
573kthread_init(dummy)
574 const void *dummy;
575{
576 /* Create process 1 (init(8)). */
577 start_init(curproc);
578
579 prepare_usermode();
580
581 /*
582 * This returns to the fork trampoline, then to user mode.
583 */
584 return;
585}
586
587
588/*
589 * List of paths to try when searching for "init".
590 */
591static char init_path[MAXPATHLEN] =
592 "/sbin/init;/sbin/oinit;/sbin/init.bak;/stand/sysinstall";
593SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0, "");
594
595/*
596 * Start the initial user process; try exec'ing each pathname in init_path.
597 * The program is invoked with one argument containing the boot flags.
598 */
599static void
600start_init(p)
601 struct proc *p;
602{
603 vm_offset_t addr;
604 struct execve_args args;
605 int options, error;
606 char *var, *path, *next, *s;
607 char *ucp, **uap, *arg0, *arg1;
608
609 initproc = p;
610
611 /*
612 * Need just enough stack to hold the faked-up "execve()" arguments.
613 */
614 addr = trunc_page(USRSTACK - PAGE_SIZE);
615 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
616 FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
617 panic("init: couldn't allocate argument space");
618 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
619 p->p_vmspace->vm_ssize = 1;
620
621 if ((var = getenv("init_path")) != NULL) {
622 strncpy(init_path, var, MAXPATHLEN);
623 init_path[sizeof init_path - 1] = 0;
624 }
625
626 for (path = init_path; path != '\0'; path = next) {
627 while (*path == ';')
628 path++;
629 if (path == '\0')
630 break;
631 for (next = path; *next != '\0' && *next != ';'; next++)
632 /* nothing */ ;
633 if (bootverbose)
634 printf("start_init: trying %.*s\n", (int)(next - path),
635 path);
636
637 /*
638 * Move out the boot flag argument.
639 */
640 options = 0;
641 ucp = (char *)USRSTACK;
642 (void)subyte(--ucp, 0); /* trailing zero */
643 if (boothowto & RB_SINGLE) {
644 (void)subyte(--ucp, 's');
645 options = 1;
646 }
647#ifdef notyet
648 if (boothowto & RB_FASTBOOT) {
649 (void)subyte(--ucp, 'f');
650 options = 1;
651 }
652#endif
653
654#ifdef BOOTCDROM
655 (void)subyte(--ucp, 'C');
656 options = 1;
657#endif
658 if (options == 0)
659 (void)subyte(--ucp, '-');
660 (void)subyte(--ucp, '-'); /* leading hyphen */
661 arg1 = ucp;
662
663 /*
664 * Move out the file name (also arg 0).
665 */
666 (void)subyte(--ucp, 0);
667 for (s = next - 1; s >= path; s--)
668 (void)subyte(--ucp, *s);
669 arg0 = ucp;
670
671 /*
672 * Move out the arg pointers.
673 */
674 uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
675 (void)suword((caddr_t)--uap, (long)0); /* terminator */
676 (void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
677 (void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
678
679 /*
680 * Point at the arguments.
681 */
682 args.fname = arg0;
683 args.argv = uap;
684 args.envv = NULL;
685
686 /*
687 * Now try to exec the program. If can't for any reason
688 * other than it doesn't exist, complain.
689 *
690 * Otherwise return to main() which returns to btext
691 * which completes the system startup.
692 */
693 if ((error = execve(p, &args)) == 0)
694 return;
695 if (error != ENOENT)
696 printf("exec %.*s: error %d\n", (int)(next - path),
697 path, error);
698 }
699 printf("init: not found\n");
700 panic("no init");
701}