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