u. is gone, pcb is at p_addr; aston => signotify
[unix-history] / usr / src / sys / kern / init_main.c
CommitLineData
da7c5cc6 1/*
d7db4999 2 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
2d9d8fa8 3 * All rights reserved.
da7c5cc6 4 *
2d9d8fa8
MK
5 * %sccs.include.redist.c%
6 *
f657c741 7 * @(#)init_main.c 7.38 (Berkeley) %G%
da7c5cc6 8 */
961945a8 9
94368568 10#include "param.h"
5e00df3b 11#include "filedesc.h"
94368568 12#include "kernel.h"
94368568
JB
13#include "mount.h"
14#include "map.h"
15#include "proc.h"
c040c6b1
MK
16#include "resourcevar.h"
17#include "signalvar.h"
18#include "systm.h"
475798b6 19#include "vnode.h"
94368568
JB
20#include "seg.h"
21#include "conf.h"
22#include "buf.h"
94368568 23#include "clist.h"
8fe87cbb 24#include "malloc.h"
94368568 25#include "protosw.h"
f378da4c 26#include "reboot.h"
c040c6b1
MK
27#include "user.h"
28
d301d150 29
d301d150 30#include "machine/cpu.h"
961945a8 31
d7db4999 32#include "vm/vm.h"
d7db4999
MK
33
34/*
35 * Components of process 0;
36 * never freed.
37 */
38struct session session0;
39struct pgrp pgrp0;
40struct proc proc0;
41struct pcred cred0;
c040c6b1 42struct filedesc0 filedesc0;
d7db4999
MK
43struct plimit limit0;
44struct vmspace vmspace0;
c040c6b1 45struct proc *curproc = &proc0;
d7db4999 46struct proc *initproc, *pageproc;
9d4095a1 47
28c7a4c5 48int cmask = CMASK;
f657c741 49extern struct user *proc0paddr;
475798b6 50extern int (*mountroot)();
362786f8 51
c4708522 52/*
d7db4999
MK
53 * System startup; initialize the world, create process 0,
54 * mount root filesystem, and fork to create init and pagedaemon.
55 * Most of the hard work is done in the lower-level initialization
56 * routines including startup(), which does memory initialization
57 * and autoconfiguration.
c4708522
BJ
58 */
59main(firstaddr)
b7892118 60 int firstaddr;
c4708522 61{
73248996 62 register int i;
dd4b582c 63 register struct proc *p;
c040c6b1 64 register struct filedesc0 *fdp;
d7db4999 65 int s, rval[2];
083baeb6 66
362786f8 67 /*
d7db4999
MK
68 * Initialize curproc before any possible traps/probes
69 * to simplify trap processing.
362786f8 70 */
d7db4999
MK
71 p = &proc0;
72 curproc = p;
9d4095a1 73 /*
d7db4999
MK
74 * Attempt to find console and initialize
75 * in case of early panic or other messages.
9d4095a1 76 */
d7db4999
MK
77 consinit();
78
9d4095a1
KM
79 vm_mem_init();
80 kmeminit();
c4708522 81 startup(firstaddr);
c4708522
BJ
82
83 /*
84 * set up system process 0 (swapper)
85 */
d7db4999
MK
86 p = &proc0;
87 curproc = p;
88
89 allproc = p;
90 p->p_prev = &allproc;
91 p->p_pgrp = &pgrp0;
92 pgrphash[0] = &pgrp0;
93 pgrp0.pg_mem = p;
94 pgrp0.pg_session = &session0;
95 session0.s_count = 1;
96 session0.s_leader = p;
97
98 p->p_flag = SLOAD|SSYS;
dd4b582c 99 p->p_stat = SRUN;
dd4b582c 100 p->p_nice = NZERO;
d7db4999
MK
101 bcopy("swapper", p->p_comm, sizeof ("swapper"));
102
9d4095a1 103 /*
d7db4999 104 * Setup credentials
14fda239 105 */
d7db4999
MK
106 p->p_cred = &cred0;
107 p->p_ucred = crget();
108 p->p_ucred->cr_ngroups = 1; /* group 0 */
fb1db32c 109
5e00df3b
KM
110 /*
111 * Create the file descriptor table for process 0.
112 */
d7db4999 113 fdp = &filedesc0;
c040c6b1
MK
114 p->p_fd = &fdp->fd_fd;
115 fdp->fd_fd.fd_refcnt = 1;
116 fdp->fd_fd.fd_cmask = cmask;
117 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
118 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
119 fdp->fd_fd.fd_nfiles = NDFILE;
d7db4999
MK
120
121 /*
122 * Set initial limits
123 */
124 p->p_limit = &limit0;
125 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
126 limit0.pl_rlimit[i].rlim_cur =
127 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
128 limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE;
129 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
130 limit0.p_refcnt = 1;
131
132 /*
133 * Allocate a prototype map so we have something to fork
134 */
135 p->p_vmspace = &vmspace0;
136 vmspace0.vm_refcnt = 1;
137 pmap_pinit(&vmspace0.vm_pmap);
138 vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS),
139 trunc_page(VM_MAX_ADDRESS), TRUE);
140 vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
141 p->p_addr = proc0paddr; /* XXX */
142
143 /*
144 * We continue to place resource usage info
145 * and signal actions in the user struct so they're pageable.
146 */
f657c741
MK
147 p->p_stats = &p->p_addr->u_stats;
148 p->p_sigacts = &p->p_addr->u_sigacts;
d7db4999
MK
149
150 rqinit();
151
4898b838 152 /*
8ede3c1b
MK
153 * configure virtual memory system,
154 * set vm rlimits
4898b838 155 */
d7db4999 156 vm_init_limits(p);
8ede3c1b 157
475798b6 158 /*
85570e35
KM
159 * Initialize the file systems.
160 *
475798b6
KM
161 * Get vnodes for swapdev, argdev, and rootdev.
162 */
85570e35 163 vfsinit();
475798b6
KM
164 if (bdevvp(swapdev, &swapdev_vp) ||
165 bdevvp(argdev, &argdev_vp) ||
166 bdevvp(rootdev, &rootvp))
167 panic("can't setup bdevvp's");
168
c70d0a8b 169 startrtclock();
5cb75b5d 170#if defined(vax)
f882447b
SL
171#include "kg.h"
172#if NKG > 0
d0ab60b1 173 startkgclock();
fb1db32c 174#endif
d0ab60b1 175#endif
c4708522
BJ
176
177 /*
d872f034 178 * Initialize tables, protocols, and set up well-known inodes.
c4708522 179 */
d872f034 180 mbinit();
a5829200 181 cinit();
933220e9
KM
182#ifdef SYSVSHM
183 shminit();
184#endif
730ff8ce
MK
185#include "sl.h"
186#if NSL > 0
187 slattach(); /* XXX */
188#endif
933220e9 189#include "loop.h"
4f4caf05
BJ
190#if NLOOP > 0
191 loattach(); /* XXX */
192#endif
4f083fd7
SL
193 /*
194 * Block reception of incoming packets
195 * until protocols have been initialized.
196 */
197 s = splimp();
fbf9a431 198 ifinit();
b7892118 199 domaininit();
4f083fd7 200 splx(s);
d7db4999 201
e6254ffb
BJ
202#ifdef GPROF
203 kmstartup();
204#endif
9d6d37ce 205
d7db4999 206 /* kick off timeout driven events by calling first time */
27b91f59
BJ
207 roundrobin();
208 schedcpu();
362786f8 209 enablertclock(); /* enable realtime clock interrupts */
27b91f59 210
d7db4999
MK
211 /*
212 * Set up the root file system and vnode.
213 */
475798b6
KM
214 if ((*mountroot)())
215 panic("cannot mount root");
216 /*
217 * Get vnode for '/'.
c040c6b1 218 * Setup rootdir and fdp->fd_fd.fd_cdir to point to it.
475798b6
KM
219 */
220 if (VFS_ROOT(rootfs, &rootdir))
221 panic("cannot find root vnode");
c040c6b1
MK
222 fdp->fd_fd.fd_cdir = rootdir;
223 VREF(fdp->fd_fd.fd_cdir);
3ca85ace 224 VOP_UNLOCK(rootdir);
c040c6b1 225 fdp->fd_fd.fd_rdir = NULL;
d7db4999 226 swapinit();
c4708522 227
28c7a4c5 228 /*
d7db4999
MK
229 * Now can look at time, having had a chance
230 * to verify the time from the file system.
28c7a4c5 231 */
d7db4999 232 boottime = p->p_stats->p_start = time;
28c7a4c5 233
d7db4999
MK
234 /*
235 * make init process
236 */
237 siginit(p);
238 if (fork(p, (void *) NULL, rval))
239 panic("fork init");
240 if (rval[1]) {
83cf086b
MK
241 static char initflags[] = "-sf";
242 char *ip = initflags + 1;
9d4095a1
KM
243 vm_offset_t addr = 0;
244
d7db4999
MK
245 /*
246 * Now in process 1. Set init flags into icode,
247 * get a minimal address space, copy out "icode",
248 * and return to it to do an exec of init.
249 */
250 p = curproc;
251 initproc = p;
d7db4999
MK
252 if (boothowto&RB_SINGLE)
253 *ip++ = 's';
254#ifdef notyet
255 if (boothowto&RB_FASTBOOT)
256 *ip++ = 'f';
d7db4999 257#endif
83cf086b 258 *ip++ = '\0';
d7db4999
MK
259
260 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
83cf086b
MK
261 round_page(szicode + sizeof(initflags)), FALSE) != 0 ||
262 addr != 0)
9d4095a1
KM
263 panic("init: couldn't allocate at zero");
264
265 /* need just enough stack to exec from */
f657c741 266 addr = trunc_page(USRSTACK - PAGE_SIZE);
d7db4999
MK
267 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
268 PAGE_SIZE, FALSE) != KERN_SUCCESS)
269 panic("vm_allocate init stack");
270 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
28c7a4c5 271 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
83cf086b 272 (void) copyout(initflags, (caddr_t)szicode, sizeof(initflags));
d7db4999 273 return; /* returns to icode */
28c7a4c5 274 }
d7db4999 275
c4708522 276 /*
9d4095a1 277 * Start up pageout daemon (process 2).
c4708522 278 */
d7db4999
MK
279 if (fork(p, (void *) NULL, rval))
280 panic("fork pager");
281 if (rval[1]) {
282 /*
283 * Now in process 2.
284 */
285 p = curproc;
286 pageproc = p;
287 p->p_flag |= SLOAD|SSYS; /* XXX */
288 bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
9d4095a1 289 vm_pageout();
b7892118 290 /*NOTREACHED*/
c4708522
BJ
291 }
292
293 /*
c4708522
BJ
294 * enter scheduling loop
295 */
c4708522
BJ
296 sched();
297}
298
d7db4999 299/* MOVE TO vfs_bio.c (bufinit) XXX */
94d38c1e 300/*
d7db4999 301 * Initialize buffers and hash links for buffers.
94d38c1e 302 */
d7db4999 303bufinit()
94d38c1e
KM
304{
305 register int i;
21c39d9c 306 register struct buf *bp, *dp;
d7db4999 307 register struct bufhd *hp;
af371633 308 int base, residual;
c4708522 309
d7db4999
MK
310 for (hp = bufhash, i = 0; i < BUFHSZ; i++, hp++)
311 hp->b_forw = hp->b_back = (struct buf *)hp;
312
63e97a1d
BJ
313 for (dp = bfreelist; dp < &bfreelist[BQUEUES]; dp++) {
314 dp->b_forw = dp->b_back = dp->av_forw = dp->av_back = dp;
315 dp->b_flags = B_HEAD;
316 }
af371633
KM
317 base = bufpages / nbuf;
318 residual = bufpages % nbuf;
6459ebe0 319 for (i = 0; i < nbuf; i++) {
c4708522
BJ
320 bp = &buf[i];
321 bp->b_dev = NODEV;
4f083fd7 322 bp->b_bcount = 0;
29561cd7
KM
323 bp->b_rcred = NOCRED;
324 bp->b_wcred = NOCRED;
325 bp->b_dirtyoff = 0;
326 bp->b_dirtyend = 0;
6459ebe0 327 bp->b_un.b_addr = buffers + i * MAXBSIZE;
af371633
KM
328 if (i < residual)
329 bp->b_bufsize = (base + 1) * CLBYTES;
330 else
331 bp->b_bufsize = base * CLBYTES;
961945a8 332 binshash(bp, &bfreelist[BQ_AGE]);
63e97a1d 333 bp->b_flags = B_BUSY|B_INVAL;
c4708522
BJ
334 brelse(bp);
335 }
fa1a0164 336}