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