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