xref: /csrg-svn/sys/kern/init_main.c (revision 45914)
123364Smckusick /*
237610Smckusick  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
339480Smckusick  * All rights reserved.  The Berkeley software License Agreement
439480Smckusick  * specifies the terms and conditions for redistribution.
523364Smckusick  *
6*45914Smckusick  *	@(#)init_main.c	7.32 (Berkeley) 01/10/91
723364Smckusick  */
826Sbill 
917087Sbloom #include "param.h"
1017087Sbloom #include "systm.h"
1117087Sbloom #include "user.h"
12*45914Smckusick #include "filedesc.h"
1317087Sbloom #include "kernel.h"
1417087Sbloom #include "mount.h"
1517087Sbloom #include "map.h"
1617087Sbloom #include "proc.h"
1737610Smckusick #include "vnode.h"
1817087Sbloom #include "seg.h"
1917087Sbloom #include "conf.h"
2017087Sbloom #include "buf.h"
2117087Sbloom #include "clist.h"
2237611Smckusick #include "malloc.h"
2317087Sbloom #include "protosw.h"
2430570Skarels #include "reboot.h"
2537610Smckusick #include "../ufs/quota.h"
2626Sbill 
2737522Smckusick #include "machine/reg.h"
2837522Smckusick #include "machine/cpu.h"
2937522Smckusick 
3045724Smckusick #include "../vm/vm_param.h"
3145724Smckusick #include "../vm/vm_map.h"
3245724Smckusick 
3316807Skarels int	cmask = CMASK;
3445724Smckusick extern	caddr_t proc0paddr;
3537610Smckusick extern	int (*mountroot)();
3645880Swilliam #if defined(i386)
3745880Swilliam extern	char	initflags[];
3845880Swilliam #endif
3945880Swilliam 
4026Sbill /*
4126Sbill  * Initialization code.
4226Sbill  * Called from cold start routine as
4326Sbill  * soon as a stack and segmentation
4426Sbill  * have been established.
4526Sbill  * Functions:
4626Sbill  *	clear and free user core
4726Sbill  *	turn on clock
4826Sbill  *	hand craft 0th process
4926Sbill  *	call all initialization routines
5026Sbill  *	fork - process 0 to schedule
5121103Skarels  *	     - process 1 execute bootstrap
5226Sbill  *	     - process 2 to page out
5326Sbill  */
5426Sbill main(firstaddr)
558969Sroot 	int firstaddr;
5626Sbill {
57361Sbill 	register int i;
582451Swnj 	register struct proc *p;
5937611Smckusick 	register struct pgrp *pg;
60*45914Smckusick 	register struct filedesc *fdp;
619156Ssam 	int s;
6226Sbill 
6326Sbill 	rqinit();
6445880Swilliam #if defined(i386)
6545880Swilliam 	/*
6645880Swilliam 	 * set boot flags
6745880Swilliam 	 */
6845880Swilliam 	if (boothowto&RB_SINGLE)
6945880Swilliam 		bcopy("-s", initflags, 3);
7045880Swilliam 	else
7145880Swilliam 		if (boothowto&RB_ASKNAME)
7245880Swilliam 			bcopy("-a", initflags, 3);
7345880Swilliam 	else
7445880Swilliam 		bcopy("-", initflags, 2);
7545880Swilliam #endif
7645724Smckusick #if defined(hp300) && defined(DEBUG)
7745724Smckusick 	/*
7845724Smckusick 	 * Assumes mapping is really on
7945724Smckusick 	 */
8045724Smckusick 	find_devs();
8145724Smckusick 	cninit();
8245724Smckusick #endif
8345724Smckusick 	vm_mem_init();
8445724Smckusick 	kmeminit();
8526Sbill 	startup(firstaddr);
8626Sbill 
8726Sbill 	/*
8826Sbill 	 * set up system process 0 (swapper)
8926Sbill 	 */
902451Swnj 	p = &proc[0];
9140806Smarc 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
922451Swnj 	p->p_stat = SRUN;
932451Swnj 	p->p_flag |= SLOAD|SSYS;
942451Swnj 	p->p_nice = NZERO;
9545724Smckusick 	/*
9645724Smckusick 	 * Allocate a prototype map so we have something to fork
9745724Smckusick 	 */
9845724Smckusick 	p->p_map = vm_map_create(pmap_create(0),
9945724Smckusick 				 round_page(VM_MIN_ADDRESS),
10045724Smckusick 				 trunc_page(VM_MAX_ADDRESS), TRUE);
10145724Smckusick 	p->p_addr = proc0paddr;
1022451Swnj 	u.u_procp = p;
10337611Smckusick 	MALLOC(pgrphash[0], struct pgrp *, sizeof (struct pgrp),
10437611Smckusick 		M_PGRP, M_NOWAIT);
10537611Smckusick 	if ((pg = pgrphash[0]) == NULL)
10637611Smckusick 		panic("no space to craft zero'th process group");
10737611Smckusick 	pg->pg_id = 0;
10837611Smckusick 	pg->pg_hforw = 0;
10937611Smckusick 	pg->pg_mem = p;
11037611Smckusick 	pg->pg_jobc = 0;
11137611Smckusick 	p->p_pgrp = pg;
11237611Smckusick 	p->p_pgrpnxt = 0;
11337611Smckusick 	MALLOC(pg->pg_session, struct session *, sizeof (struct session),
11437611Smckusick 		M_SESSION, M_NOWAIT);
11537611Smckusick 	if (pg->pg_session == NULL)
11637611Smckusick 		panic("no space to craft zero'th session");
11737611Smckusick 	pg->pg_session->s_count = 1;
11839559Smarc 	pg->pg_session->s_leader = NULL;
11939559Smarc 	pg->pg_session->s_ttyvp = NULL;
12039559Smarc 	pg->pg_session->s_ttyp = NULL;
12137611Smckusick #ifdef KTRACE
12237611Smckusick 	p->p_tracep = NULL;
12337611Smckusick 	p->p_traceflag = 0;
12437611Smckusick #endif
12516690Smckusick 	/*
12618278Smckusick 	 * These assume that the u. area is always mapped
12718278Smckusick 	 * to the same virtual address. Otherwise must be
12816690Smckusick 	 * handled when copying the u. area in newproc().
12916690Smckusick 	 */
13038264Smckusick 	ndinit(&u.u_nd);
13129946Skarels 
132*45914Smckusick 	/*
133*45914Smckusick 	 * Create the file descriptor table for process 0.
134*45914Smckusick 	 */
135*45914Smckusick 	fdp = (struct filedesc *)malloc(sizeof(*fdp), M_FILE, M_WAITOK);
136*45914Smckusick 	bzero((char *)fdp, sizeof(struct filedesc));
137*45914Smckusick 	p->p_fd = fdp;
138*45914Smckusick 	fdp->fd_refcnt = 1;
139*45914Smckusick 	fdp->fd_cmask = cmask;
140*45914Smckusick 	fdp->fd_lastfile = -1;
141*45914Smckusick 	fdp->fd_maxfiles = NDFILE;
1428027Sroot 	for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++)
1438027Sroot 		u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max =
1448027Sroot 		    RLIM_INFINITY;
14518278Smckusick 	/*
14623534Skarels 	 * configure virtual memory system,
14723534Skarels 	 * set vm rlimits
14818278Smckusick 	 */
14918278Smckusick 	vminit();
15023534Skarels 
15137610Smckusick 	/*
15239431Smckusick 	 * Initialize the file systems.
15339431Smckusick 	 *
15437610Smckusick 	 * Get vnodes for swapdev, argdev, and rootdev.
15537610Smckusick 	 */
15639431Smckusick 	vfsinit();
15737610Smckusick 	if (bdevvp(swapdev, &swapdev_vp) ||
15837610Smckusick 	    bdevvp(argdev, &argdev_vp) ||
15937610Smckusick 	    bdevvp(rootdev, &rootvp))
16037610Smckusick 		panic("can't setup bdevvp's");
16137610Smckusick 
16237610Smckusick 	/*
16337610Smckusick 	 * Setup credentials
16437610Smckusick 	 */
16537610Smckusick 	u.u_cred = crget();
16641513Smckusick 	u.u_cred->cr_ngroups = 1;
16737610Smckusick 
16830256Ssam 	startrtclock();
16929946Skarels #if defined(vax)
17012823Ssam #include "kg.h"
17112823Ssam #if NKG > 0
17211356Smckusick 	startkgclock();
17311356Smckusick #endif
17429946Skarels #endif
17526Sbill 
17626Sbill 	/*
1774821Swnj 	 * Initialize tables, protocols, and set up well-known inodes.
17826Sbill 	 */
1794821Swnj 	mbinit();
18021103Skarels 	cinit();
18141565Smckusick #ifdef SYSVSHM
18241565Smckusick 	shminit();
18341565Smckusick #endif
18426137Skarels #include "sl.h"
18526137Skarels #if NSL > 0
18626137Skarels 	slattach();			/* XXX */
18726137Skarels #endif
18841565Smckusick #include "loop.h"
1895855Swnj #if NLOOP > 0
1905855Swnj 	loattach();			/* XXX */
1915855Swnj #endif
1929156Ssam 	/*
1939156Ssam 	 * Block reception of incoming packets
1949156Ssam 	 * until protocols have been initialized.
1959156Ssam 	 */
1969156Ssam 	s = splimp();
1975227Swnj 	ifinit();
1988969Sroot 	domaininit();
1999156Ssam 	splx(s);
20016526Skarels 	pqinit();
20130531Skarels 	swapinit();
2027419Sroot #ifdef GPROF
2037419Sroot 	kmstartup();
2047419Sroot #endif
2057189Sroot 
2068096Sroot /* kick off timeout driven events by calling first time */
2078096Sroot 	roundrobin();
2088096Sroot 	schedcpu();
20945880Swilliam 	enablertclock();		/* enable realtime clock interrupts */
2108096Sroot 
2118096Sroot /* set up the root file system */
21237610Smckusick 	if ((*mountroot)())
21337610Smckusick 		panic("cannot mount root");
21437610Smckusick 	/*
21537610Smckusick 	 * Get vnode for '/'.
216*45914Smckusick 	 * Setup rootdir and fdp->fd_cdir to point to it.
21737610Smckusick 	 */
21837610Smckusick 	if (VFS_ROOT(rootfs, &rootdir))
21937610Smckusick 		panic("cannot find root vnode");
220*45914Smckusick 	fdp->fd_cdir = rootdir;
221*45914Smckusick 	VREF(fdp->fd_cdir);
22237726Smckusick 	VOP_UNLOCK(rootdir);
223*45914Smckusick 	fdp->fd_rdir = NULL;
22442303Smarc 	boottime = u.u_start =  time;
22526Sbill 
22626Sbill 	/*
22716807Skarels 	 * make init process
22816807Skarels 	 */
22916807Skarels 
23038927Skarels 	siginit(&proc[0]);
23116807Skarels 	if (newproc(0)) {
23245724Smckusick 		vm_offset_t addr = 0;
23345724Smckusick 
23445724Smckusick 		(void) vm_allocate(u.u_procp->p_map,
23545724Smckusick 				   &addr, round_page(szicode), FALSE);
23645724Smckusick 		if (addr != 0)
23745724Smckusick 			panic("init: couldn't allocate at zero");
23845724Smckusick 
23945724Smckusick 		/* need just enough stack to exec from */
24045724Smckusick 		addr = trunc_page(VM_MAX_ADDRESS - PAGE_SIZE);
24145724Smckusick 		(void) vm_allocate(u.u_procp->p_map, &addr, PAGE_SIZE, FALSE);
24245724Smckusick 		u.u_maxsaddr = (caddr_t)addr;
24316807Skarels 		(void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
24416807Skarels 		/*
24516807Skarels 		 * Return goes to loc. 0 of user init
24616807Skarels 		 * code just copied out.
24716807Skarels 		 */
24816807Skarels 		return;
24916807Skarels 	}
25016807Skarels 	/*
25145724Smckusick 	 * Start up pageout daemon (process 2).
25226Sbill 	 */
25326Sbill 	if (newproc(0)) {
25426Sbill 		proc[2].p_flag |= SLOAD|SSYS;
25540806Smarc 		bcopy("pagedaemon", proc[2].p_comm, sizeof ("pagedaemon"));
25645724Smckusick 		vm_pageout();
2579025Sroot 		/*NOTREACHED*/
25826Sbill 	}
25926Sbill 
26026Sbill 	/*
26126Sbill 	 * enter scheduling loop
26226Sbill 	 */
26326Sbill 	sched();
26426Sbill }
26526Sbill 
26626Sbill /*
2677001Smckusick  * Initialize hash links for buffers.
2687001Smckusick  */
2697001Smckusick bhinit()
2707001Smckusick {
2717001Smckusick 	register int i;
2727001Smckusick 	register struct bufhd *bp;
2737001Smckusick 
2747001Smckusick 	for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++)
2757001Smckusick 		bp->b_forw = bp->b_back = (struct buf *)bp;
2767001Smckusick }
2777001Smckusick 
2787001Smckusick /*
27926Sbill  * Initialize the buffer I/O system by freeing
28026Sbill  * all buffers and setting all device buffer lists to empty.
28126Sbill  */
28226Sbill binit()
28326Sbill {
2848554Sroot 	register struct buf *bp, *dp;
28526Sbill 	register int i;
28610336Smckusick 	int base, residual;
28726Sbill 
2882322Swnj 	for (dp = bfreelist; dp < &bfreelist[BQUEUES]; dp++) {
2892322Swnj 		dp->b_forw = dp->b_back = dp->av_forw = dp->av_back = dp;
2902322Swnj 		dp->b_flags = B_HEAD;
2912322Swnj 	}
29210336Smckusick 	base = bufpages / nbuf;
29310336Smckusick 	residual = bufpages % nbuf;
2946570Smckusic 	for (i = 0; i < nbuf; i++) {
29526Sbill 		bp = &buf[i];
29626Sbill 		bp->b_dev = NODEV;
2979156Ssam 		bp->b_bcount = 0;
29838774Smckusick 		bp->b_rcred = NOCRED;
29938774Smckusick 		bp->b_wcred = NOCRED;
30038774Smckusick 		bp->b_dirtyoff = 0;
30138774Smckusick 		bp->b_dirtyend = 0;
3026570Smckusic 		bp->b_un.b_addr = buffers + i * MAXBSIZE;
30310336Smckusick 		if (i < residual)
30410336Smckusick 			bp->b_bufsize = (base + 1) * CLBYTES;
30510336Smckusick 		else
30610336Smckusick 			bp->b_bufsize = base * CLBYTES;
3079750Ssam 		binshash(bp, &bfreelist[BQ_AGE]);
3082322Swnj 		bp->b_flags = B_BUSY|B_INVAL;
30926Sbill 		brelse(bp);
31026Sbill 	}
31130531Skarels }
31230531Skarels 
31330531Skarels /*
31430531Skarels  * Set up swap devices.
31530531Skarels  * Initialize linked list of free swap
31630531Skarels  * headers. These do not actually point
31730531Skarels  * to buffers, but rather to pages that
31830531Skarels  * are being swapped in and out.
31930531Skarels  */
32030531Skarels swapinit()
32130531Skarels {
32230531Skarels 	register int i;
32330531Skarels 	register struct buf *sp = swbuf;
32430531Skarels 	struct swdevt *swp;
32537611Smckusick 	int error;
32630531Skarels 
327306Sbill 	/*
328306Sbill 	 * Count swap devices, and adjust total swap space available.
32930531Skarels 	 * Some of this space will not be available until a swapon()
330306Sbill 	 * system is issued, usually when the system goes multi-user.
331306Sbill 	 */
332306Sbill 	nswdev = 0;
33312489Ssam 	nswap = 0;
33412489Ssam 	for (swp = swdevt; swp->sw_dev; swp++) {
335306Sbill 		nswdev++;
33612489Ssam 		if (swp->sw_nblks > nswap)
33712489Ssam 			nswap = swp->sw_nblks;
33812489Ssam 	}
339306Sbill 	if (nswdev == 0)
34030531Skarels 		panic("swapinit");
3414132Secc 	if (nswdev > 1)
34212489Ssam 		nswap = ((nswap + dmmax - 1) / dmmax) * dmmax;
343306Sbill 	nswap *= nswdev;
34437610Smckusick 	if (bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp))
34537610Smckusick 		panic("swapvp");
34637611Smckusick 	if (error = swfree(0)) {
34737611Smckusick 		printf("swfree errno %d\n", error);	/* XXX */
34837611Smckusick 		panic("swapinit swfree 0");
34937611Smckusick 	}
35026Sbill 
35130531Skarels 	/*
35230531Skarels 	 * Now set up swap buffer headers.
35330531Skarels 	 */
3542753Swnj 	bswlist.av_forw = sp;
3552769Swnj 	for (i=0; i<nswbuf-1; i++, sp++)
3562753Swnj 		sp->av_forw = sp+1;
3572753Swnj 	sp->av_forw = NULL;
35826Sbill }
3592746Swnj 
3602746Swnj /*
3612746Swnj  * Initialize clist by freeing all character blocks, then count
3622746Swnj  * number of character devices. (Once-only routine)
3632746Swnj  */
3642746Swnj cinit()
3652746Swnj {
3662746Swnj 	register int ccp;
3672746Swnj 	register struct cblock *cp;
3682746Swnj 
3692746Swnj 	ccp = (int)cfree;
3702746Swnj 	ccp = (ccp+CROUND) & ~CROUND;
3712746Swnj 	for(cp=(struct cblock *)ccp; cp < &cfree[nclist-1]; cp++) {
3722746Swnj 		cp->c_next = cfreelist;
3732746Swnj 		cfreelist = cp;
3742746Swnj 		cfreecount += CBSIZE;
3752746Swnj 	}
3762746Swnj }
377