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