init_main.c revision 1.190 1 1.190 thorpej /* $NetBSD: init_main.c,v 1.190 2001/04/13 23:30:10 thorpej Exp $ */
2 1.61 mycroft
3 1.61 mycroft /*
4 1.76 cgd * Copyright (c) 1995 Christopher G. Demetriou. All rights reserved.
5 1.61 mycroft * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
6 1.61 mycroft * The Regents of the University of California. All rights reserved.
7 1.61 mycroft * (c) UNIX System Laboratories, Inc.
8 1.61 mycroft * All or some portions of this file are derived from material licensed
9 1.61 mycroft * to the University of California by American Telephone and Telegraph
10 1.61 mycroft * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11 1.61 mycroft * the permission of UNIX System Laboratories, Inc.
12 1.61 mycroft *
13 1.61 mycroft * Redistribution and use in source and binary forms, with or without
14 1.61 mycroft * modification, are permitted provided that the following conditions
15 1.61 mycroft * are met:
16 1.61 mycroft * 1. Redistributions of source code must retain the above copyright
17 1.61 mycroft * notice, this list of conditions and the following disclaimer.
18 1.61 mycroft * 2. Redistributions in binary form must reproduce the above copyright
19 1.61 mycroft * notice, this list of conditions and the following disclaimer in the
20 1.61 mycroft * documentation and/or other materials provided with the distribution.
21 1.61 mycroft * 3. All advertising materials mentioning features or use of this software
22 1.61 mycroft * must display the following acknowledgement:
23 1.61 mycroft * This product includes software developed by the University of
24 1.61 mycroft * California, Berkeley and its contributors.
25 1.61 mycroft * 4. Neither the name of the University nor the names of its contributors
26 1.61 mycroft * may be used to endorse or promote products derived from this software
27 1.61 mycroft * without specific prior written permission.
28 1.61 mycroft *
29 1.61 mycroft * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 1.61 mycroft * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 1.61 mycroft * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 1.61 mycroft * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 1.61 mycroft * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 1.61 mycroft * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 1.61 mycroft * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 1.61 mycroft * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 1.61 mycroft * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 1.61 mycroft * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 1.61 mycroft * SUCH DAMAGE.
40 1.61 mycroft *
41 1.118 fvdl * @(#)init_main.c 8.16 (Berkeley) 5/14/95
42 1.61 mycroft */
43 1.115 mrg
44 1.117 thorpej #include "fs_nfs.h"
45 1.123 thorpej #include "opt_nfsserver.h"
46 1.134 tron #include "opt_sysv.h"
47 1.158 simonb #include "opt_maxuprc.h"
48 1.160 thorpej #include "opt_multiprocessor.h"
49 1.172 soren #include "opt_syscall_debug.h"
50 1.61 mycroft
51 1.106 explorer #include "rnd.h"
52 1.106 explorer
53 1.61 mycroft #include <sys/param.h>
54 1.164 enami #include <sys/acct.h>
55 1.61 mycroft #include <sys/filedesc.h>
56 1.131 thorpej #include <sys/file.h>
57 1.61 mycroft #include <sys/errno.h>
58 1.162 thorpej #include <sys/callout.h>
59 1.61 mycroft #include <sys/kernel.h>
60 1.61 mycroft #include <sys/mount.h>
61 1.61 mycroft #include <sys/map.h>
62 1.61 mycroft #include <sys/proc.h>
63 1.136 thorpej #include <sys/kthread.h>
64 1.61 mycroft #include <sys/resourcevar.h>
65 1.61 mycroft #include <sys/signalvar.h>
66 1.61 mycroft #include <sys/systm.h>
67 1.61 mycroft #include <sys/vnode.h>
68 1.87 thorpej #include <sys/tty.h>
69 1.61 mycroft #include <sys/conf.h>
70 1.95 thorpej #include <sys/disklabel.h>
71 1.61 mycroft #include <sys/buf.h>
72 1.61 mycroft #include <sys/device.h>
73 1.186 jdolecek #include <sys/exec.h>
74 1.128 thorpej #include <sys/socketvar.h>
75 1.61 mycroft #include <sys/protosw.h>
76 1.61 mycroft #include <sys/reboot.h>
77 1.61 mycroft #include <sys/user.h>
78 1.176 thorpej #include <sys/sysctl.h>
79 1.82 christos #ifdef SYSVSHM
80 1.82 christos #include <sys/shm.h>
81 1.82 christos #endif
82 1.82 christos #ifdef SYSVSEM
83 1.82 christos #include <sys/sem.h>
84 1.82 christos #endif
85 1.82 christos #ifdef SYSVMSG
86 1.82 christos #include <sys/msg.h>
87 1.82 christos #endif
88 1.82 christos #include <sys/domain.h>
89 1.82 christos #include <sys/mbuf.h>
90 1.94 mouse #include <sys/namei.h>
91 1.106 explorer #if NRND > 0
92 1.103 explorer #include <sys/rnd.h>
93 1.106 explorer #endif
94 1.61 mycroft
95 1.77 christos #include <sys/syscall.h>
96 1.68 cgd #include <sys/syscallargs.h>
97 1.68 cgd
98 1.61 mycroft #include <ufs/ufs/quota.h>
99 1.61 mycroft
100 1.159 fvdl #include <miscfs/genfs/genfs.h>
101 1.159 fvdl #include <miscfs/syncfs/syncfs.h>
102 1.159 fvdl
103 1.61 mycroft #include <machine/cpu.h>
104 1.61 mycroft
105 1.114 mrg #include <uvm/uvm.h>
106 1.114 mrg
107 1.81 christos #include <net/if.h>
108 1.81 christos #include <net/raw_cb.h>
109 1.61 mycroft
110 1.176 thorpej const char copyright[] = "\
111 1.188 thorpej Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001
112 1.112 thorpej The NetBSD Foundation, Inc. All rights reserved.
113 1.107 thorpej Copyright (c) 1982, 1986, 1989, 1991, 1993
114 1.107 thorpej The Regents of the University of California. All rights reserved.
115 1.107 thorpej
116 1.107 thorpej ";
117 1.61 mycroft
118 1.61 mycroft /* Components of the first process -- never freed. */
119 1.61 mycroft struct session session0;
120 1.61 mycroft struct pgrp pgrp0;
121 1.61 mycroft struct proc proc0;
122 1.61 mycroft struct pcred cred0;
123 1.61 mycroft struct filedesc0 filedesc0;
124 1.148 thorpej struct cwdinfo cwdi0;
125 1.61 mycroft struct plimit limit0;
126 1.61 mycroft struct vmspace vmspace0;
127 1.149 thorpej struct sigacts sigacts0;
128 1.133 pk #ifndef curproc
129 1.61 mycroft struct proc *curproc = &proc0;
130 1.133 pk #endif
131 1.105 mycroft struct proc *initproc;
132 1.61 mycroft
133 1.61 mycroft int cmask = CMASK;
134 1.61 mycroft extern struct user *proc0paddr;
135 1.61 mycroft
136 1.61 mycroft struct vnode *rootvp, *swapdev_vp;
137 1.61 mycroft int boothowto;
138 1.156 thorpej int cold = 1; /* still working on startup */
139 1.61 mycroft struct timeval boottime;
140 1.61 mycroft
141 1.163 thorpej __volatile int start_init_exec; /* semaphore for start_init() */
142 1.163 thorpej
143 1.176 thorpej static void check_console(struct proc *p);
144 1.176 thorpej static void start_init(void *);
145 1.176 thorpej void main(void);
146 1.76 cgd
147 1.184 jdolecek extern const struct emul emul_netbsd; /* defined in kern_exec.c */
148 1.77 christos
149 1.61 mycroft /*
150 1.61 mycroft * System startup; initialize the world, create process 0, mount root
151 1.61 mycroft * filesystem, and fork to create init and pagedaemon. Most of the
152 1.61 mycroft * hard work is done in the lower-level initialization routines including
153 1.61 mycroft * startup(), which does memory initialization and autoconfiguration.
154 1.61 mycroft */
155 1.81 christos void
156 1.176 thorpej main(void)
157 1.61 mycroft {
158 1.144 thorpej struct proc *p;
159 1.111 thorpej struct pdevinit *pdev;
160 1.111 thorpej int i, s, error;
161 1.182 he rlim_t lim;
162 1.61 mycroft extern struct pdevinit pdevinit[];
163 1.176 thorpej extern void schedcpu(void *);
164 1.176 thorpej extern void disk_init(void);
165 1.95 thorpej #if defined(NFSSERVER) || defined(NFS)
166 1.176 thorpej extern void nfs_init(void);
167 1.91 thorpej #endif
168 1.175 jdolecek #ifdef NVNODE_IMPLICIT
169 1.175 jdolecek int usevnodes;
170 1.175 jdolecek #endif
171 1.61 mycroft
172 1.61 mycroft /*
173 1.61 mycroft * Initialize the current process pointer (curproc) before
174 1.61 mycroft * any possible traps/probes to simplify trap processing.
175 1.61 mycroft */
176 1.61 mycroft p = &proc0;
177 1.61 mycroft curproc = p;
178 1.171 thorpej p->p_cpu = curcpu();
179 1.61 mycroft /*
180 1.61 mycroft * Attempt to find console and initialize
181 1.61 mycroft * in case of early panic or other messages.
182 1.61 mycroft */
183 1.61 mycroft consinit();
184 1.141 cjs printf("%s", copyright);
185 1.61 mycroft
186 1.179 thorpej KERNEL_LOCK_INIT();
187 1.179 thorpej
188 1.114 mrg uvm_init();
189 1.127 thorpej
190 1.145 thorpej /* Do machine-dependent initialization. */
191 1.145 thorpej cpu_startup();
192 1.162 thorpej
193 1.166 enami /* Initialize callouts. */
194 1.166 enami callout_startup();
195 1.145 thorpej
196 1.127 thorpej /*
197 1.127 thorpej * Initialize mbuf's. Do this now because we might attempt to
198 1.127 thorpej * allocate mbufs or mbuf clusters during autoconfiguration.
199 1.127 thorpej */
200 1.127 thorpej mbinit();
201 1.128 thorpej
202 1.128 thorpej /* Initialize sockets. */
203 1.128 thorpej soinit();
204 1.127 thorpej
205 1.156 thorpej /*
206 1.156 thorpej * The following 3 things must be done before autoconfiguration.
207 1.156 thorpej */
208 1.156 thorpej disk_init(); /* initialize disk list */
209 1.156 thorpej tty_init(); /* initialize tty list */
210 1.106 explorer #if NRND > 0
211 1.156 thorpej rnd_init(); /* initialize RNG */
212 1.106 explorer #endif
213 1.61 mycroft
214 1.176 thorpej /* Initialize the sysctl subsystem. */
215 1.176 thorpej sysctl_init();
216 1.176 thorpej
217 1.61 mycroft /*
218 1.63 mycroft * Initialize process and pgrp structures.
219 1.63 mycroft */
220 1.63 mycroft procinit();
221 1.63 mycroft
222 1.63 mycroft /*
223 1.61 mycroft * Create process 0 (the swapper).
224 1.61 mycroft */
225 1.154 thorpej s = proclist_lock_write();
226 1.63 mycroft LIST_INSERT_HEAD(&allproc, p, p_list);
227 1.170 jhawk LIST_INSERT_HEAD(PIDHASH(p->p_pid), p, p_hash);
228 1.154 thorpej proclist_unlock_write(s);
229 1.154 thorpej
230 1.61 mycroft p->p_pgrp = &pgrp0;
231 1.63 mycroft LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
232 1.63 mycroft LIST_INIT(&pgrp0.pg_members);
233 1.63 mycroft LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
234 1.63 mycroft
235 1.61 mycroft pgrp0.pg_session = &session0;
236 1.61 mycroft session0.s_count = 1;
237 1.116 thorpej session0.s_sid = p->p_pid;
238 1.61 mycroft session0.s_leader = p;
239 1.61 mycroft
240 1.136 thorpej /*
241 1.136 thorpej * Set P_NOCLDWAIT so that kernel threads are reparented to
242 1.136 thorpej * init(8) when they exit. init(8) can easily wait them out
243 1.136 thorpej * for us.
244 1.136 thorpej */
245 1.136 thorpej p->p_flag = P_INMEM | P_SYSTEM | P_NOCLDWAIT;
246 1.167 thorpej p->p_stat = SONPROC;
247 1.61 mycroft p->p_nice = NZERO;
248 1.77 christos p->p_emul = &emul_netbsd;
249 1.187 mycroft #ifdef __HAVE_SYSCALL_INTERN
250 1.187 mycroft (*p->p_emul->e_syscall_intern)(p);
251 1.187 mycroft #endif
252 1.146 gwr strncpy(p->p_comm, "swapper", MAXCOMLEN);
253 1.165 thorpej
254 1.165 thorpej callout_init(&p->p_realit_ch);
255 1.165 thorpej callout_init(&p->p_tsleep_ch);
256 1.61 mycroft
257 1.61 mycroft /* Create credentials. */
258 1.61 mycroft cred0.p_refcnt = 1;
259 1.61 mycroft p->p_cred = &cred0;
260 1.61 mycroft p->p_ucred = crget();
261 1.61 mycroft p->p_ucred->cr_ngroups = 1; /* group 0 */
262 1.61 mycroft
263 1.61 mycroft /* Create the file descriptor table. */
264 1.131 thorpej finit();
265 1.79 mycroft p->p_fd = &filedesc0.fd_fd;
266 1.109 thorpej fdinit1(&filedesc0);
267 1.61 mycroft
268 1.148 thorpej /* Create the CWD info. */
269 1.148 thorpej p->p_cwdi = &cwdi0;
270 1.148 thorpej cwdi0.cwdi_cmask = cmask;
271 1.148 thorpej cwdi0.cwdi_refcnt = 1;
272 1.148 thorpej
273 1.61 mycroft /* Create the limits structures. */
274 1.61 mycroft p->p_limit = &limit0;
275 1.61 mycroft for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
276 1.61 mycroft limit0.pl_rlimit[i].rlim_cur =
277 1.61 mycroft limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
278 1.140 christos
279 1.140 christos limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
280 1.140 christos limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
281 1.140 christos maxfiles < NOFILE ? maxfiles : NOFILE;
282 1.140 christos
283 1.140 christos limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
284 1.140 christos limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
285 1.140 christos maxproc < MAXUPRC ? maxproc : MAXUPRC;
286 1.140 christos
287 1.182 he lim = ptoa(uvmexp.free);
288 1.182 he limit0.pl_rlimit[RLIMIT_RSS].rlim_max = lim;
289 1.182 he limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = lim;
290 1.182 he limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
291 1.157 bouyer limit0.pl_corename = defcorename;
292 1.61 mycroft limit0.p_refcnt = 1;
293 1.61 mycroft
294 1.120 thorpej /*
295 1.120 thorpej * Initialize proc0's vmspace, which uses the kernel pmap.
296 1.120 thorpej * All kernel processes (which never have user space mappings)
297 1.120 thorpej * share proc0's vmspace, and thus, the kernel pmap.
298 1.120 thorpej */
299 1.120 thorpej uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
300 1.120 thorpej trunc_page(VM_MAX_ADDRESS), TRUE);
301 1.120 thorpej p->p_vmspace = &vmspace0;
302 1.99 gwr
303 1.61 mycroft p->p_addr = proc0paddr; /* XXX */
304 1.61 mycroft
305 1.61 mycroft /*
306 1.149 thorpej * We continue to place resource usage info in the
307 1.149 thorpej * user struct so they're pageable.
308 1.61 mycroft */
309 1.61 mycroft p->p_stats = &p->p_addr->u_stats;
310 1.61 mycroft
311 1.61 mycroft /*
312 1.63 mycroft * Charge root for one process.
313 1.61 mycroft */
314 1.61 mycroft (void)chgproccnt(0, 1);
315 1.61 mycroft
316 1.61 mycroft rqinit();
317 1.61 mycroft
318 1.61 mycroft /* Configure virtual memory system, set vm rlimits. */
319 1.114 mrg uvm_init_limits(p);
320 1.61 mycroft
321 1.61 mycroft /* Initialize the file systems. */
322 1.95 thorpej #if defined(NFSSERVER) || defined(NFS)
323 1.91 thorpej nfs_init(); /* initialize server/shared data */
324 1.91 thorpej #endif
325 1.61 mycroft vfsinit();
326 1.61 mycroft
327 1.156 thorpej /* Configure the system hardware. This will enable interrupts. */
328 1.156 thorpej configure();
329 1.61 mycroft
330 1.185 chs ubc_init(); /* must be after autoconfig */
331 1.185 chs
332 1.179 thorpej /* Lock the kernel on behalf of proc0. */
333 1.179 thorpej KERNEL_PROC_LOCK(p);
334 1.179 thorpej
335 1.61 mycroft #ifdef SYSVSHM
336 1.61 mycroft /* Initialize System V style shared memory. */
337 1.61 mycroft shminit();
338 1.61 mycroft #endif
339 1.61 mycroft
340 1.61 mycroft #ifdef SYSVSEM
341 1.61 mycroft /* Initialize System V style semaphores. */
342 1.61 mycroft seminit();
343 1.61 mycroft #endif
344 1.61 mycroft
345 1.61 mycroft #ifdef SYSVMSG
346 1.61 mycroft /* Initialize System V style message queues. */
347 1.61 mycroft msginit();
348 1.61 mycroft #endif
349 1.61 mycroft
350 1.61 mycroft /* Attach pseudo-devices. */
351 1.61 mycroft for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
352 1.61 mycroft (*pdev->pdev_attach)(pdev->pdev_count);
353 1.61 mycroft
354 1.61 mycroft /*
355 1.61 mycroft * Initialize protocols. Block reception of incoming packets
356 1.61 mycroft * until everything is ready.
357 1.61 mycroft */
358 1.190 thorpej s = splnet();
359 1.61 mycroft ifinit();
360 1.61 mycroft domaininit();
361 1.61 mycroft splx(s);
362 1.61 mycroft
363 1.61 mycroft #ifdef GPROF
364 1.61 mycroft /* Initialize kernel profiling. */
365 1.61 mycroft kmstartup();
366 1.61 mycroft #endif
367 1.164 enami
368 1.164 enami /* Initialize system accouting. */
369 1.164 enami acct_init();
370 1.61 mycroft
371 1.163 thorpej /*
372 1.163 thorpej * Initialize signal-related data structures, and signal state
373 1.163 thorpej * for proc0.
374 1.163 thorpej */
375 1.163 thorpej signal_init();
376 1.163 thorpej p->p_sigacts = &sigacts0;
377 1.163 thorpej siginit(p);
378 1.163 thorpej
379 1.61 mycroft /* Kick off timeout driven events by calling first time. */
380 1.61 mycroft schedcpu(NULL);
381 1.98 gwr
382 1.163 thorpej /*
383 1.163 thorpej * Create process 1 (init(8)). We do this now, as Unix has
384 1.163 thorpej * historically had init be process 1, and changing this would
385 1.163 thorpej * probably upset a lot of people.
386 1.163 thorpej *
387 1.163 thorpej * Note that process 1 won't immediately exec init(8), but will
388 1.163 thorpej * wait for us to inform it that the root file system has been
389 1.163 thorpej * mounted.
390 1.163 thorpej */
391 1.169 thorpej if (fork1(p, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL, &initproc))
392 1.163 thorpej panic("fork init");
393 1.163 thorpej
394 1.163 thorpej /*
395 1.163 thorpej * Create any kernel threads who's creation was deferred because
396 1.163 thorpej * initproc had not yet been created.
397 1.163 thorpej */
398 1.163 thorpej kthread_run_deferred_queue();
399 1.163 thorpej
400 1.163 thorpej /*
401 1.163 thorpej * Now that device driver threads have been created, wait for
402 1.163 thorpej * them to finish any deferred autoconfiguration. Note we don't
403 1.163 thorpej * need to lock this semaphore, since we haven't booted any
404 1.163 thorpej * secondary processors, yet.
405 1.163 thorpej */
406 1.163 thorpej while (config_pending)
407 1.163 thorpej (void) tsleep((void *)&config_pending, PWAIT, "cfpend", 0);
408 1.163 thorpej
409 1.163 thorpej /*
410 1.163 thorpej * Now that autoconfiguration has completed, we can determine
411 1.163 thorpej * the root and dump devices.
412 1.163 thorpej */
413 1.98 gwr cpu_rootconf();
414 1.101 thorpej cpu_dumpconf();
415 1.61 mycroft
416 1.61 mycroft /* Mount the root file system. */
417 1.95 thorpej do {
418 1.95 thorpej domountroothook();
419 1.95 thorpej if ((error = vfs_mountroot())) {
420 1.97 thorpej printf("cannot mount root, error = %d\n", error);
421 1.95 thorpej boothowto |= RB_ASKNAME;
422 1.95 thorpej setroot(root_device,
423 1.152 thorpej (rootdev != NODEV) ? DISKPART(rootdev) : 0);
424 1.95 thorpej }
425 1.95 thorpej } while (error != 0);
426 1.95 thorpej mountroothook_destroy();
427 1.95 thorpej
428 1.74 mycroft mountlist.cqh_first->mnt_flag |= MNT_ROOTFS;
429 1.74 mycroft mountlist.cqh_first->mnt_op->vfs_refcount++;
430 1.61 mycroft
431 1.111 thorpej /*
432 1.111 thorpej * Get the vnode for '/'. Set filedesc0.fd_fd.fd_cdir to
433 1.111 thorpej * reference it.
434 1.111 thorpej */
435 1.74 mycroft if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
436 1.61 mycroft panic("cannot find root vnode");
437 1.148 thorpej cwdi0.cwdi_cdir = rootvnode;
438 1.148 thorpej VREF(cwdi0.cwdi_cdir);
439 1.118 fvdl VOP_UNLOCK(rootvnode, 0);
440 1.148 thorpej cwdi0.cwdi_rdir = NULL;
441 1.163 thorpej
442 1.163 thorpej /*
443 1.163 thorpej * Now that root is mounted, we can fixup initproc's CWD
444 1.163 thorpej * info. All other processes are kthreads, which merely
445 1.163 thorpej * share proc0's CWD info.
446 1.163 thorpej */
447 1.163 thorpej initproc->p_cwdi->cwdi_cdir = rootvnode;
448 1.163 thorpej VREF(initproc->p_cwdi->cwdi_cdir);
449 1.163 thorpej initproc->p_cwdi->cwdi_rdir = NULL;
450 1.61 mycroft
451 1.61 mycroft /*
452 1.61 mycroft * Now can look at time, having had a chance to verify the time
453 1.61 mycroft * from the file system. Reset p->p_rtime as it may have been
454 1.61 mycroft * munched in mi_switch() after the time got set.
455 1.61 mycroft */
456 1.163 thorpej proclist_lock_read();
457 1.178 thorpej s = splsched();
458 1.163 thorpej for (p = LIST_FIRST(&allproc); p != NULL;
459 1.163 thorpej p = LIST_NEXT(p, p_list)) {
460 1.171 thorpej p->p_stats->p_start = mono_time = boottime = time;
461 1.171 thorpej if (p->p_cpu != NULL)
462 1.171 thorpej p->p_cpu->ci_schedstate.spc_runtime = time;
463 1.163 thorpej p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
464 1.163 thorpej }
465 1.163 thorpej splx(s);
466 1.163 thorpej proclist_unlock_read();
467 1.61 mycroft
468 1.163 thorpej /* Create the pageout daemon kernel thread. */
469 1.163 thorpej uvm_swap_init();
470 1.177 thorpej if (kthread_create1(uvm_pageout, NULL, NULL, "pagedaemon"))
471 1.135 thorpej panic("fork pagedaemon");
472 1.61 mycroft
473 1.163 thorpej /* Create the process reaper kernel thread. */
474 1.177 thorpej if (kthread_create1(reaper, NULL, NULL, "reaper"))
475 1.132 thorpej panic("fork reaper");
476 1.159 fvdl
477 1.163 thorpej /* Create the filesystem syncer kernel thread. */
478 1.159 fvdl if (kthread_create1(sched_sync, NULL, NULL, "ioflush"))
479 1.159 fvdl panic("fork syncer");
480 1.185 chs
481 1.185 chs /* Create the aiodone daemon kernel thread. */
482 1.185 chs if (kthread_create1(uvm_aiodone_daemon, NULL, NULL, "aiodoned"))
483 1.185 chs panic("fork aiodoned");
484 1.137 thorpej
485 1.160 thorpej #if defined(MULTIPROCESSOR)
486 1.160 thorpej /* Boot the secondary processors. */
487 1.160 thorpej cpu_boot_secondary_processors();
488 1.160 thorpej #endif
489 1.186 jdolecek
490 1.186 jdolecek /* Initialize exec structures */
491 1.186 jdolecek exec_init(1);
492 1.132 thorpej
493 1.163 thorpej /*
494 1.163 thorpej * Okay, now we can let init(8) exec! It's off to userland!
495 1.163 thorpej */
496 1.163 thorpej start_init_exec = 1;
497 1.163 thorpej wakeup((void *)&start_init_exec);
498 1.175 jdolecek
499 1.175 jdolecek #ifdef NVNODE_IMPLICIT
500 1.175 jdolecek /*
501 1.175 jdolecek * If maximum number of vnodes in namei vnode cache is not explicitly
502 1.175 jdolecek * defined in kernel config, adjust the number such as we use roughly
503 1.175 jdolecek * 0.5% of memory for vnode cache (but not less than NVNODE vnodes).
504 1.175 jdolecek */
505 1.175 jdolecek usevnodes = (ptoa(physmem) / 200) / sizeof(struct vnode);
506 1.175 jdolecek if (usevnodes > desiredvnodes)
507 1.175 jdolecek desiredvnodes = usevnodes;
508 1.175 jdolecek #endif
509 1.163 thorpej
510 1.61 mycroft /* The scheduler is an infinite loop. */
511 1.114 mrg uvm_scheduler();
512 1.61 mycroft /* NOTREACHED */
513 1.61 mycroft }
514 1.61 mycroft
515 1.93 mouse static void
516 1.176 thorpej check_console(struct proc *p)
517 1.93 mouse {
518 1.93 mouse struct nameidata nd;
519 1.93 mouse int error;
520 1.93 mouse
521 1.93 mouse NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
522 1.93 mouse error = namei(&nd);
523 1.96 cgd if (error == 0)
524 1.96 cgd vrele(nd.ni_vp);
525 1.96 cgd else if (error == ENOENT)
526 1.96 cgd printf("warning: no /dev/console\n");
527 1.93 mouse else
528 1.96 cgd printf("warning: lookup /dev/console: error %d\n", error);
529 1.93 mouse }
530 1.93 mouse
531 1.61 mycroft /*
532 1.61 mycroft * List of paths to try when searching for "init".
533 1.61 mycroft */
534 1.176 thorpej static const char *initpaths[] = {
535 1.61 mycroft "/sbin/init",
536 1.61 mycroft "/sbin/oinit",
537 1.61 mycroft "/sbin/init.bak",
538 1.61 mycroft NULL,
539 1.61 mycroft };
540 1.61 mycroft
541 1.61 mycroft /*
542 1.61 mycroft * Start the initial user process; try exec'ing each pathname in "initpaths".
543 1.61 mycroft * The program is invoked with one argument containing the boot flags.
544 1.61 mycroft */
545 1.61 mycroft static void
546 1.176 thorpej start_init(void *arg)
547 1.61 mycroft {
548 1.135 thorpej struct proc *p = arg;
549 1.130 eeh vaddr_t addr;
550 1.78 mycroft struct sys_execve_args /* {
551 1.108 mycroft syscallarg(const char *) path;
552 1.92 cgd syscallarg(char * const *) argp;
553 1.92 cgd syscallarg(char * const *) envp;
554 1.68 cgd } */ args;
555 1.68 cgd int options, i, error;
556 1.68 cgd register_t retval[2];
557 1.66 mycroft char flags[4], *flagsp;
558 1.176 thorpej const char **pathp, *path, *slash;
559 1.176 thorpej char *ucp, **uap, *arg0, *arg1 = NULL;
560 1.61 mycroft
561 1.76 cgd /*
562 1.76 cgd * Now in process 1.
563 1.76 cgd */
564 1.146 gwr strncpy(p->p_comm, "init", MAXCOMLEN);
565 1.163 thorpej
566 1.163 thorpej /*
567 1.163 thorpej * Wait for main() to tell us that it's safe to exec.
568 1.163 thorpej */
569 1.163 thorpej while (start_init_exec == 0)
570 1.163 thorpej (void) tsleep((void *)&start_init_exec, PWAIT, "initexec", 0);
571 1.93 mouse
572 1.93 mouse /*
573 1.93 mouse * This is not the right way to do this. We really should
574 1.93 mouse * hand-craft a descriptor onto /dev/console to hand to init,
575 1.93 mouse * but that's a _lot_ more work, and the benefit from this easy
576 1.93 mouse * hack makes up for the "good is the enemy of the best" effect.
577 1.93 mouse */
578 1.93 mouse check_console(p);
579 1.61 mycroft
580 1.61 mycroft /*
581 1.61 mycroft * Need just enough stack to hold the faked-up "execve()" arguments.
582 1.61 mycroft */
583 1.61 mycroft addr = USRSTACK - PAGE_SIZE;
584 1.114 mrg if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
585 1.181 thorpej NULL, UVM_UNKNOWN_OFFSET, 0,
586 1.114 mrg UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
587 1.114 mrg UVM_ADV_NORMAL,
588 1.189 chs UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0)
589 1.114 mrg panic("init: couldn't allocate argument space");
590 1.61 mycroft p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
591 1.61 mycroft
592 1.61 mycroft for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
593 1.64 mycroft ucp = (char *)(addr + PAGE_SIZE);
594 1.64 mycroft
595 1.61 mycroft /*
596 1.64 mycroft * Construct the boot flag argument.
597 1.61 mycroft */
598 1.66 mycroft flagsp = flags;
599 1.66 mycroft *flagsp++ = '-';
600 1.61 mycroft options = 0;
601 1.66 mycroft
602 1.61 mycroft if (boothowto & RB_SINGLE) {
603 1.64 mycroft *flagsp++ = 's';
604 1.61 mycroft options = 1;
605 1.61 mycroft }
606 1.61 mycroft #ifdef notyet
607 1.61 mycroft if (boothowto & RB_FASTBOOT) {
608 1.64 mycroft *flagsp++ = 'f';
609 1.61 mycroft options = 1;
610 1.61 mycroft }
611 1.61 mycroft #endif
612 1.64 mycroft
613 1.64 mycroft /*
614 1.64 mycroft * Move out the flags (arg 1), if necessary.
615 1.64 mycroft */
616 1.64 mycroft if (options != 0) {
617 1.64 mycroft *flagsp++ = '\0';
618 1.64 mycroft i = flagsp - flags;
619 1.64 mycroft #ifdef DEBUG
620 1.90 christos printf("init: copying out flags `%s' %d\n", flags, i);
621 1.64 mycroft #endif
622 1.64 mycroft (void)copyout((caddr_t)flags, (caddr_t)(ucp -= i), i);
623 1.64 mycroft arg1 = ucp;
624 1.64 mycroft }
625 1.61 mycroft
626 1.61 mycroft /*
627 1.61 mycroft * Move out the file name (also arg 0).
628 1.61 mycroft */
629 1.64 mycroft i = strlen(path) + 1;
630 1.64 mycroft #ifdef DEBUG
631 1.90 christos printf("init: copying out path `%s' %d\n", path, i);
632 1.64 mycroft #endif
633 1.64 mycroft (void)copyout((caddr_t)path, (caddr_t)(ucp -= i), i);
634 1.61 mycroft arg0 = ucp;
635 1.61 mycroft
636 1.61 mycroft /*
637 1.61 mycroft * Move out the arg pointers.
638 1.61 mycroft */
639 1.73 cgd uap = (char **)((long)ucp & ~ALIGNBYTES);
640 1.61 mycroft (void)suword((caddr_t)--uap, 0); /* terminator */
641 1.64 mycroft if (options != 0)
642 1.64 mycroft (void)suword((caddr_t)--uap, (long)arg1);
643 1.142 mycroft slash = strrchr(path, '/');
644 1.142 mycroft if (slash)
645 1.142 mycroft (void)suword((caddr_t)--uap,
646 1.142 mycroft (long)arg0 + (slash + 1 - path));
647 1.142 mycroft else
648 1.142 mycroft (void)suword((caddr_t)--uap, (long)arg0);
649 1.61 mycroft
650 1.61 mycroft /*
651 1.61 mycroft * Point at the arguments.
652 1.61 mycroft */
653 1.68 cgd SCARG(&args, path) = arg0;
654 1.68 cgd SCARG(&args, argp) = uap;
655 1.68 cgd SCARG(&args, envp) = NULL;
656 1.61 mycroft
657 1.61 mycroft /*
658 1.61 mycroft * Now try to exec the program. If can't for any reason
659 1.61 mycroft * other than it doesn't exist, complain.
660 1.61 mycroft */
661 1.102 mycroft error = sys_execve(p, &args, retval);
662 1.179 thorpej if (error == 0 || error == EJUSTRETURN) {
663 1.179 thorpej KERNEL_PROC_UNLOCK(p);
664 1.61 mycroft return;
665 1.179 thorpej }
666 1.61 mycroft if (error != ENOENT)
667 1.90 christos printf("exec %s: error %d\n", path, error);
668 1.61 mycroft }
669 1.90 christos printf("init: not found\n");
670 1.61 mycroft panic("no init");
671 1.61 mycroft }
672