Bad kludge to work around the alternative wd driver problems
[unix-history] / sys / kern / init_main.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
d4d5cd13
RG
33 * from: @(#)init_main.c 7.41 (Berkeley) 5/15/91
34 * $Id$
15637ed4 35 */
15637ed4
RG
36
37#include "param.h"
38#include "filedesc.h"
39#include "kernel.h"
40#include "mount.h"
41#include "proc.h"
42#include "resourcevar.h"
43#include "signalvar.h"
44#include "systm.h"
45#include "vnode.h"
46#include "conf.h"
47#include "buf.h"
48#include "malloc.h"
49#include "protosw.h"
50#include "reboot.h"
51#include "user.h"
5da574a1 52#include "utsname.h"
15637ed4
RG
53
54#include "ufs/quota.h"
55
56#include "machine/cpu.h"
57
58#include "vm/vm.h"
59
29b4e64c 60char copyright[] =
15637ed4 61"Copyright (c) 1989,1990,1991,1992 William F. Jolitz. All rights reserved.\n\
29b4e64c
NW
62Copyright (c) 1982,1986,1989,1991 The Regents of the University\n\
63of California. All rights reserved.\n\n";
15637ed4 64
5da574a1
JH
65/* For uname() */
66struct utsname utsname;
67
15637ed4
RG
68/*
69 * Components of process 0;
70 * never freed.
71 */
72struct session session0;
73struct pgrp pgrp0;
74struct proc proc0;
75struct pcred cred0;
76struct filedesc0 filedesc0;
77struct plimit limit0;
78struct vmspace vmspace0;
79struct proc *curproc = &proc0;
80struct proc *initproc, *pageproc;
81
82int cmask = CMASK;
83extern struct user *proc0paddr;
84extern int (*mountroot)();
85
86struct vnode *rootvp, *swapdev_vp;
87int boothowto;
88
d4d5cd13
RG
89#if __GNUC__ >= 2
90__main() {}
91#endif
92
15637ed4
RG
93/*
94 * System startup; initialize the world, create process 0,
95 * mount root filesystem, and fork to create init and pagedaemon.
96 * Most of the hard work is done in the lower-level initialization
97 * routines including startup(), which does memory initialization
98 * and autoconfiguration.
99 */
100main()
101{
102 register int i;
103 register struct proc *p;
104 register struct filedesc0 *fdp;
105 int s, rval[2];
5da574a1 106 char *cp;
15637ed4
RG
107
108 /*
109 * Initialize curproc before any possible traps/probes
110 * to simplify trap processing.
111 */
112 p = &proc0;
113 curproc = p;
114 /*
115 * Attempt to find console and initialize
116 * in case of early panic or other messages.
117 */
118 startrtclock();
119 consinit();
120
29b4e64c 121 printf("%s", copyright);
15637ed4
RG
122
123 vm_mem_init();
124 kmeminit();
125 cpu_startup();
126
127 /*
128 * set up system process 0 (swapper)
129 */
130 p = &proc0;
131 curproc = p;
132
133 allproc = p;
134 p->p_prev = &allproc;
135 p->p_pgrp = &pgrp0;
136 pgrphash[0] = &pgrp0;
137 pgrp0.pg_mem = p;
138 pgrp0.pg_session = &session0;
139 session0.s_count = 1;
140 session0.s_leader = p;
141
142 p->p_flag = SLOAD|SSYS;
143 p->p_stat = SRUN;
144 p->p_nice = NZERO;
145 bcopy("swapper", p->p_comm, sizeof ("swapper"));
146
147 /*
148 * Setup credentials
149 */
150 cred0.p_refcnt = 1;
151 p->p_cred = &cred0;
152 p->p_ucred = crget();
153 p->p_ucred->cr_ngroups = 1; /* group 0 */
154
155 /*
156 * Create the file descriptor table for process 0.
157 */
158 fdp = &filedesc0;
159 p->p_fd = &fdp->fd_fd;
160 fdp->fd_fd.fd_refcnt = 1;
161 fdp->fd_fd.fd_cmask = cmask;
162 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
163 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
164 fdp->fd_fd.fd_nfiles = NDFILE;
165
166 /*
167 * Set initial limits
168 */
169 p->p_limit = &limit0;
170 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
171 limit0.pl_rlimit[i].rlim_cur =
172 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
173 limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE;
174 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
175 limit0.p_refcnt = 1;
176
177 /*
178 * Allocate a prototype map so we have something to fork
179 */
180 p->p_vmspace = &vmspace0;
181 vmspace0.vm_refcnt = 1;
182 pmap_pinit(&vmspace0.vm_pmap);
183 vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS),
184 trunc_page(VM_MAX_ADDRESS), TRUE);
185 vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
186 p->p_addr = proc0paddr; /* XXX */
187
188 /*
189 * We continue to place resource usage info
190 * and signal actions in the user struct so they're pageable.
191 */
192 p->p_stats = &p->p_addr->u_stats;
193 p->p_sigacts = &p->p_addr->u_sigacts;
194
195 rqinit();
196
197 /*
198 * configure virtual memory system,
199 * set vm rlimits
200 */
201 vm_init_limits(p);
202
203 /*
204 * Initialize the file systems.
205 *
206 * Get vnodes for swapdev and rootdev.
207 */
208 vfsinit();
209 if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
210 panic("can't setup bdevvp's");
211
212#if defined(vax)
213#include "kg.h"
214#if NKG > 0
215 startkgclock();
216#endif
217#endif
218
219 /*
220 * Initialize tables, protocols, and set up well-known inodes.
221 */
222 mbinit();
223#ifdef SYSVSHM
224 shminit();
225#endif
226#include "sl.h"
227#if NSL > 0
228 slattach(); /* XXX */
229#endif
8b3438a6
RG
230#include "ppp.h"
231#if NPPP > 0
232 pppattach(); /* XXX */
233#endif
15637ed4
RG
234#include "loop.h"
235#if NLOOP > 0
236 loattach(); /* XXX */
237#endif
238 /*
239 * Block reception of incoming packets
240 * until protocols have been initialized.
241 */
242 s = splimp();
243 ifinit();
244 domaininit();
245 splx(s);
246
247#ifdef GPROF
248 kmstartup();
249#endif
250
251 /* kick off timeout driven events by calling first time */
252 roundrobin();
253 schedcpu();
254 enablertclock(); /* enable realtime clock interrupts */
255
256 /*
257 * Set up the root file system and vnode.
258 */
259 if ((*mountroot)())
260 panic("cannot mount root");
261 /*
262 * Get vnode for '/'.
263 * Setup rootdir and fdp->fd_fd.fd_cdir to point to it.
264 */
265 if (VFS_ROOT(rootfs, &rootdir))
266 panic("cannot find root vnode");
267 fdp->fd_fd.fd_cdir = rootdir;
268 VREF(fdp->fd_fd.fd_cdir);
269 VOP_UNLOCK(rootdir);
270 fdp->fd_fd.fd_rdir = NULL;
271 swapinit();
272
273 /*
274 * Now can look at time, having had a chance
275 * to verify the time from the file system.
276 */
277 boottime = p->p_stats->p_start = time;
278
5da574a1
JH
279 /*
280 * Setup version number for uname syscall
281 * XXX probably should go elsewhere.
282 */
283 bzero(utsname.sysname, sizeof(utsname.sysname));
284 for (cp = version, i= 0;
285 *cp && *cp != ' ' && i <= sizeof(utsname.sysname);
286 )
287 utsname.sysname[i++] = *cp++;
288 bzero(utsname.release, sizeof(utsname.release));
289 for (cp++, i= 0; *cp && *cp != ' ' && i <= sizeof(utsname.release);)
290 utsname.release[i++] = *cp++;
291 bzero(utsname.version, sizeof(utsname.version));
292 for (; *cp != '('; cp++);
293 for (cp++, i= 0; *cp && *cp != ')' && i <= sizeof(utsname.version);)
294 utsname.version[i++] = *cp++;
295 for (; *cp != '#'; cp++);
296 if(i <= sizeof(utsname.version))
297 utsname.version[i++] = '#';
298 for (cp++; *cp && *cp != ':' && i <= sizeof(utsname.version);)
299 utsname.version[i++] = *cp++;
300 strncpy(utsname.machine, MACHINE, sizeof(utsname.machine));
301 utsname.machine[sizeof(utsname.machine)-1] = '\0';
302
15637ed4
RG
303 /*
304 * make init process
305 */
306 siginit(p);
307 if (fork(p, (void *) NULL, rval))
308 panic("fork init");
309 if (rval[1]) {
310 static char initflags[] = "-sf";
311 char *ip = initflags + 1;
312 vm_offset_t addr = 0;
313 extern int icode[]; /* user init code */
314 extern int szicode; /* size of icode */
315
316 /*
317 * Now in process 1. Set init flags into icode,
318 * get a minimal address space, copy out "icode",
319 * and return to it to do an exec of init.
320 */
321 p = curproc;
322 initproc = p;
323 if (boothowto&RB_SINGLE)
324 *ip++ = 's';
325#ifdef notyet
326 if (boothowto&RB_FASTBOOT)
327 *ip++ = 'f';
328#endif
329 *ip++ = '\0';
330
331 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
332 round_page(szicode + sizeof(initflags)), FALSE) != 0 ||
333 addr != 0)
334 panic("init: couldn't allocate at zero");
335
336 /* need just enough stack to exec from */
337 addr = trunc_page(USRSTACK - MAXSSIZ);
338 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
339 MAXSSIZ, FALSE) != KERN_SUCCESS)
340 panic("vm_allocate init stack");
341 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
342 p->p_vmspace->vm_ssize = 1;
343 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
344 (void) copyout(initflags, (caddr_t)szicode, sizeof(initflags));
345 return; /* returns to icode */
346 }
347
348 /*
349 * Start up pageout daemon (process 2).
350 */
351 if (fork(p, (void *) NULL, rval))
352 panic("fork pager");
353 if (rval[1]) {
354 /*
355 * Now in process 2.
356 */
357 p = curproc;
358 pageproc = p;
359 p->p_flag |= SLOAD|SSYS; /* XXX */
360 bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
361 vm_pageout();
362 /*NOTREACHED*/
363 }
364
365 /*
366 * enter scheduling loop
367 */
368 sched();
369}