date and time created 91/01/10 23:37:32 by mckusick
[unix-history] / usr / src / sys / kern / init_main.c
CommitLineData
da7c5cc6 1/*
475798b6 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
be555728
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
da7c5cc6 5 *
362786f8 6 * @(#)init_main.c 7.31 (Berkeley) %G%
da7c5cc6 7 */
961945a8 8
94368568
JB
9#include "param.h"
10#include "systm.h"
94368568
JB
11#include "user.h"
12#include "kernel.h"
94368568
JB
13#include "mount.h"
14#include "map.h"
15#include "proc.h"
475798b6 16#include "vnode.h"
94368568
JB
17#include "seg.h"
18#include "conf.h"
19#include "buf.h"
94368568 20#include "clist.h"
8fe87cbb 21#include "malloc.h"
94368568 22#include "protosw.h"
f378da4c 23#include "reboot.h"
d301d150 24
d301d150
KM
25#include "machine/reg.h"
26#include "machine/cpu.h"
961945a8 27
9d4095a1
KM
28#include "../vm/vm_param.h"
29#include "../vm/vm_map.h"
30
28c7a4c5 31int cmask = CMASK;
9d4095a1 32extern caddr_t proc0paddr;
475798b6 33extern int (*mountroot)();
362786f8
WN
34#if defined(i386)
35extern char initflags[];
36#endif
37
c4708522
BJ
38/*
39 * Initialization code.
40 * Called from cold start routine as
41 * soon as a stack and segmentation
42 * have been established.
43 * Functions:
44 * clear and free user core
45 * turn on clock
46 * hand craft 0th process
47 * call all initialization routines
48 * fork - process 0 to schedule
c4708522 49 * - process 1 execute bootstrap
a5829200 50 * - process 2 to page out
c4708522
BJ
51 */
52main(firstaddr)
b7892118 53 int firstaddr;
c4708522 54{
73248996 55 register int i;
dd4b582c 56 register struct proc *p;
8fe87cbb 57 register struct pgrp *pg;
4f083fd7 58 int s;
c4708522 59
c4708522 60 rqinit();
362786f8
WN
61#if defined(i386)
62 /*
63 * set boot flags
64 */
65 if (boothowto&RB_SINGLE)
66 bcopy("-s", initflags, 3);
67 else
68 if (boothowto&RB_ASKNAME)
69 bcopy("-a", initflags, 3);
70 else
71 bcopy("-", initflags, 2);
72#endif
9d4095a1
KM
73#if defined(hp300) && defined(DEBUG)
74 /*
75 * Assumes mapping is really on
76 */
77 find_devs();
78 cninit();
79#endif
80 vm_mem_init();
81 kmeminit();
c4708522 82 startup(firstaddr);
c4708522
BJ
83
84 /*
85 * set up system process 0 (swapper)
86 */
dd4b582c 87 p = &proc[0];
25d213eb 88 bcopy("swapper", p->p_comm, sizeof ("swapper"));
dd4b582c
BJ
89 p->p_stat = SRUN;
90 p->p_flag |= SLOAD|SSYS;
91 p->p_nice = NZERO;
9d4095a1
KM
92 /*
93 * Allocate a prototype map so we have something to fork
94 */
95 p->p_map = vm_map_create(pmap_create(0),
96 round_page(VM_MIN_ADDRESS),
97 trunc_page(VM_MAX_ADDRESS), TRUE);
98 p->p_addr = proc0paddr;
dd4b582c 99 u.u_procp = p;
8fe87cbb
MT
100 MALLOC(pgrphash[0], struct pgrp *, sizeof (struct pgrp),
101 M_PGRP, M_NOWAIT);
102 if ((pg = pgrphash[0]) == NULL)
103 panic("no space to craft zero'th process group");
104 pg->pg_id = 0;
105 pg->pg_hforw = 0;
106 pg->pg_mem = p;
107 pg->pg_jobc = 0;
108 p->p_pgrp = pg;
109 p->p_pgrpnxt = 0;
110 MALLOC(pg->pg_session, struct session *, sizeof (struct session),
111 M_SESSION, M_NOWAIT);
112 if (pg->pg_session == NULL)
113 panic("no space to craft zero'th session");
114 pg->pg_session->s_count = 1;
ca7a8dcb
MT
115 pg->pg_session->s_leader = NULL;
116 pg->pg_session->s_ttyvp = NULL;
117 pg->pg_session->s_ttyp = NULL;
27ef8b9b
MT
118#ifdef KTRACE
119 p->p_tracep = NULL;
120 p->p_traceflag = 0;
121#endif
14fda239 122 /*
4898b838
KM
123 * These assume that the u. area is always mapped
124 * to the same virtual address. Otherwise must be
14fda239
KM
125 * handled when copying the u. area in newproc().
126 */
dc456b6b 127 ndinit(&u.u_nd);
fb1db32c 128
28c7a4c5 129 u.u_cmask = cmask;
a5829200 130 u.u_lastfile = -1;
d3003a84
BJ
131 for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++)
132 u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max =
133 RLIM_INFINITY;
4898b838 134 /*
8ede3c1b
MK
135 * configure virtual memory system,
136 * set vm rlimits
4898b838
KM
137 */
138 vminit();
8ede3c1b 139
475798b6 140 /*
85570e35
KM
141 * Initialize the file systems.
142 *
475798b6
KM
143 * Get vnodes for swapdev, argdev, and rootdev.
144 */
85570e35 145 vfsinit();
475798b6
KM
146 if (bdevvp(swapdev, &swapdev_vp) ||
147 bdevvp(argdev, &argdev_vp) ||
148 bdevvp(rootdev, &rootvp))
149 panic("can't setup bdevvp's");
150
151 /*
152 * Setup credentials
153 */
154 u.u_cred = crget();
d106268b 155 u.u_cred->cr_ngroups = 1;
475798b6 156
c70d0a8b 157 startrtclock();
5cb75b5d 158#if defined(vax)
f882447b
SL
159#include "kg.h"
160#if NKG > 0
d0ab60b1 161 startkgclock();
fb1db32c 162#endif
d0ab60b1 163#endif
c4708522
BJ
164
165 /*
d872f034 166 * Initialize tables, protocols, and set up well-known inodes.
c4708522 167 */
d872f034 168 mbinit();
a5829200 169 cinit();
933220e9
KM
170#ifdef SYSVSHM
171 shminit();
172#endif
730ff8ce
MK
173#include "sl.h"
174#if NSL > 0
175 slattach(); /* XXX */
176#endif
933220e9 177#include "loop.h"
4f4caf05
BJ
178#if NLOOP > 0
179 loattach(); /* XXX */
180#endif
4f083fd7
SL
181 /*
182 * Block reception of incoming packets
183 * until protocols have been initialized.
184 */
185 s = splimp();
fbf9a431 186 ifinit();
b7892118 187 domaininit();
4f083fd7 188 splx(s);
1d348849 189 pqinit();
fa1a0164 190 swapinit();
e6254ffb
BJ
191#ifdef GPROF
192 kmstartup();
193#endif
9d6d37ce 194
27b91f59
BJ
195/* kick off timeout driven events by calling first time */
196 roundrobin();
197 schedcpu();
362786f8 198 enablertclock(); /* enable realtime clock interrupts */
27b91f59
BJ
199
200/* set up the root file system */
475798b6
KM
201 if ((*mountroot)())
202 panic("cannot mount root");
203 /*
204 * Get vnode for '/'.
205 * Setup rootdir and u.u_cdir to point to it.
206 */
207 if (VFS_ROOT(rootfs, &rootdir))
208 panic("cannot find root vnode");
209 u.u_cdir = rootdir;
8fe1c702 210 VREF(u.u_cdir);
3ca85ace 211 VOP_UNLOCK(rootdir);
c4708522 212 u.u_rdir = NULL;
5ce8782f 213 boottime = u.u_start = time;
c4708522 214
28c7a4c5
MK
215 /*
216 * make init process
217 */
218
6d21bbfc 219 siginit(&proc[0]);
28c7a4c5 220 if (newproc(0)) {
9d4095a1
KM
221 vm_offset_t addr = 0;
222
223 (void) vm_allocate(u.u_procp->p_map,
224 &addr, round_page(szicode), FALSE);
225 if (addr != 0)
226 panic("init: couldn't allocate at zero");
227
228 /* need just enough stack to exec from */
229 addr = trunc_page(VM_MAX_ADDRESS - PAGE_SIZE);
230 (void) vm_allocate(u.u_procp->p_map, &addr, PAGE_SIZE, FALSE);
231 u.u_maxsaddr = (caddr_t)addr;
28c7a4c5
MK
232 (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
233 /*
234 * Return goes to loc. 0 of user init
235 * code just copied out.
236 */
237 return;
238 }
c4708522 239 /*
9d4095a1 240 * Start up pageout daemon (process 2).
c4708522 241 */
c4708522
BJ
242 if (newproc(0)) {
243 proc[2].p_flag |= SLOAD|SSYS;
25d213eb 244 bcopy("pagedaemon", proc[2].p_comm, sizeof ("pagedaemon"));
9d4095a1 245 vm_pageout();
b7892118 246 /*NOTREACHED*/
c4708522
BJ
247 }
248
249 /*
c4708522
BJ
250 * enter scheduling loop
251 */
c4708522
BJ
252 sched();
253}
254
94d38c1e
KM
255/*
256 * Initialize hash links for buffers.
257 */
258bhinit()
259{
260 register int i;
261 register struct bufhd *bp;
262
263 for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++)
264 bp->b_forw = bp->b_back = (struct buf *)bp;
c4708522
BJ
265}
266
c4708522
BJ
267/*
268 * Initialize the buffer I/O system by freeing
269 * all buffers and setting all device buffer lists to empty.
c4708522
BJ
270 */
271binit()
272{
21c39d9c 273 register struct buf *bp, *dp;
c4708522 274 register int i;
af371633 275 int base, residual;
c4708522 276
63e97a1d
BJ
277 for (dp = bfreelist; dp < &bfreelist[BQUEUES]; dp++) {
278 dp->b_forw = dp->b_back = dp->av_forw = dp->av_back = dp;
279 dp->b_flags = B_HEAD;
280 }
af371633
KM
281 base = bufpages / nbuf;
282 residual = bufpages % nbuf;
6459ebe0 283 for (i = 0; i < nbuf; i++) {
c4708522
BJ
284 bp = &buf[i];
285 bp->b_dev = NODEV;
4f083fd7 286 bp->b_bcount = 0;
29561cd7
KM
287 bp->b_rcred = NOCRED;
288 bp->b_wcred = NOCRED;
289 bp->b_dirtyoff = 0;
290 bp->b_dirtyend = 0;
6459ebe0 291 bp->b_un.b_addr = buffers + i * MAXBSIZE;
af371633
KM
292 if (i < residual)
293 bp->b_bufsize = (base + 1) * CLBYTES;
294 else
295 bp->b_bufsize = base * CLBYTES;
961945a8 296 binshash(bp, &bfreelist[BQ_AGE]);
63e97a1d 297 bp->b_flags = B_BUSY|B_INVAL;
c4708522
BJ
298 brelse(bp);
299 }
fa1a0164
MK
300}
301
302/*
303 * Set up swap devices.
304 * Initialize linked list of free swap
305 * headers. These do not actually point
306 * to buffers, but rather to pages that
307 * are being swapped in and out.
308 */
309swapinit()
310{
311 register int i;
312 register struct buf *sp = swbuf;
313 struct swdevt *swp;
3f36033f 314 int error;
fa1a0164 315
41888f16
BJ
316 /*
317 * Count swap devices, and adjust total swap space available.
fa1a0164 318 * Some of this space will not be available until a swapon()
41888f16
BJ
319 * system is issued, usually when the system goes multi-user.
320 */
321 nswdev = 0;
d668d9ba
SL
322 nswap = 0;
323 for (swp = swdevt; swp->sw_dev; swp++) {
41888f16 324 nswdev++;
d668d9ba
SL
325 if (swp->sw_nblks > nswap)
326 nswap = swp->sw_nblks;
327 }
41888f16 328 if (nswdev == 0)
fa1a0164 329 panic("swapinit");
b2fdd14d 330 if (nswdev > 1)
d668d9ba 331 nswap = ((nswap + dmmax - 1) / dmmax) * dmmax;
41888f16 332 nswap *= nswdev;
475798b6
KM
333 if (bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp))
334 panic("swapvp");
3f36033f
MK
335 if (error = swfree(0)) {
336 printf("swfree errno %d\n", error); /* XXX */
337 panic("swapinit swfree 0");
338 }
c4708522 339
fa1a0164
MK
340 /*
341 * Now set up swap buffer headers.
342 */
c34926db 343 bswlist.av_forw = sp;
0a34b6fd 344 for (i=0; i<nswbuf-1; i++, sp++)
c34926db
BJ
345 sp->av_forw = sp+1;
346 sp->av_forw = NULL;
c4708522 347}
e7c7d88e
BJ
348
349/*
350 * Initialize clist by freeing all character blocks, then count
351 * number of character devices. (Once-only routine)
352 */
353cinit()
354{
355 register int ccp;
356 register struct cblock *cp;
e7c7d88e
BJ
357
358 ccp = (int)cfree;
359 ccp = (ccp+CROUND) & ~CROUND;
360 for(cp=(struct cblock *)ccp; cp < &cfree[nclist-1]; cp++) {
361 cp->c_next = cfreelist;
362 cfreelist = cp;
363 cfreecount += CBSIZE;
364 }
e7c7d88e 365}