init_main.c revision 1.107 1 1.107 thorpej /* $NetBSD: init_main.c,v 1.107 1997/10/17 21:40:00 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.61 mycroft * @(#)init_main.c 8.9 (Berkeley) 1/21/94
42 1.61 mycroft */
43 1.61 mycroft
44 1.106 explorer #include "rnd.h"
45 1.106 explorer
46 1.61 mycroft #include <sys/param.h>
47 1.61 mycroft #include <sys/filedesc.h>
48 1.61 mycroft #include <sys/errno.h>
49 1.61 mycroft #include <sys/exec.h>
50 1.61 mycroft #include <sys/kernel.h>
51 1.61 mycroft #include <sys/mount.h>
52 1.61 mycroft #include <sys/map.h>
53 1.61 mycroft #include <sys/proc.h>
54 1.61 mycroft #include <sys/resourcevar.h>
55 1.61 mycroft #include <sys/signalvar.h>
56 1.61 mycroft #include <sys/systm.h>
57 1.61 mycroft #include <sys/vnode.h>
58 1.87 thorpej #include <sys/tty.h>
59 1.61 mycroft #include <sys/conf.h>
60 1.95 thorpej #include <sys/disklabel.h>
61 1.61 mycroft #include <sys/buf.h>
62 1.61 mycroft #ifdef REAL_CLISTS
63 1.61 mycroft #include <sys/clist.h>
64 1.61 mycroft #endif
65 1.61 mycroft #include <sys/device.h>
66 1.61 mycroft #include <sys/protosw.h>
67 1.61 mycroft #include <sys/reboot.h>
68 1.61 mycroft #include <sys/user.h>
69 1.82 christos #ifdef SYSVSHM
70 1.82 christos #include <sys/shm.h>
71 1.82 christos #endif
72 1.82 christos #ifdef SYSVSEM
73 1.82 christos #include <sys/sem.h>
74 1.82 christos #endif
75 1.82 christos #ifdef SYSVMSG
76 1.82 christos #include <sys/msg.h>
77 1.82 christos #endif
78 1.82 christos #include <sys/domain.h>
79 1.82 christos #include <sys/mbuf.h>
80 1.94 mouse #include <sys/namei.h>
81 1.106 explorer #if NRND > 0
82 1.103 explorer #include <sys/rnd.h>
83 1.106 explorer #endif
84 1.61 mycroft
85 1.77 christos #include <sys/syscall.h>
86 1.68 cgd #include <sys/syscallargs.h>
87 1.68 cgd
88 1.61 mycroft #include <ufs/ufs/quota.h>
89 1.61 mycroft
90 1.61 mycroft #include <machine/cpu.h>
91 1.61 mycroft
92 1.61 mycroft #include <vm/vm.h>
93 1.81 christos #include <vm/vm_pageout.h>
94 1.81 christos
95 1.81 christos #include <net/if.h>
96 1.81 christos #include <net/raw_cb.h>
97 1.61 mycroft
98 1.107 thorpej char copyright[] = "\
99 1.107 thorpej Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. All rights reserved.
100 1.107 thorpej Copyright (c) 1982, 1986, 1989, 1991, 1993
101 1.107 thorpej The Regents of the University of California. All rights reserved.
102 1.107 thorpej
103 1.107 thorpej ";
104 1.61 mycroft
105 1.61 mycroft /* Components of the first process -- never freed. */
106 1.61 mycroft struct session session0;
107 1.61 mycroft struct pgrp pgrp0;
108 1.61 mycroft struct proc proc0;
109 1.61 mycroft struct pcred cred0;
110 1.61 mycroft struct filedesc0 filedesc0;
111 1.61 mycroft struct plimit limit0;
112 1.61 mycroft struct vmspace vmspace0;
113 1.61 mycroft struct proc *curproc = &proc0;
114 1.105 mycroft struct proc *initproc;
115 1.61 mycroft
116 1.61 mycroft int cmask = CMASK;
117 1.61 mycroft extern struct user *proc0paddr;
118 1.61 mycroft
119 1.61 mycroft struct vnode *rootvp, *swapdev_vp;
120 1.61 mycroft int boothowto;
121 1.61 mycroft struct timeval boottime;
122 1.61 mycroft struct timeval runtime;
123 1.61 mycroft
124 1.96 cgd static void check_console __P((struct proc *p));
125 1.76 cgd static void start_init __P((struct proc *));
126 1.76 cgd static void start_pagedaemon __P((struct proc *));
127 1.81 christos void main __P((void *));
128 1.76 cgd
129 1.76 cgd #ifdef cpu_set_init_frame
130 1.76 cgd void *initframep; /* XXX should go away */
131 1.76 cgd #endif
132 1.61 mycroft
133 1.77 christos extern char sigcode[], esigcode[];
134 1.77 christos #ifdef SYSCALL_DEBUG
135 1.77 christos extern char *syscallnames[];
136 1.77 christos #endif
137 1.77 christos
138 1.77 christos struct emul emul_netbsd = {
139 1.77 christos "netbsd",
140 1.77 christos NULL,
141 1.77 christos sendsig,
142 1.77 christos SYS_syscall,
143 1.77 christos SYS_MAXSYSCALL,
144 1.77 christos sysent,
145 1.77 christos #ifdef SYSCALL_DEBUG
146 1.77 christos syscallnames,
147 1.77 christos #else
148 1.77 christos NULL,
149 1.77 christos #endif
150 1.77 christos 0,
151 1.77 christos copyargs,
152 1.77 christos setregs,
153 1.77 christos sigcode,
154 1.77 christos esigcode,
155 1.77 christos };
156 1.77 christos
157 1.61 mycroft /*
158 1.61 mycroft * System startup; initialize the world, create process 0, mount root
159 1.61 mycroft * filesystem, and fork to create init and pagedaemon. Most of the
160 1.61 mycroft * hard work is done in the lower-level initialization routines including
161 1.61 mycroft * startup(), which does memory initialization and autoconfiguration.
162 1.61 mycroft */
163 1.81 christos void
164 1.61 mycroft main(framep)
165 1.76 cgd void *framep; /* XXX should go away */
166 1.61 mycroft {
167 1.61 mycroft register struct proc *p;
168 1.61 mycroft register struct pdevinit *pdev;
169 1.61 mycroft register int i;
170 1.95 thorpej int s, error;
171 1.68 cgd register_t rval[2];
172 1.61 mycroft extern struct pdevinit pdevinit[];
173 1.61 mycroft extern void roundrobin __P((void *));
174 1.61 mycroft extern void schedcpu __P((void *));
175 1.80 thorpej extern void disk_init __P((void));
176 1.95 thorpej #if defined(NFSSERVER) || defined(NFS)
177 1.91 thorpej extern void nfs_init __P((void));
178 1.91 thorpej #endif
179 1.61 mycroft
180 1.61 mycroft /*
181 1.61 mycroft * Initialize the current process pointer (curproc) before
182 1.61 mycroft * any possible traps/probes to simplify trap processing.
183 1.61 mycroft */
184 1.61 mycroft p = &proc0;
185 1.61 mycroft curproc = p;
186 1.61 mycroft /*
187 1.61 mycroft * Attempt to find console and initialize
188 1.61 mycroft * in case of early panic or other messages.
189 1.61 mycroft */
190 1.61 mycroft consinit();
191 1.90 christos printf(copyright);
192 1.61 mycroft
193 1.61 mycroft vm_mem_init();
194 1.61 mycroft kmeminit();
195 1.80 thorpej disk_init(); /* must come before autoconfiguration */
196 1.85 mrg tty_init(); /* initialise tty list */
197 1.106 explorer #if NRND > 0
198 1.103 explorer rnd_init();
199 1.106 explorer #endif
200 1.83 cgd config_init(); /* init autoconfiguration data structures */
201 1.61 mycroft cpu_startup();
202 1.61 mycroft
203 1.61 mycroft /*
204 1.63 mycroft * Initialize process and pgrp structures.
205 1.63 mycroft */
206 1.63 mycroft procinit();
207 1.63 mycroft
208 1.63 mycroft /*
209 1.61 mycroft * Create process 0 (the swapper).
210 1.61 mycroft */
211 1.63 mycroft LIST_INSERT_HEAD(&allproc, p, p_list);
212 1.61 mycroft p->p_pgrp = &pgrp0;
213 1.63 mycroft LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
214 1.63 mycroft LIST_INIT(&pgrp0.pg_members);
215 1.63 mycroft LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
216 1.63 mycroft
217 1.61 mycroft pgrp0.pg_session = &session0;
218 1.61 mycroft session0.s_count = 1;
219 1.61 mycroft session0.s_leader = p;
220 1.61 mycroft
221 1.61 mycroft p->p_flag = P_INMEM | P_SYSTEM;
222 1.61 mycroft p->p_stat = SRUN;
223 1.61 mycroft p->p_nice = NZERO;
224 1.77 christos p->p_emul = &emul_netbsd;
225 1.61 mycroft bcopy("swapper", p->p_comm, sizeof ("swapper"));
226 1.61 mycroft
227 1.61 mycroft /* Create credentials. */
228 1.61 mycroft cred0.p_refcnt = 1;
229 1.61 mycroft p->p_cred = &cred0;
230 1.61 mycroft p->p_ucred = crget();
231 1.61 mycroft p->p_ucred->cr_ngroups = 1; /* group 0 */
232 1.61 mycroft
233 1.61 mycroft /* Create the file descriptor table. */
234 1.79 mycroft p->p_fd = &filedesc0.fd_fd;
235 1.79 mycroft filedesc0.fd_fd.fd_refcnt = 1;
236 1.79 mycroft filedesc0.fd_fd.fd_cmask = cmask;
237 1.79 mycroft filedesc0.fd_fd.fd_ofiles = filedesc0.fd_dfiles;
238 1.79 mycroft filedesc0.fd_fd.fd_ofileflags = filedesc0.fd_dfileflags;
239 1.79 mycroft filedesc0.fd_fd.fd_nfiles = NDFILE;
240 1.61 mycroft
241 1.61 mycroft /* Create the limits structures. */
242 1.61 mycroft p->p_limit = &limit0;
243 1.61 mycroft for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
244 1.61 mycroft limit0.pl_rlimit[i].rlim_cur =
245 1.61 mycroft limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
246 1.61 mycroft limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
247 1.61 mycroft limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
248 1.61 mycroft i = ptoa(cnt.v_free_count);
249 1.61 mycroft limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
250 1.61 mycroft limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
251 1.61 mycroft limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
252 1.61 mycroft limit0.p_refcnt = 1;
253 1.61 mycroft
254 1.61 mycroft /* Allocate a prototype map so we have something to fork. */
255 1.99 gwr p->p_vmspace = vmspace_alloc(round_page(VM_MIN_ADDRESS),
256 1.99 gwr trunc_page(VM_MAX_ADDRESS), TRUE);
257 1.99 gwr
258 1.61 mycroft p->p_addr = proc0paddr; /* XXX */
259 1.61 mycroft
260 1.61 mycroft /*
261 1.61 mycroft * We continue to place resource usage info and signal
262 1.61 mycroft * actions in the user struct so they're pageable.
263 1.61 mycroft */
264 1.61 mycroft p->p_stats = &p->p_addr->u_stats;
265 1.61 mycroft p->p_sigacts = &p->p_addr->u_sigacts;
266 1.61 mycroft
267 1.61 mycroft /*
268 1.63 mycroft * Charge root for one process.
269 1.61 mycroft */
270 1.61 mycroft (void)chgproccnt(0, 1);
271 1.61 mycroft
272 1.61 mycroft rqinit();
273 1.61 mycroft
274 1.61 mycroft /* Configure virtual memory system, set vm rlimits. */
275 1.61 mycroft vm_init_limits(p);
276 1.61 mycroft
277 1.61 mycroft /* Initialize the file systems. */
278 1.95 thorpej #if defined(NFSSERVER) || defined(NFS)
279 1.91 thorpej nfs_init(); /* initialize server/shared data */
280 1.91 thorpej #endif
281 1.61 mycroft vfsinit();
282 1.61 mycroft
283 1.61 mycroft /* Start real time and statistics clocks. */
284 1.61 mycroft initclocks();
285 1.61 mycroft
286 1.61 mycroft /* Initialize mbuf's. */
287 1.61 mycroft mbinit();
288 1.61 mycroft
289 1.61 mycroft #ifdef REAL_CLISTS
290 1.61 mycroft /* Initialize clists. */
291 1.61 mycroft clist_init();
292 1.61 mycroft #endif
293 1.61 mycroft
294 1.61 mycroft #ifdef SYSVSHM
295 1.61 mycroft /* Initialize System V style shared memory. */
296 1.61 mycroft shminit();
297 1.61 mycroft #endif
298 1.61 mycroft
299 1.61 mycroft #ifdef SYSVSEM
300 1.61 mycroft /* Initialize System V style semaphores. */
301 1.61 mycroft seminit();
302 1.61 mycroft #endif
303 1.61 mycroft
304 1.61 mycroft #ifdef SYSVMSG
305 1.61 mycroft /* Initialize System V style message queues. */
306 1.61 mycroft msginit();
307 1.61 mycroft #endif
308 1.61 mycroft
309 1.61 mycroft /* Attach pseudo-devices. */
310 1.61 mycroft for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
311 1.61 mycroft (*pdev->pdev_attach)(pdev->pdev_count);
312 1.61 mycroft
313 1.61 mycroft /*
314 1.61 mycroft * Initialize protocols. Block reception of incoming packets
315 1.61 mycroft * until everything is ready.
316 1.61 mycroft */
317 1.61 mycroft s = splimp();
318 1.61 mycroft ifinit();
319 1.61 mycroft domaininit();
320 1.61 mycroft splx(s);
321 1.61 mycroft
322 1.61 mycroft #ifdef GPROF
323 1.61 mycroft /* Initialize kernel profiling. */
324 1.61 mycroft kmstartup();
325 1.61 mycroft #endif
326 1.61 mycroft
327 1.61 mycroft /* Kick off timeout driven events by calling first time. */
328 1.61 mycroft roundrobin(NULL);
329 1.61 mycroft schedcpu(NULL);
330 1.98 gwr
331 1.101 thorpej /* Determine the root and dump devices. */
332 1.98 gwr cpu_rootconf();
333 1.101 thorpej cpu_dumpconf();
334 1.61 mycroft
335 1.61 mycroft /* Mount the root file system. */
336 1.95 thorpej do {
337 1.95 thorpej domountroothook();
338 1.95 thorpej if ((error = vfs_mountroot())) {
339 1.97 thorpej printf("cannot mount root, error = %d\n", error);
340 1.95 thorpej boothowto |= RB_ASKNAME;
341 1.95 thorpej setroot(root_device,
342 1.95 thorpej (rootdev != NODEV) ? DISKPART(rootdev) : 0, NULL);
343 1.95 thorpej }
344 1.95 thorpej } while (error != 0);
345 1.95 thorpej mountroothook_destroy();
346 1.95 thorpej
347 1.74 mycroft mountlist.cqh_first->mnt_flag |= MNT_ROOTFS;
348 1.74 mycroft mountlist.cqh_first->mnt_op->vfs_refcount++;
349 1.61 mycroft
350 1.79 mycroft /* Get the vnode for '/'. Set filedesc0.fd_fd.fd_cdir to reference it. */
351 1.74 mycroft if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
352 1.61 mycroft panic("cannot find root vnode");
353 1.79 mycroft filedesc0.fd_fd.fd_cdir = rootvnode;
354 1.79 mycroft VREF(filedesc0.fd_fd.fd_cdir);
355 1.61 mycroft VOP_UNLOCK(rootvnode);
356 1.79 mycroft filedesc0.fd_fd.fd_rdir = NULL;
357 1.61 mycroft swapinit();
358 1.61 mycroft
359 1.61 mycroft /*
360 1.61 mycroft * Now can look at time, having had a chance to verify the time
361 1.61 mycroft * from the file system. Reset p->p_rtime as it may have been
362 1.61 mycroft * munched in mi_switch() after the time got set.
363 1.61 mycroft */
364 1.61 mycroft p->p_stats->p_start = runtime = mono_time = boottime = time;
365 1.61 mycroft p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
366 1.61 mycroft
367 1.61 mycroft /* Initialize signal state for process 0. */
368 1.61 mycroft siginit(p);
369 1.61 mycroft
370 1.61 mycroft /* Create process 1 (init(8)). */
371 1.78 mycroft if (sys_fork(p, NULL, rval))
372 1.61 mycroft panic("fork init");
373 1.76 cgd #ifdef cpu_set_init_frame /* XXX should go away */
374 1.61 mycroft if (rval[1]) {
375 1.76 cgd /*
376 1.76 cgd * Now in process 1.
377 1.76 cgd */
378 1.76 cgd initframep = framep;
379 1.76 cgd start_init(curproc);
380 1.61 mycroft return;
381 1.61 mycroft }
382 1.76 cgd #else
383 1.76 cgd cpu_set_kpc(pfind(1), start_init);
384 1.76 cgd #endif
385 1.61 mycroft
386 1.61 mycroft /* Create process 2 (the pageout daemon). */
387 1.78 mycroft if (sys_fork(p, NULL, rval))
388 1.61 mycroft panic("fork pager");
389 1.76 cgd #ifdef cpu_set_init_frame /* XXX should go away */
390 1.61 mycroft if (rval[1]) {
391 1.61 mycroft /*
392 1.61 mycroft * Now in process 2.
393 1.61 mycroft */
394 1.76 cgd start_pagedaemon(curproc);
395 1.61 mycroft }
396 1.76 cgd #else
397 1.76 cgd cpu_set_kpc(pfind(2), start_pagedaemon);
398 1.76 cgd #endif
399 1.61 mycroft
400 1.61 mycroft /* The scheduler is an infinite loop. */
401 1.61 mycroft scheduler();
402 1.61 mycroft /* NOTREACHED */
403 1.61 mycroft }
404 1.61 mycroft
405 1.93 mouse static void
406 1.93 mouse check_console(p)
407 1.96 cgd struct proc *p;
408 1.93 mouse {
409 1.93 mouse struct nameidata nd;
410 1.93 mouse int error;
411 1.93 mouse
412 1.93 mouse NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
413 1.93 mouse error = namei(&nd);
414 1.96 cgd if (error == 0)
415 1.96 cgd vrele(nd.ni_vp);
416 1.96 cgd else if (error == ENOENT)
417 1.96 cgd printf("warning: no /dev/console\n");
418 1.93 mouse else
419 1.96 cgd printf("warning: lookup /dev/console: error %d\n", error);
420 1.93 mouse }
421 1.93 mouse
422 1.61 mycroft /*
423 1.61 mycroft * List of paths to try when searching for "init".
424 1.61 mycroft */
425 1.61 mycroft static char *initpaths[] = {
426 1.61 mycroft "/sbin/init",
427 1.61 mycroft "/sbin/oinit",
428 1.61 mycroft "/sbin/init.bak",
429 1.61 mycroft NULL,
430 1.61 mycroft };
431 1.61 mycroft
432 1.61 mycroft /*
433 1.61 mycroft * Start the initial user process; try exec'ing each pathname in "initpaths".
434 1.61 mycroft * The program is invoked with one argument containing the boot flags.
435 1.61 mycroft */
436 1.61 mycroft static void
437 1.76 cgd start_init(p)
438 1.61 mycroft struct proc *p;
439 1.61 mycroft {
440 1.61 mycroft vm_offset_t addr;
441 1.78 mycroft struct sys_execve_args /* {
442 1.68 cgd syscallarg(char *) path;
443 1.92 cgd syscallarg(char * const *) argp;
444 1.92 cgd syscallarg(char * const *) envp;
445 1.68 cgd } */ args;
446 1.68 cgd int options, i, error;
447 1.68 cgd register_t retval[2];
448 1.66 mycroft char flags[4], *flagsp;
449 1.82 christos char **pathp, *path, *ucp, **uap, *arg0, *arg1 = NULL;
450 1.61 mycroft
451 1.76 cgd /*
452 1.76 cgd * Now in process 1.
453 1.76 cgd */
454 1.61 mycroft initproc = p;
455 1.61 mycroft
456 1.76 cgd #ifdef cpu_set_init_frame /* XXX should go away */
457 1.61 mycroft /*
458 1.61 mycroft * We need to set the system call frame as if we were entered through
459 1.78 mycroft * a syscall() so that when we call sys_execve() below, it will be able
460 1.61 mycroft * to set the entry point (see setregs) when it tries to exec. The
461 1.61 mycroft * startup code in "locore.s" has allocated space for the frame and
462 1.61 mycroft * passed a pointer to that space as main's argument.
463 1.61 mycroft */
464 1.76 cgd cpu_set_init_frame(p, initframep);
465 1.76 cgd #endif
466 1.93 mouse
467 1.93 mouse /*
468 1.93 mouse * This is not the right way to do this. We really should
469 1.93 mouse * hand-craft a descriptor onto /dev/console to hand to init,
470 1.93 mouse * but that's a _lot_ more work, and the benefit from this easy
471 1.93 mouse * hack makes up for the "good is the enemy of the best" effect.
472 1.93 mouse */
473 1.93 mouse check_console(p);
474 1.61 mycroft
475 1.61 mycroft /*
476 1.61 mycroft * Need just enough stack to hold the faked-up "execve()" arguments.
477 1.61 mycroft */
478 1.61 mycroft addr = USRSTACK - PAGE_SIZE;
479 1.61 mycroft if (vm_allocate(&p->p_vmspace->vm_map, &addr, (vm_size_t)PAGE_SIZE,
480 1.61 mycroft FALSE) != 0)
481 1.61 mycroft panic("init: couldn't allocate argument space");
482 1.61 mycroft p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
483 1.61 mycroft
484 1.61 mycroft for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
485 1.64 mycroft ucp = (char *)(addr + PAGE_SIZE);
486 1.64 mycroft
487 1.61 mycroft /*
488 1.64 mycroft * Construct the boot flag argument.
489 1.61 mycroft */
490 1.66 mycroft flagsp = flags;
491 1.66 mycroft *flagsp++ = '-';
492 1.61 mycroft options = 0;
493 1.66 mycroft
494 1.61 mycroft if (boothowto & RB_SINGLE) {
495 1.64 mycroft *flagsp++ = 's';
496 1.61 mycroft options = 1;
497 1.61 mycroft }
498 1.61 mycroft #ifdef notyet
499 1.61 mycroft if (boothowto & RB_FASTBOOT) {
500 1.64 mycroft *flagsp++ = 'f';
501 1.61 mycroft options = 1;
502 1.61 mycroft }
503 1.61 mycroft #endif
504 1.64 mycroft
505 1.64 mycroft /*
506 1.64 mycroft * Move out the flags (arg 1), if necessary.
507 1.64 mycroft */
508 1.64 mycroft if (options != 0) {
509 1.64 mycroft *flagsp++ = '\0';
510 1.64 mycroft i = flagsp - flags;
511 1.64 mycroft #ifdef DEBUG
512 1.90 christos printf("init: copying out flags `%s' %d\n", flags, i);
513 1.64 mycroft #endif
514 1.64 mycroft (void)copyout((caddr_t)flags, (caddr_t)(ucp -= i), i);
515 1.64 mycroft arg1 = ucp;
516 1.64 mycroft }
517 1.61 mycroft
518 1.61 mycroft /*
519 1.61 mycroft * Move out the file name (also arg 0).
520 1.61 mycroft */
521 1.64 mycroft i = strlen(path) + 1;
522 1.64 mycroft #ifdef DEBUG
523 1.90 christos printf("init: copying out path `%s' %d\n", path, i);
524 1.64 mycroft #endif
525 1.64 mycroft (void)copyout((caddr_t)path, (caddr_t)(ucp -= i), i);
526 1.61 mycroft arg0 = ucp;
527 1.61 mycroft
528 1.61 mycroft /*
529 1.61 mycroft * Move out the arg pointers.
530 1.61 mycroft */
531 1.73 cgd uap = (char **)((long)ucp & ~ALIGNBYTES);
532 1.61 mycroft (void)suword((caddr_t)--uap, 0); /* terminator */
533 1.64 mycroft if (options != 0)
534 1.64 mycroft (void)suword((caddr_t)--uap, (long)arg1);
535 1.64 mycroft (void)suword((caddr_t)--uap, (long)arg0);
536 1.61 mycroft
537 1.61 mycroft /*
538 1.61 mycroft * Point at the arguments.
539 1.61 mycroft */
540 1.68 cgd SCARG(&args, path) = arg0;
541 1.68 cgd SCARG(&args, argp) = uap;
542 1.68 cgd SCARG(&args, envp) = NULL;
543 1.61 mycroft
544 1.61 mycroft /*
545 1.61 mycroft * Now try to exec the program. If can't for any reason
546 1.61 mycroft * other than it doesn't exist, complain.
547 1.61 mycroft */
548 1.102 mycroft error = sys_execve(p, &args, retval);
549 1.102 mycroft if (error == 0 || error == EJUSTRETURN)
550 1.61 mycroft return;
551 1.61 mycroft if (error != ENOENT)
552 1.90 christos printf("exec %s: error %d\n", path, error);
553 1.61 mycroft }
554 1.90 christos printf("init: not found\n");
555 1.61 mycroft panic("no init");
556 1.76 cgd }
557 1.76 cgd
558 1.76 cgd static void
559 1.76 cgd start_pagedaemon(p)
560 1.76 cgd struct proc *p;
561 1.76 cgd {
562 1.76 cgd
563 1.76 cgd /*
564 1.76 cgd * Now in process 2.
565 1.76 cgd */
566 1.76 cgd p->p_flag |= P_INMEM | P_SYSTEM; /* XXX */
567 1.76 cgd bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
568 1.76 cgd vm_pageout();
569 1.76 cgd /* NOTREACHED */
570 1.61 mycroft }
571