minor formatting and comment changes; removed some old #if 0'd code.
[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 33 * from: @(#)init_main.c 7.41 (Berkeley) 5/15/91
6ea0a677 34 * $Id: init_main.c,v 1.14 1994/01/14 16:24:45 davidg Exp $
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
3228baa0 60const char 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
933ee974
DG
89struct proc *updateproc;
90
d4d5cd13 91#if __GNUC__ >= 2
4c45483e 92void __main() {}
d4d5cd13
RG
93#endif
94
3228baa0
GW
95/*
96 * This table is filled in by the linker with functions that need to be
97 * called to initialize various pseudo-devices and whatnot.
98 */
99typedef void (*pseudo_func_t)(void);
100extern const struct linker_set pseudo_set;
101static const pseudo_func_t *pseudos =
102 (const pseudo_func_t *)&pseudo_set.ls_items[0];
103
15637ed4
RG
104/*
105 * System startup; initialize the world, create process 0,
106 * mount root filesystem, and fork to create init and pagedaemon.
107 * Most of the hard work is done in the lower-level initialization
108 * routines including startup(), which does memory initialization
109 * and autoconfiguration.
110 */
4c45483e 111void
15637ed4
RG
112main()
113{
114 register int i;
115 register struct proc *p;
116 register struct filedesc0 *fdp;
117 int s, rval[2];
1d7f5b47 118 const char *cp;
15637ed4
RG
119
120 /*
121 * Initialize curproc before any possible traps/probes
122 * to simplify trap processing.
123 */
124 p = &proc0;
125 curproc = p;
126 /*
127 * Attempt to find console and initialize
128 * in case of early panic or other messages.
129 */
130 startrtclock();
131 consinit();
132
29b4e64c 133 printf("%s", copyright);
15637ed4
RG
134
135 vm_mem_init();
136 kmeminit();
137 cpu_startup();
138
139 /*
140 * set up system process 0 (swapper)
141 */
142 p = &proc0;
143 curproc = p;
144
145 allproc = p;
146 p->p_prev = &allproc;
147 p->p_pgrp = &pgrp0;
148 pgrphash[0] = &pgrp0;
149 pgrp0.pg_mem = p;
150 pgrp0.pg_session = &session0;
151 session0.s_count = 1;
152 session0.s_leader = p;
153
154 p->p_flag = SLOAD|SSYS;
155 p->p_stat = SRUN;
156 p->p_nice = NZERO;
157 bcopy("swapper", p->p_comm, sizeof ("swapper"));
158
159 /*
160 * Setup credentials
161 */
162 cred0.p_refcnt = 1;
163 p->p_cred = &cred0;
164 p->p_ucred = crget();
165 p->p_ucred->cr_ngroups = 1; /* group 0 */
166
167 /*
168 * Create the file descriptor table for process 0.
169 */
170 fdp = &filedesc0;
171 p->p_fd = &fdp->fd_fd;
172 fdp->fd_fd.fd_refcnt = 1;
173 fdp->fd_fd.fd_cmask = cmask;
174 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
175 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
176 fdp->fd_fd.fd_nfiles = NDFILE;
177
178 /*
179 * Set initial limits
180 */
181 p->p_limit = &limit0;
182 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
183 limit0.pl_rlimit[i].rlim_cur =
184 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
185 limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE;
186 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
187 limit0.p_refcnt = 1;
188
189 /*
190 * Allocate a prototype map so we have something to fork
191 */
192 p->p_vmspace = &vmspace0;
193 vmspace0.vm_refcnt = 1;
194 pmap_pinit(&vmspace0.vm_pmap);
195 vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS),
196 trunc_page(VM_MAX_ADDRESS), TRUE);
197 vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
198 p->p_addr = proc0paddr; /* XXX */
199
200 /*
201 * We continue to place resource usage info
202 * and signal actions in the user struct so they're pageable.
203 */
204 p->p_stats = &p->p_addr->u_stats;
205 p->p_sigacts = &p->p_addr->u_sigacts;
206
207 rqinit();
208
209 /*
210 * configure virtual memory system,
211 * set vm rlimits
212 */
213 vm_init_limits(p);
214
215 /*
216 * Initialize the file systems.
217 *
218 * Get vnodes for swapdev and rootdev.
219 */
220 vfsinit();
221 if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
222 panic("can't setup bdevvp's");
223
224#if defined(vax)
225#include "kg.h"
226#if NKG > 0
227 startkgclock();
228#endif
229#endif
230
231 /*
232 * Initialize tables, protocols, and set up well-known inodes.
233 */
234 mbinit();
3228baa0
GW
235
236 while(*pseudos) {
7a248400 237 (**pseudos++)();
3228baa0
GW
238 }
239
15637ed4
RG
240 /*
241 * Block reception of incoming packets
242 * until protocols have been initialized.
243 */
244 s = splimp();
245 ifinit();
246 domaininit();
247 splx(s);
248
249#ifdef GPROF
250 kmstartup();
251#endif
252
253 /* kick off timeout driven events by calling first time */
fde1aeb2
GW
254 roundrobin(0, 0);
255 schedcpu(0, 0);
15637ed4
RG
256 enablertclock(); /* enable realtime clock interrupts */
257
258 /*
259 * Set up the root file system and vnode.
260 */
261 if ((*mountroot)())
262 panic("cannot mount root");
263 /*
264 * Get vnode for '/'.
265 * Setup rootdir and fdp->fd_fd.fd_cdir to point to it.
266 */
267 if (VFS_ROOT(rootfs, &rootdir))
268 panic("cannot find root vnode");
269 fdp->fd_fd.fd_cdir = rootdir;
270 VREF(fdp->fd_fd.fd_cdir);
271 VOP_UNLOCK(rootdir);
272 fdp->fd_fd.fd_rdir = NULL;
273 swapinit();
274
275 /*
276 * Now can look at time, having had a chance
277 * to verify the time from the file system.
278 */
279 boottime = p->p_stats->p_start = time;
280
5da574a1
JH
281 /*
282 * Setup version number for uname syscall
283 * XXX probably should go elsewhere.
284 */
285 bzero(utsname.sysname, sizeof(utsname.sysname));
1d7f5b47
DG
286 for (cp = version, i= 0; *cp && *cp != ' ' && i <= sizeof(utsname.sysname);)
287 utsname.sysname[i++] = *cp++;
5da574a1
JH
288 bzero(utsname.release, sizeof(utsname.release));
289 for (cp++, i= 0; *cp && *cp != ' ' && i <= sizeof(utsname.release);)
1d7f5b47 290 utsname.release[i++] = *cp++;
5da574a1
JH
291 bzero(utsname.version, sizeof(utsname.version));
292 for (; *cp != '('; cp++);
293 for (cp++, i= 0; *cp && *cp != ')' && i <= sizeof(utsname.version);)
1d7f5b47 294 utsname.version[i++] = *cp++;
5da574a1
JH
295 for (; *cp != '#'; cp++);
296 if(i <= sizeof(utsname.version))
1d7f5b47 297 utsname.version[i++] = '#';
5da574a1 298 for (cp++; *cp && *cp != ':' && i <= sizeof(utsname.version);)
1d7f5b47 299 utsname.version[i++] = *cp++;
5da574a1
JH
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
2da7b5c3
NW
329 if (ip == initflags + 1)
330 *ip++ = '-';
15637ed4
RG
331 *ip++ = '\0';
332
333 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
334 round_page(szicode + sizeof(initflags)), FALSE) != 0 ||
335 addr != 0)
336 panic("init: couldn't allocate at zero");
337
338 /* need just enough stack to exec from */
339 addr = trunc_page(USRSTACK - MAXSSIZ);
340 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
341 MAXSSIZ, FALSE) != KERN_SUCCESS)
342 panic("vm_allocate init stack");
343 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
344 p->p_vmspace->vm_ssize = 1;
345 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
346 (void) copyout(initflags, (caddr_t)szicode, sizeof(initflags));
347 return; /* returns to icode */
348 }
349
350 /*
351 * Start up pageout daemon (process 2).
352 */
353 if (fork(p, (void *) NULL, rval))
354 panic("fork pager");
355 if (rval[1]) {
356 /*
357 * Now in process 2.
358 */
359 p = curproc;
360 pageproc = p;
361 p->p_flag |= SLOAD|SSYS; /* XXX */
362 bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
363 vm_pageout();
364 /*NOTREACHED*/
365 }
366
933ee974
DG
367 /*
368 * Start update daemon (process 3).
369 */
6ea0a677 370#ifndef LAPTOP
933ee974
DG
371 if (fork(p, (void *) NULL, rval))
372 panic("fork update");
373 if (rval[1]) {
374 p = curproc;
375 updateproc = p;
376 p->p_flag |= SLOAD|SSYS;
377 bcopy("update", p->p_comm, sizeof("update"));
378 vfs_update();
379 /*NOTREACHED*/
380 }
6ea0a677 381#endif
933ee974 382
15637ed4
RG
383 /*
384 * enter scheduling loop
385 */
386 sched();
387}