xref: /csrg-svn/sys/kern/init_main.c (revision 55406)
123364Smckusick /*
247543Skarels  * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
347817Skarels  * All rights reserved.
423364Smckusick  *
547817Skarels  * %sccs.include.redist.c%
647817Skarels  *
7*55406Smckusick  *	@(#)init_main.c	7.53 (Berkeley) 07/19/92
823364Smckusick  */
926Sbill 
1017087Sbloom #include "param.h"
1145914Smckusick #include "filedesc.h"
1217087Sbloom #include "kernel.h"
1317087Sbloom #include "mount.h"
1417087Sbloom #include "map.h"
1517087Sbloom #include "proc.h"
1647654Skarels #include "resourcevar.h"
1747654Skarels #include "signalvar.h"
1847654Skarels #include "systm.h"
1937610Smckusick #include "vnode.h"
2017087Sbloom #include "conf.h"
2117087Sbloom #include "buf.h"
2217087Sbloom #include "clist.h"
2317087Sbloom #include "protosw.h"
2430570Skarels #include "reboot.h"
2547654Skarels #include "user.h"
2647654Skarels 
2751453Sbostic #include "ufs/ufs/quota.h"
2826Sbill 
2937522Smckusick #include "machine/cpu.h"
3037522Smckusick 
3147543Skarels #include "vm/vm.h"
3245724Smckusick 
3355399Smckusick #ifdef HPFPLIB
3449382Skarels char	copyright[] =
3555399Smckusick "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n";
3655399Smckusick #else
3755399Smckusick char	copyright[] =
3849382Skarels "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n";
3955399Smckusick #endif
4049382Skarels 
4147543Skarels /*
4247543Skarels  * Components of process 0;
4347543Skarels  * never freed.
4447543Skarels  */
4547543Skarels struct	session session0;
4647543Skarels struct	pgrp pgrp0;
4747543Skarels struct	proc proc0;
4847543Skarels struct	pcred cred0;
4947654Skarels struct	filedesc0 filedesc0;
5047543Skarels struct	plimit limit0;
5147543Skarels struct	vmspace vmspace0;
5247654Skarels struct	proc *curproc = &proc0;
5347543Skarels struct	proc *initproc, *pageproc;
5447543Skarels 
5516807Skarels int	cmask = CMASK;
5648981Skarels extern	struct user *proc0paddr;
5737610Smckusick extern	int (*mountroot)();
5845880Swilliam 
5949382Skarels struct	vnode *rootvp, *swapdev_vp;
6049382Skarels int	boothowto;
6153009Ssklower struct	timeval boottime;
6254781Storek struct	timeval runtime;
6349382Skarels 
6426Sbill /*
6547543Skarels  * System startup; initialize the world, create process 0,
6647543Skarels  * mount root filesystem, and fork to create init and pagedaemon.
6747543Skarels  * Most of the hard work is done in the lower-level initialization
6847543Skarels  * routines including startup(), which does memory initialization
6947543Skarels  * and autoconfiguration.
7026Sbill  */
7149533Skarels main()
7226Sbill {
73361Sbill 	register int i;
742451Swnj 	register struct proc *p;
7547654Skarels 	register struct filedesc0 *fdp;
7647543Skarels 	int s, rval[2];
7754781Storek 	extern void roundrobin __P((void *));
7854781Storek 	extern void schedcpu __P((void *));
7926Sbill 
8045880Swilliam 	/*
8147543Skarels 	 * Initialize curproc before any possible traps/probes
8247543Skarels 	 * to simplify trap processing.
8345880Swilliam 	 */
8447543Skarels 	p = &proc0;
8547543Skarels 	curproc = p;
8645724Smckusick 	/*
8747543Skarels 	 * Attempt to find console and initialize
8847543Skarels 	 * in case of early panic or other messages.
8945724Smckusick 	 */
9047543Skarels 	consinit();
9149382Skarels 	printf(copyright);
9247543Skarels 
9345724Smckusick 	vm_mem_init();
9445724Smckusick 	kmeminit();
9549533Skarels 	cpu_startup();
9626Sbill 
9726Sbill 	/*
9826Sbill 	 * set up system process 0 (swapper)
9926Sbill 	 */
10047543Skarels 	p = &proc0;
10147543Skarels 	curproc = p;
10247543Skarels 
10354781Storek 	allproc = (volatile struct proc *)p;
10454781Storek 	p->p_prev = (struct proc **)&allproc;
10547543Skarels 	p->p_pgrp = &pgrp0;
10647543Skarels 	pgrphash[0] = &pgrp0;
10747543Skarels 	pgrp0.pg_mem = p;
10847543Skarels 	pgrp0.pg_session = &session0;
10947543Skarels 	session0.s_count = 1;
11047543Skarels 	session0.s_leader = p;
11147543Skarels 
11247543Skarels 	p->p_flag = SLOAD|SSYS;
1132451Swnj 	p->p_stat = SRUN;
1142451Swnj 	p->p_nice = NZERO;
11547543Skarels 	bcopy("swapper", p->p_comm, sizeof ("swapper"));
11647543Skarels 
11745724Smckusick 	/*
11847543Skarels 	 * Setup credentials
11945724Smckusick 	 */
12049745Smckusick 	cred0.p_refcnt = 1;
12147543Skarels 	p->p_cred = &cred0;
12247543Skarels 	p->p_ucred = crget();
12347543Skarels 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
12429946Skarels 
12545914Smckusick 	/*
12645914Smckusick 	 * Create the file descriptor table for process 0.
12745914Smckusick 	 */
12847543Skarels 	fdp = &filedesc0;
12947654Skarels 	p->p_fd = &fdp->fd_fd;
13047654Skarels 	fdp->fd_fd.fd_refcnt = 1;
13147654Skarels 	fdp->fd_fd.fd_cmask = cmask;
13247654Skarels 	fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
13347654Skarels 	fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
13447654Skarels 	fdp->fd_fd.fd_nfiles = NDFILE;
13547543Skarels 
13618278Smckusick 	/*
13747543Skarels 	 * Set initial limits
13847543Skarels 	 */
13947543Skarels 	p->p_limit = &limit0;
14047543Skarels 	for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
14147543Skarels 		limit0.pl_rlimit[i].rlim_cur =
14247543Skarels 		    limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
14347543Skarels 	limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE;
14447543Skarels 	limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
14547543Skarels 	limit0.p_refcnt = 1;
14647543Skarels 
14747543Skarels 	/*
14847543Skarels 	 * Allocate a prototype map so we have something to fork
14947543Skarels 	 */
15047543Skarels 	p->p_vmspace = &vmspace0;
15147543Skarels 	vmspace0.vm_refcnt = 1;
15247543Skarels 	pmap_pinit(&vmspace0.vm_pmap);
15347543Skarels 	vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS),
15447543Skarels 	    trunc_page(VM_MAX_ADDRESS), TRUE);
15547543Skarels 	vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
15647543Skarels 	p->p_addr = proc0paddr;				/* XXX */
15747543Skarels 
15847543Skarels 	/*
15947543Skarels 	 * We continue to place resource usage info
16047543Skarels 	 * and signal actions in the user struct so they're pageable.
16147543Skarels 	 */
16248981Skarels 	p->p_stats = &p->p_addr->u_stats;
16348981Skarels 	p->p_sigacts = &p->p_addr->u_sigacts;
16447543Skarels 
165*55406Smckusick 	/*
166*55406Smckusick 	 * Initialize per uid information structure and charge
167*55406Smckusick 	 * root for one process.
168*55406Smckusick 	 */
169*55406Smckusick 	usrinfoinit();
170*55406Smckusick 	(void)chgproccnt(0, 1);
171*55406Smckusick 
17247543Skarels 	rqinit();
17347543Skarels 
17447543Skarels 	/*
17523534Skarels 	 * configure virtual memory system,
17623534Skarels 	 * set vm rlimits
17718278Smckusick 	 */
17847543Skarels 	vm_init_limits(p);
17923534Skarels 
18037610Smckusick 	/*
18139431Smckusick 	 * Initialize the file systems.
18239431Smckusick 	 *
18349382Skarels 	 * Get vnodes for swapdev and rootdev.
18437610Smckusick 	 */
18539431Smckusick 	vfsinit();
18649382Skarels 	if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
18737610Smckusick 		panic("can't setup bdevvp's");
18837610Smckusick 
18954781Storek 	/*
19054781Storek 	 * Start real time and statistics clocks.
19154781Storek 	 */
19254781Storek 	initclocks();
19326Sbill 
19426Sbill 	/*
1954821Swnj 	 * Initialize tables, protocols, and set up well-known inodes.
19626Sbill 	 */
1974821Swnj 	mbinit();
19821103Skarels 	cinit();
19941565Smckusick #ifdef SYSVSHM
20041565Smckusick 	shminit();
20141565Smckusick #endif
20226137Skarels #include "sl.h"
20326137Skarels #if NSL > 0
20426137Skarels 	slattach();			/* XXX */
20526137Skarels #endif
20641565Smckusick #include "loop.h"
2075855Swnj #if NLOOP > 0
2085855Swnj 	loattach();			/* XXX */
2095855Swnj #endif
2109156Ssam 	/*
2119156Ssam 	 * Block reception of incoming packets
2129156Ssam 	 * until protocols have been initialized.
2139156Ssam 	 */
2149156Ssam 	s = splimp();
2155227Swnj 	ifinit();
2168969Sroot 	domaininit();
2179156Ssam 	splx(s);
21847543Skarels 
2197419Sroot #ifdef GPROF
2207419Sroot 	kmstartup();
2217419Sroot #endif
2227189Sroot 
22347543Skarels 	/* kick off timeout driven events by calling first time */
22454781Storek 	roundrobin(NULL);
22554781Storek 	schedcpu(NULL);
2268096Sroot 
22747543Skarels 	/*
22847543Skarels 	 * Set up the root file system and vnode.
22947543Skarels 	 */
23037610Smckusick 	if ((*mountroot)())
23137610Smckusick 		panic("cannot mount root");
23237610Smckusick 	/*
23337610Smckusick 	 * Get vnode for '/'.
23447654Skarels 	 * Setup rootdir and fdp->fd_fd.fd_cdir to point to it.
23537610Smckusick 	 */
23637610Smckusick 	if (VFS_ROOT(rootfs, &rootdir))
23737610Smckusick 		panic("cannot find root vnode");
23847654Skarels 	fdp->fd_fd.fd_cdir = rootdir;
23947654Skarels 	VREF(fdp->fd_fd.fd_cdir);
24037726Smckusick 	VOP_UNLOCK(rootdir);
24147654Skarels 	fdp->fd_fd.fd_rdir = NULL;
24247543Skarels 	swapinit();
24326Sbill 
24426Sbill 	/*
24547543Skarels 	 * Now can look at time, having had a chance
24647543Skarels 	 * to verify the time from the file system.
24747543Skarels 	 */
24854943Storek 	p->p_stats->p_start = runtime = mono_time = boottime = time;
24947543Skarels 
25047543Skarels 	/*
25116807Skarels 	 * make init process
25216807Skarels 	 */
25347543Skarels 	siginit(p);
25452504Sbostic 	if (fork(p, NULL, rval))
25547543Skarels 		panic("fork init");
25647543Skarels 	if (rval[1]) {
25749382Skarels 		extern int icode[];		/* user init code */
25849382Skarels 		extern int szicode;		/* size of icode */
25952504Sbostic 		static char initflags[] = "-sf";
26052504Sbostic 		vm_offset_t addr;
26152504Sbostic 		char *ip;
26245724Smckusick 
26347543Skarels 		/*
26452504Sbostic 		 * Now in process 1.  Set init flags into icode, get a minimal
26552504Sbostic 		 * address space, copy out "icode", and return to it to do an
26652504Sbostic 		 * exec of init.
26747543Skarels 		 */
26852504Sbostic 		ip = initflags + 1;
26947543Skarels 		if (boothowto&RB_SINGLE)
27047543Skarels 			*ip++ = 's';
27147543Skarels #ifdef notyet
27247543Skarels 		if (boothowto&RB_FASTBOOT)
27347543Skarels 			*ip++ = 'f';
27447689Skarels #endif
27552504Sbostic 		if (ip == initflags + 1)
27652504Sbostic 			*ip++ = '-';
27747543Skarels 		*ip++ = '\0';
27847543Skarels 
27952505Storek 		addr = VM_MIN_ADDRESS;
28052504Sbostic 		initproc = p = curproc;
28147543Skarels 		if (vm_allocate(&p->p_vmspace->vm_map, &addr,
28247689Skarels 		    round_page(szicode + sizeof(initflags)), FALSE) != 0 ||
28352505Storek 		    addr != VM_MIN_ADDRESS)
28445724Smckusick 			panic("init: couldn't allocate at zero");
28545724Smckusick 
28645724Smckusick 		/* need just enough stack to exec from */
28748981Skarels 		addr = trunc_page(USRSTACK - PAGE_SIZE);
28847543Skarels 		if (vm_allocate(&p->p_vmspace->vm_map, &addr,
28947543Skarels 		    PAGE_SIZE, FALSE) != KERN_SUCCESS)
29047543Skarels 			panic("vm_allocate init stack");
29147543Skarels 		p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
29252505Storek 		(void)copyout((caddr_t)icode, (caddr_t)VM_MIN_ADDRESS,
29352505Storek 		    (u_int)szicode);
29452505Storek 		(void)copyout(initflags, (caddr_t)(VM_MIN_ADDRESS + szicode),
29552505Storek 		    sizeof(initflags));
29647543Skarels 		return;			/* returns to icode */
29716807Skarels 	}
29847543Skarels 
29916807Skarels 	/*
30045724Smckusick 	 * Start up pageout daemon (process 2).
30126Sbill 	 */
30252504Sbostic 	if (fork(p, NULL, rval))
30347543Skarels 		panic("fork pager");
30447543Skarels 	if (rval[1]) {
30547543Skarels 		/*
30647543Skarels 		 * Now in process 2.
30747543Skarels 		 */
30847543Skarels 		p = curproc;
30947543Skarels 		pageproc = p;
31047543Skarels 		p->p_flag |= SLOAD|SSYS;		/* XXX */
31147543Skarels 		bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
31245724Smckusick 		vm_pageout();
3139025Sroot 		/*NOTREACHED*/
31426Sbill 	}
31526Sbill 
31626Sbill 	/*
31726Sbill 	 * enter scheduling loop
31826Sbill 	 */
31926Sbill 	sched();
32026Sbill }
321