Deleted Added
full compact
init_main.c (35136) init_main.c (35256)
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
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.88 1998/04/08 09:01:52 phk Exp $
42 * $Id: init_main.c,v 1.89 1998/04/11 17:24:06 phk 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
64#include <machine/cpu.h>
65
66#include <vm/vm.h>
67#include <vm/vm_param.h>
68#include <vm/vm_prot.h>
69#include <sys/lock.h>
70#include <vm/pmap.h>
71#include <vm/vm_map.h>
72#include <sys/user.h>
73#include <sys/copyright.h>
74
75extern struct linker_set sysinit_set; /* XXX */
76
77extern void __main __P((void));
78extern void main __P((void *framep));
79
80/* Components of the first process -- never freed. */
81static struct session session0;
82static struct pgrp pgrp0;
83struct proc proc0;
84static struct pcred cred0;
85static struct filedesc0 filedesc0;
86static struct plimit limit0;
87static struct vmspace vmspace0;
88struct proc *initproc;
89
90int cmask = CMASK;
91extern struct user *proc0paddr;
92
93struct vnode *rootvp;
94int boothowto = 0; /* initialized so that it can be patched */
95
96struct timeval boottime;
97SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime,
98 CTLFLAG_RD, &boottime, timeval, "");
99
100static int shutdowntimeout = 120;
101SYSCTL_INT(_kern, OID_AUTO, shutdown_timeout,
102 CTLFLAG_RW, &shutdowntimeout, 0, "");
103
104/*
105 * Promiscuous argument pass for start_init()
106 *
107 * This is a kludge because we use a return from main() rather than a call
108 * to a new routine in locore.s to kick the kernel alive from locore.s.
109 */
110static void *init_framep;
111
112
113#if __GNUC__ >= 2
114void __main() {}
115#endif
116
117
118/*
119 * This ensures that there is at least one entry so that the sysinit_set
120 * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never
121 * executed.
122 */
123SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
124
125
126/*
127 * System startup; initialize the world, create process 0, mount root
128 * filesystem, and fork to create init and pagedaemon. Most of the
129 * hard work is done in the lower-level initialization routines including
130 * startup(), which does memory initialization and autoconfiguration.
131 *
132 * This allows simple addition of new kernel subsystems that require
133 * boot time initialization. It also allows substitution of subsystem
134 * (for instance, a scheduler, kernel profiler, or VM system) by object
135 * module. Finally, it allows for optional "kernel threads".
136 */
137void
138main(framep)
139 void *framep;
140{
141
142 register struct sysinit **sipp; /* system initialization*/
143 register struct sysinit **xipp; /* interior loop of sort*/
144 register struct sysinit *save; /* bubble*/
145
146 /*
147 * Copy the locore.s frame pointer for proc0, this is forked into
148 * all other processes.
149 */
150 init_framep = framep;
151
152 /*
153 * Perform a bubble sort of the system initialization objects by
154 * their subsystem (primary key) and order (secondary key).
155 *
156 * Since some things care about execution order, this is the
157 * operation which ensures continued function.
158 */
159 for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
160 for( xipp = sipp + 1; *xipp; xipp++) {
161 if( (*sipp)->subsystem < (*xipp)->subsystem ||
162 ( (*sipp)->subsystem == (*xipp)->subsystem &&
163 (*sipp)->order < (*xipp)->order))
164 continue; /* skip*/
165 save = *sipp;
166 *sipp = *xipp;
167 *xipp = save;
168 }
169 }
170
171 /*
172 * Traverse the (now) ordered list of system initialization tasks.
173 * Perform each task, and continue on to the next task.
174 *
175 * The last item on the list is expected to be the scheduler,
176 * which will not return.
177 */
178 for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
179
180 if( (*sipp)->subsystem == SI_SUB_DUMMY)
181 continue; /* skip dummy task(s)*/
182
183 switch( (*sipp)->type) {
184 case SI_TYPE_DEFAULT:
185 /* no special processing*/
186 (*((*sipp)->func))( (*sipp)->udata);
187 break;
188
189 case SI_TYPE_KTHREAD:
190#if !defined(SMP)
191 /* kernel thread*/
192 if (fork1(&proc0, RFMEM|RFFDG|RFPROC))
193 panic("fork kernel thread");
194 cpu_set_fork_handler(pfind(proc0.p_retval[0]),
195 (*sipp)->func, (*sipp)->udata);
196 break;
197#endif
198
199 case SI_TYPE_KPROCESS:
200 if (fork1(&proc0, RFFDG|RFPROC))
201 panic("fork kernel process");
202 cpu_set_fork_handler(pfind(proc0.p_retval[0]),
203 (*sipp)->func, (*sipp)->udata);
204 break;
205
206 default:
207 panic( "init_main: unrecognized init type");
208 }
209 }
210
211 panic("Shouldn't get here!");
212 /* NOTREACHED*/
213}
214
215
216/*
217 * Start a kernel process. This is called after a fork() call in
218 * main() in the file kern/init_main.c.
219 *
220 * This function is used to start "internal" daemons.
221 */
222/* ARGSUSED*/
223void
224kproc_start(udata)
225 void *udata;
226{
227 struct kproc_desc *kp = udata;
228 struct proc *p = curproc;
229
230#ifdef DIAGNOSTIC
231 printf("Start pid=%d <%s>\n",p->p_pid, kp->arg0);
232#endif
233
234 /* save a global descriptor, if desired*/
235 if( kp->global_procpp != NULL)
236 *kp->global_procpp = p;
237
238 /* this is a non-swapped system process*/
239 p->p_flag |= P_INMEM | P_SYSTEM;
240
241 /* set up arg0 for 'ps', et al*/
242 strcpy( p->p_comm, kp->arg0);
243
244 /* call the processes' main()...*/
245 (*kp->func)();
246
247 /* NOTREACHED */
248 panic("kproc_start: %s", kp->arg0);
249}
250
251
252/*
253 ***************************************************************************
254 ****
255 **** The following SYSINIT's belong elsewhere, but have not yet
256 **** been moved.
257 ****
258 ***************************************************************************
259 */
260#ifdef OMIT
261/*
262 * Handled by vfs_mountroot (bad idea) at this time... should be
263 * done the same as 4.4Lite2.
264 */
265SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
266#endif /* OMIT*/
267
268static void print_caddr_t __P((void *data));
269static void
270print_caddr_t(data)
271 void *data;
272{
273 printf("%s", (char *)data);
274}
275SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
276
277
278/*
279 ***************************************************************************
280 ****
281 **** The two following SYSINT's are proc0 specific glue code. I am not
282 **** convinced that they can not be safely combined, but their order of
283 **** operation has been maintained as the same as the original init_main.c
284 **** for right now.
285 ****
286 **** These probably belong in init_proc.c or kern_proc.c, since they
287 **** deal with proc0 (the fork template process).
288 ****
289 ***************************************************************************
290 */
291/* ARGSUSED*/
292static void proc0_init __P((void *dummy));
293static void
294proc0_init(dummy)
295 void *dummy;
296{
297 register struct proc *p;
298 register struct filedesc0 *fdp;
299 register unsigned i;
300
301 /*
302 * Initialize the current process pointer (curproc) before
303 * any possible traps/probes to simplify trap processing.
304 */
305 p = &proc0;
306 curproc = p; /* XXX redundant*/
307
308 /*
309 * Initialize process and pgrp structures.
310 */
311 procinit();
312
313 /*
314 * Initialize sleep queue hash table
315 */
316 sleepinit();
317
318 /*
319 * additional VM structures
320 */
321 vm_init2();
322
323 /*
324 * Create process 0 (the swapper).
325 */
326 LIST_INSERT_HEAD(&allproc, p, p_list);
327 p->p_pgrp = &pgrp0;
328 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
329 LIST_INIT(&pgrp0.pg_members);
330 LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
331
332 pgrp0.pg_session = &session0;
333 session0.s_count = 1;
334 session0.s_leader = p;
335
336 p->p_sysent = &aout_sysvec;
337
338 p->p_flag = P_INMEM | P_SYSTEM;
339 p->p_stat = SRUN;
340 p->p_nice = NZERO;
341 p->p_rtprio.type = RTP_PRIO_NORMAL;
342 p->p_rtprio.prio = 0;
343
344/*
345 * Link for kernel based threads
346 */
347 p->p_peers = 0;
348 p->p_leader = p;
349
350 bcopy("swapper", p->p_comm, sizeof ("swapper"));
351
352 /* Create credentials. */
353 cred0.p_refcnt = 1;
354 p->p_cred = &cred0;
355 p->p_ucred = crget();
356 p->p_ucred->cr_ngroups = 1; /* group 0 */
357
358 /* Create the file descriptor table. */
359 fdp = &filedesc0;
360 p->p_fd = &fdp->fd_fd;
361 fdp->fd_fd.fd_refcnt = 1;
362 fdp->fd_fd.fd_cmask = cmask;
363 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
364 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
365 fdp->fd_fd.fd_nfiles = NDFILE;
366
367 /* Create the limits structures. */
368 p->p_limit = &limit0;
369 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
370 limit0.pl_rlimit[i].rlim_cur =
371 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
372 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
373 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
374 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
375 limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
376 i = ptoa(cnt.v_free_count);
377 limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
378 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
379 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
380 limit0.p_refcnt = 1;
381
382 /* Allocate a prototype map so we have something to fork. */
383 pmap_pinit0(&vmspace0.vm_pmap);
384 p->p_vmspace = &vmspace0;
385 vmspace0.vm_refcnt = 1;
386 vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
387 trunc_page(VM_MAXUSER_ADDRESS));
388 vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
389 p->p_addr = proc0paddr; /* XXX */
390
391#define INCOMPAT_LITES2
392#ifdef INCOMPAT_LITES2
393 /*
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
64#include <machine/cpu.h>
65
66#include <vm/vm.h>
67#include <vm/vm_param.h>
68#include <vm/vm_prot.h>
69#include <sys/lock.h>
70#include <vm/pmap.h>
71#include <vm/vm_map.h>
72#include <sys/user.h>
73#include <sys/copyright.h>
74
75extern struct linker_set sysinit_set; /* XXX */
76
77extern void __main __P((void));
78extern void main __P((void *framep));
79
80/* Components of the first process -- never freed. */
81static struct session session0;
82static struct pgrp pgrp0;
83struct proc proc0;
84static struct pcred cred0;
85static struct filedesc0 filedesc0;
86static struct plimit limit0;
87static struct vmspace vmspace0;
88struct proc *initproc;
89
90int cmask = CMASK;
91extern struct user *proc0paddr;
92
93struct vnode *rootvp;
94int boothowto = 0; /* initialized so that it can be patched */
95
96struct timeval boottime;
97SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime,
98 CTLFLAG_RD, &boottime, timeval, "");
99
100static int shutdowntimeout = 120;
101SYSCTL_INT(_kern, OID_AUTO, shutdown_timeout,
102 CTLFLAG_RW, &shutdowntimeout, 0, "");
103
104/*
105 * Promiscuous argument pass for start_init()
106 *
107 * This is a kludge because we use a return from main() rather than a call
108 * to a new routine in locore.s to kick the kernel alive from locore.s.
109 */
110static void *init_framep;
111
112
113#if __GNUC__ >= 2
114void __main() {}
115#endif
116
117
118/*
119 * This ensures that there is at least one entry so that the sysinit_set
120 * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never
121 * executed.
122 */
123SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
124
125
126/*
127 * System startup; initialize the world, create process 0, mount root
128 * filesystem, and fork to create init and pagedaemon. Most of the
129 * hard work is done in the lower-level initialization routines including
130 * startup(), which does memory initialization and autoconfiguration.
131 *
132 * This allows simple addition of new kernel subsystems that require
133 * boot time initialization. It also allows substitution of subsystem
134 * (for instance, a scheduler, kernel profiler, or VM system) by object
135 * module. Finally, it allows for optional "kernel threads".
136 */
137void
138main(framep)
139 void *framep;
140{
141
142 register struct sysinit **sipp; /* system initialization*/
143 register struct sysinit **xipp; /* interior loop of sort*/
144 register struct sysinit *save; /* bubble*/
145
146 /*
147 * Copy the locore.s frame pointer for proc0, this is forked into
148 * all other processes.
149 */
150 init_framep = framep;
151
152 /*
153 * Perform a bubble sort of the system initialization objects by
154 * their subsystem (primary key) and order (secondary key).
155 *
156 * Since some things care about execution order, this is the
157 * operation which ensures continued function.
158 */
159 for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
160 for( xipp = sipp + 1; *xipp; xipp++) {
161 if( (*sipp)->subsystem < (*xipp)->subsystem ||
162 ( (*sipp)->subsystem == (*xipp)->subsystem &&
163 (*sipp)->order < (*xipp)->order))
164 continue; /* skip*/
165 save = *sipp;
166 *sipp = *xipp;
167 *xipp = save;
168 }
169 }
170
171 /*
172 * Traverse the (now) ordered list of system initialization tasks.
173 * Perform each task, and continue on to the next task.
174 *
175 * The last item on the list is expected to be the scheduler,
176 * which will not return.
177 */
178 for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
179
180 if( (*sipp)->subsystem == SI_SUB_DUMMY)
181 continue; /* skip dummy task(s)*/
182
183 switch( (*sipp)->type) {
184 case SI_TYPE_DEFAULT:
185 /* no special processing*/
186 (*((*sipp)->func))( (*sipp)->udata);
187 break;
188
189 case SI_TYPE_KTHREAD:
190#if !defined(SMP)
191 /* kernel thread*/
192 if (fork1(&proc0, RFMEM|RFFDG|RFPROC))
193 panic("fork kernel thread");
194 cpu_set_fork_handler(pfind(proc0.p_retval[0]),
195 (*sipp)->func, (*sipp)->udata);
196 break;
197#endif
198
199 case SI_TYPE_KPROCESS:
200 if (fork1(&proc0, RFFDG|RFPROC))
201 panic("fork kernel process");
202 cpu_set_fork_handler(pfind(proc0.p_retval[0]),
203 (*sipp)->func, (*sipp)->udata);
204 break;
205
206 default:
207 panic( "init_main: unrecognized init type");
208 }
209 }
210
211 panic("Shouldn't get here!");
212 /* NOTREACHED*/
213}
214
215
216/*
217 * Start a kernel process. This is called after a fork() call in
218 * main() in the file kern/init_main.c.
219 *
220 * This function is used to start "internal" daemons.
221 */
222/* ARGSUSED*/
223void
224kproc_start(udata)
225 void *udata;
226{
227 struct kproc_desc *kp = udata;
228 struct proc *p = curproc;
229
230#ifdef DIAGNOSTIC
231 printf("Start pid=%d <%s>\n",p->p_pid, kp->arg0);
232#endif
233
234 /* save a global descriptor, if desired*/
235 if( kp->global_procpp != NULL)
236 *kp->global_procpp = p;
237
238 /* this is a non-swapped system process*/
239 p->p_flag |= P_INMEM | P_SYSTEM;
240
241 /* set up arg0 for 'ps', et al*/
242 strcpy( p->p_comm, kp->arg0);
243
244 /* call the processes' main()...*/
245 (*kp->func)();
246
247 /* NOTREACHED */
248 panic("kproc_start: %s", kp->arg0);
249}
250
251
252/*
253 ***************************************************************************
254 ****
255 **** The following SYSINIT's belong elsewhere, but have not yet
256 **** been moved.
257 ****
258 ***************************************************************************
259 */
260#ifdef OMIT
261/*
262 * Handled by vfs_mountroot (bad idea) at this time... should be
263 * done the same as 4.4Lite2.
264 */
265SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
266#endif /* OMIT*/
267
268static void print_caddr_t __P((void *data));
269static void
270print_caddr_t(data)
271 void *data;
272{
273 printf("%s", (char *)data);
274}
275SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
276
277
278/*
279 ***************************************************************************
280 ****
281 **** The two following SYSINT's are proc0 specific glue code. I am not
282 **** convinced that they can not be safely combined, but their order of
283 **** operation has been maintained as the same as the original init_main.c
284 **** for right now.
285 ****
286 **** These probably belong in init_proc.c or kern_proc.c, since they
287 **** deal with proc0 (the fork template process).
288 ****
289 ***************************************************************************
290 */
291/* ARGSUSED*/
292static void proc0_init __P((void *dummy));
293static void
294proc0_init(dummy)
295 void *dummy;
296{
297 register struct proc *p;
298 register struct filedesc0 *fdp;
299 register unsigned i;
300
301 /*
302 * Initialize the current process pointer (curproc) before
303 * any possible traps/probes to simplify trap processing.
304 */
305 p = &proc0;
306 curproc = p; /* XXX redundant*/
307
308 /*
309 * Initialize process and pgrp structures.
310 */
311 procinit();
312
313 /*
314 * Initialize sleep queue hash table
315 */
316 sleepinit();
317
318 /*
319 * additional VM structures
320 */
321 vm_init2();
322
323 /*
324 * Create process 0 (the swapper).
325 */
326 LIST_INSERT_HEAD(&allproc, p, p_list);
327 p->p_pgrp = &pgrp0;
328 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
329 LIST_INIT(&pgrp0.pg_members);
330 LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
331
332 pgrp0.pg_session = &session0;
333 session0.s_count = 1;
334 session0.s_leader = p;
335
336 p->p_sysent = &aout_sysvec;
337
338 p->p_flag = P_INMEM | P_SYSTEM;
339 p->p_stat = SRUN;
340 p->p_nice = NZERO;
341 p->p_rtprio.type = RTP_PRIO_NORMAL;
342 p->p_rtprio.prio = 0;
343
344/*
345 * Link for kernel based threads
346 */
347 p->p_peers = 0;
348 p->p_leader = p;
349
350 bcopy("swapper", p->p_comm, sizeof ("swapper"));
351
352 /* Create credentials. */
353 cred0.p_refcnt = 1;
354 p->p_cred = &cred0;
355 p->p_ucred = crget();
356 p->p_ucred->cr_ngroups = 1; /* group 0 */
357
358 /* Create the file descriptor table. */
359 fdp = &filedesc0;
360 p->p_fd = &fdp->fd_fd;
361 fdp->fd_fd.fd_refcnt = 1;
362 fdp->fd_fd.fd_cmask = cmask;
363 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
364 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
365 fdp->fd_fd.fd_nfiles = NDFILE;
366
367 /* Create the limits structures. */
368 p->p_limit = &limit0;
369 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
370 limit0.pl_rlimit[i].rlim_cur =
371 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
372 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur =
373 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
374 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur =
375 limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
376 i = ptoa(cnt.v_free_count);
377 limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
378 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
379 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
380 limit0.p_refcnt = 1;
381
382 /* Allocate a prototype map so we have something to fork. */
383 pmap_pinit0(&vmspace0.vm_pmap);
384 p->p_vmspace = &vmspace0;
385 vmspace0.vm_refcnt = 1;
386 vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
387 trunc_page(VM_MAXUSER_ADDRESS));
388 vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
389 p->p_addr = proc0paddr; /* XXX */
390
391#define INCOMPAT_LITES2
392#ifdef INCOMPAT_LITES2
393 /*
394 * proc0 needs to have a coherent frame base in it's stack.
394 * proc0 needs to have a coherent frame base in its stack.
395 */
396 cpu_set_init_frame(p, init_framep); /* XXX! */
397#endif /* INCOMPAT_LITES2*/
398
399 /*
400 * We continue to place resource usage info and signal
401 * actions in the user struct so they're pageable.
402 */
403 p->p_stats = &p->p_addr->u_stats;
404 p->p_sigacts = &p->p_addr->u_sigacts;
405
406 /*
407 * Charge root for one process.
408 */
409 (void)chgproccnt(0, 1);
410
411 /*
412 * Initialize the procfs flags (to 0, of course)
413 */
414 p->p_stops = p->p_stype = p->p_step = 0;
415
416}
417SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
418
419/* ARGSUSED*/
420static void proc0_post __P((void *dummy));
421static void
422proc0_post(dummy)
423 void *dummy;
424{
425 struct timespec ts;
426
427 /*
428 * Now can look at time, having had a chance to verify the time
429 * from the file system. Reset p->p_rtime as it may have been
430 * munched in mi_switch() after the time got set. Set
431 * p->p_runtime to be consistent with this unmunching.
432 */
433 microtime(&proc0.p_stats->p_start);
434 timevalclear(&proc0.p_rtime);
435 microruntime(&proc0.p_runtime);
436
437 /*
438 * Give the ``random'' number generator a thump.
439 * XXX: Does read_random() contain enough bits to be used here ?
440 */
441 nanotime(&ts);
442 srandom(ts.tv_sec ^ ts.tv_nsec);
443
444 /* Initialize signal state for process 0. */
445 siginit(&proc0);
446}
447SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
448
449
450
451
452/*
453 ***************************************************************************
454 ****
455 **** The following SYSINIT's and glue code should be moved to the
456 **** respective files on a per subsystem basis.
457 ****
458 ***************************************************************************
459 */
460
461/* ARGSUSED */
462static void root_conf __P((void *dummy));
463static void
464root_conf(dummy)
465 void *dummy;
466{
467 cpu_rootconf();
468}
469SYSINIT(root_conf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, root_conf, NULL)
470
471/* ARGSUSED*/
472static void xxx_vfs_root_fdtab __P((void *dummy));
473static void
474xxx_vfs_root_fdtab(dummy)
475 void *dummy;
476{
477 register struct filedesc0 *fdp = &filedesc0;
478
479 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
480 if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
481 panic("cannot find root vnode");
482 fdp->fd_fd.fd_cdir = rootvnode;
483 VREF(fdp->fd_fd.fd_cdir);
484 VOP_UNLOCK(rootvnode, 0, &proc0);
485 fdp->fd_fd.fd_rdir = rootvnode;
486}
487SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
488
489
490/*
491 ***************************************************************************
492 ****
493 **** The following code probably belongs in another file, like
494 **** kern/init_init.c. It is here for two reasons only:
495 ****
496 **** 1) This code returns to startup the system; this is
497 **** abnormal for a kernel thread.
498 **** 2) This code promiscuously uses init_frame
499 ****
500 ***************************************************************************
501 */
502
503static void kthread_init __P((void *dummy));
504SYSINIT_KP(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
505
506
507extern void prepare_usermode __P((void));
508static void start_init __P((struct proc *p));
509
510/* ARGSUSED*/
511static void
512kthread_init(dummy)
513 void *dummy;
514{
515 /* Create process 1 (init(8)). */
516 start_init(curproc);
517
518 prepare_usermode();
519
520 /*
521 * This returns to the fork trampoline, then to user mode.
522 */
523 return;
524}
525
526
527/*
528 * List of paths to try when searching for "init".
529 */
530static char *initpaths[] = {
531 "/sbin/init",
532 "/sbin/oinit",
533 "/sbin/init.bak",
534 "/stand/sysinstall",
535 NULL,
536};
537
538/*
539 * Start the initial user process; try exec'ing each pathname in "initpaths".
540 * The program is invoked with one argument containing the boot flags.
541 */
542static void
543start_init(p)
544 struct proc *p;
545{
546 vm_offset_t addr;
547 struct execve_args args;
548 int options, i, error;
549 char **pathp, *path, *ucp, **uap, *arg0, *arg1;
550
551 initproc = p;
552
553 /*
554 * Need just enough stack to hold the faked-up "execve()" arguments.
555 */
556 addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE);
557 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
558 panic("init: couldn't allocate argument space");
559 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
560 p->p_vmspace->vm_ssize = 1;
561
562 for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
563 /*
564 * Move out the boot flag argument.
565 */
566 options = 0;
567 ucp = (char *)USRSTACK;
568 (void)subyte(--ucp, 0); /* trailing zero */
569 if (boothowto & RB_SINGLE) {
570 (void)subyte(--ucp, 's');
571 options = 1;
572 }
573#ifdef notyet
574 if (boothowto & RB_FASTBOOT) {
575 (void)subyte(--ucp, 'f');
576 options = 1;
577 }
578#endif
579
580#ifdef BOOTCDROM
581 (void)subyte(--ucp, 'C');
582 options = 1;
583#endif
584
585#if defined(DEVFS) && defined(DEVFS_ROOT)
586 (void)subyte(--ucp, 'd');
587 options = 1;
588#endif
589 if (options == 0)
590 (void)subyte(--ucp, '-');
591 (void)subyte(--ucp, '-'); /* leading hyphen */
592 arg1 = ucp;
593
594 /*
595 * Move out the file name (also arg 0).
596 */
597 for (i = strlen(path) + 1; i >= 0; i--)
598 (void)subyte(--ucp, path[i]);
599 arg0 = ucp;
600
601 /*
602 * Move out the arg pointers.
603 */
604 uap = (char **)((int)ucp & ~(NBPW-1));
605 (void)suword((caddr_t)--uap, 0); /* terminator */
606 (void)suword((caddr_t)--uap, (int)arg1);
607 (void)suword((caddr_t)--uap, (int)arg0);
608
609 /*
610 * Point at the arguments.
611 */
612 args.fname = arg0;
613 args.argv = uap;
614 args.envv = NULL;
615
616 /*
617 * Now try to exec the program. If can't for any reason
618 * other than it doesn't exist, complain.
619 *
620 * Otherwise return to main() which returns to btext
621 * which completes the system startup.
622 */
623 if ((error = execve(p, &args)) == 0)
624 return;
625 if (error != ENOENT)
626 printf("exec %s: error %d\n", path, error);
627 }
628 printf("init: not found\n");
629 panic("no init");
630}
395 */
396 cpu_set_init_frame(p, init_framep); /* XXX! */
397#endif /* INCOMPAT_LITES2*/
398
399 /*
400 * We continue to place resource usage info and signal
401 * actions in the user struct so they're pageable.
402 */
403 p->p_stats = &p->p_addr->u_stats;
404 p->p_sigacts = &p->p_addr->u_sigacts;
405
406 /*
407 * Charge root for one process.
408 */
409 (void)chgproccnt(0, 1);
410
411 /*
412 * Initialize the procfs flags (to 0, of course)
413 */
414 p->p_stops = p->p_stype = p->p_step = 0;
415
416}
417SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
418
419/* ARGSUSED*/
420static void proc0_post __P((void *dummy));
421static void
422proc0_post(dummy)
423 void *dummy;
424{
425 struct timespec ts;
426
427 /*
428 * Now can look at time, having had a chance to verify the time
429 * from the file system. Reset p->p_rtime as it may have been
430 * munched in mi_switch() after the time got set. Set
431 * p->p_runtime to be consistent with this unmunching.
432 */
433 microtime(&proc0.p_stats->p_start);
434 timevalclear(&proc0.p_rtime);
435 microruntime(&proc0.p_runtime);
436
437 /*
438 * Give the ``random'' number generator a thump.
439 * XXX: Does read_random() contain enough bits to be used here ?
440 */
441 nanotime(&ts);
442 srandom(ts.tv_sec ^ ts.tv_nsec);
443
444 /* Initialize signal state for process 0. */
445 siginit(&proc0);
446}
447SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
448
449
450
451
452/*
453 ***************************************************************************
454 ****
455 **** The following SYSINIT's and glue code should be moved to the
456 **** respective files on a per subsystem basis.
457 ****
458 ***************************************************************************
459 */
460
461/* ARGSUSED */
462static void root_conf __P((void *dummy));
463static void
464root_conf(dummy)
465 void *dummy;
466{
467 cpu_rootconf();
468}
469SYSINIT(root_conf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, root_conf, NULL)
470
471/* ARGSUSED*/
472static void xxx_vfs_root_fdtab __P((void *dummy));
473static void
474xxx_vfs_root_fdtab(dummy)
475 void *dummy;
476{
477 register struct filedesc0 *fdp = &filedesc0;
478
479 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
480 if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
481 panic("cannot find root vnode");
482 fdp->fd_fd.fd_cdir = rootvnode;
483 VREF(fdp->fd_fd.fd_cdir);
484 VOP_UNLOCK(rootvnode, 0, &proc0);
485 fdp->fd_fd.fd_rdir = rootvnode;
486}
487SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
488
489
490/*
491 ***************************************************************************
492 ****
493 **** The following code probably belongs in another file, like
494 **** kern/init_init.c. It is here for two reasons only:
495 ****
496 **** 1) This code returns to startup the system; this is
497 **** abnormal for a kernel thread.
498 **** 2) This code promiscuously uses init_frame
499 ****
500 ***************************************************************************
501 */
502
503static void kthread_init __P((void *dummy));
504SYSINIT_KP(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
505
506
507extern void prepare_usermode __P((void));
508static void start_init __P((struct proc *p));
509
510/* ARGSUSED*/
511static void
512kthread_init(dummy)
513 void *dummy;
514{
515 /* Create process 1 (init(8)). */
516 start_init(curproc);
517
518 prepare_usermode();
519
520 /*
521 * This returns to the fork trampoline, then to user mode.
522 */
523 return;
524}
525
526
527/*
528 * List of paths to try when searching for "init".
529 */
530static char *initpaths[] = {
531 "/sbin/init",
532 "/sbin/oinit",
533 "/sbin/init.bak",
534 "/stand/sysinstall",
535 NULL,
536};
537
538/*
539 * Start the initial user process; try exec'ing each pathname in "initpaths".
540 * The program is invoked with one argument containing the boot flags.
541 */
542static void
543start_init(p)
544 struct proc *p;
545{
546 vm_offset_t addr;
547 struct execve_args args;
548 int options, i, error;
549 char **pathp, *path, *ucp, **uap, *arg0, *arg1;
550
551 initproc = p;
552
553 /*
554 * Need just enough stack to hold the faked-up "execve()" arguments.
555 */
556 addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE);
557 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
558 panic("init: couldn't allocate argument space");
559 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
560 p->p_vmspace->vm_ssize = 1;
561
562 for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
563 /*
564 * Move out the boot flag argument.
565 */
566 options = 0;
567 ucp = (char *)USRSTACK;
568 (void)subyte(--ucp, 0); /* trailing zero */
569 if (boothowto & RB_SINGLE) {
570 (void)subyte(--ucp, 's');
571 options = 1;
572 }
573#ifdef notyet
574 if (boothowto & RB_FASTBOOT) {
575 (void)subyte(--ucp, 'f');
576 options = 1;
577 }
578#endif
579
580#ifdef BOOTCDROM
581 (void)subyte(--ucp, 'C');
582 options = 1;
583#endif
584
585#if defined(DEVFS) && defined(DEVFS_ROOT)
586 (void)subyte(--ucp, 'd');
587 options = 1;
588#endif
589 if (options == 0)
590 (void)subyte(--ucp, '-');
591 (void)subyte(--ucp, '-'); /* leading hyphen */
592 arg1 = ucp;
593
594 /*
595 * Move out the file name (also arg 0).
596 */
597 for (i = strlen(path) + 1; i >= 0; i--)
598 (void)subyte(--ucp, path[i]);
599 arg0 = ucp;
600
601 /*
602 * Move out the arg pointers.
603 */
604 uap = (char **)((int)ucp & ~(NBPW-1));
605 (void)suword((caddr_t)--uap, 0); /* terminator */
606 (void)suword((caddr_t)--uap, (int)arg1);
607 (void)suword((caddr_t)--uap, (int)arg0);
608
609 /*
610 * Point at the arguments.
611 */
612 args.fname = arg0;
613 args.argv = uap;
614 args.envv = NULL;
615
616 /*
617 * Now try to exec the program. If can't for any reason
618 * other than it doesn't exist, complain.
619 *
620 * Otherwise return to main() which returns to btext
621 * which completes the system startup.
622 */
623 if ((error = execve(p, &args)) == 0)
624 return;
625 if (error != ENOENT)
626 printf("exec %s: error %d\n", path, error);
627 }
628 printf("init: not found\n");
629 panic("no init");
630}