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