describe ap (Kirk); delete lfs_mntinvalbuf, lfs_vinvalbuf, add
[unix-history] / usr / src / sys / kern / init_main.c
... / ...
CommitLineData
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.49 (Berkeley) %G%
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 "conf.h"
21#include "buf.h"
22#include "clist.h"
23#include "malloc.h"
24#include "protosw.h"
25#include "reboot.h"
26#include "user.h"
27
28
29#include "machine/cpu.h"
30
31#include "vm/vm.h"
32
33char copyright[] =
34"Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n";
35
36/*
37 * Components of process 0;
38 * never freed.
39 */
40struct session session0;
41struct pgrp pgrp0;
42struct proc proc0;
43struct pcred cred0;
44struct filedesc0 filedesc0;
45struct plimit limit0;
46struct vmspace vmspace0;
47struct proc *curproc = &proc0;
48struct proc *initproc, *pageproc;
49
50int cmask = CMASK;
51extern struct user *proc0paddr;
52extern int (*mountroot)();
53
54struct vnode *rootvp, *swapdev_vp;
55int boothowto;
56struct timeval boottime;
57
58/*
59 * System startup; initialize the world, create process 0,
60 * mount root filesystem, and fork to create init and pagedaemon.
61 * Most of the hard work is done in the lower-level initialization
62 * routines including startup(), which does memory initialization
63 * and autoconfiguration.
64 */
65main()
66{
67 register int i;
68 register struct proc *p;
69 register struct filedesc0 *fdp;
70 int s, rval[2];
71
72 /*
73 * Initialize curproc before any possible traps/probes
74 * to simplify trap processing.
75 */
76 p = &proc0;
77 curproc = p;
78 /*
79 * Attempt to find console and initialize
80 * in case of early panic or other messages.
81 */
82 consinit();
83 printf(copyright);
84
85 vm_mem_init();
86 kmeminit();
87 cpu_startup();
88
89 /*
90 * set up system process 0 (swapper)
91 */
92 p = &proc0;
93 curproc = p;
94
95 allproc = p;
96 p->p_prev = &allproc;
97 p->p_pgrp = &pgrp0;
98 pgrphash[0] = &pgrp0;
99 pgrp0.pg_mem = p;
100 pgrp0.pg_session = &session0;
101 session0.s_count = 1;
102 session0.s_leader = p;
103
104 p->p_flag = SLOAD|SSYS;
105 p->p_stat = SRUN;
106 p->p_nice = NZERO;
107 bcopy("swapper", p->p_comm, sizeof ("swapper"));
108
109 /*
110 * Setup credentials
111 */
112 cred0.p_refcnt = 1;
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 mono_time = boottime = p->p_stats->p_start = time;
238
239 /*
240 * make init process
241 */
242 siginit(p);
243 if (fork(p, NULL, rval))
244 panic("fork init");
245 if (rval[1]) {
246 extern int icode[]; /* user init code */
247 extern int szicode; /* size of icode */
248 static char initflags[] = "-sf";
249 vm_offset_t addr;
250 char *ip;
251
252 /*
253 * Now in process 1. Set init flags into icode, get a minimal
254 * address space, copy out "icode", and return to it to do an
255 * exec of init.
256 */
257 ip = initflags + 1;
258 if (boothowto&RB_SINGLE)
259 *ip++ = 's';
260#ifdef notyet
261 if (boothowto&RB_FASTBOOT)
262 *ip++ = 'f';
263#endif
264 if (ip == initflags + 1)
265 *ip++ = '-';
266 *ip++ = '\0';
267
268 addr = VM_MIN_ADDRESS;
269 initproc = p = curproc;
270 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
271 round_page(szicode + sizeof(initflags)), FALSE) != 0 ||
272 addr != VM_MIN_ADDRESS)
273 panic("init: couldn't allocate at zero");
274
275 /* need just enough stack to exec from */
276 addr = trunc_page(USRSTACK - PAGE_SIZE);
277 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
278 PAGE_SIZE, FALSE) != KERN_SUCCESS)
279 panic("vm_allocate init stack");
280 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
281 (void)copyout((caddr_t)icode, (caddr_t)VM_MIN_ADDRESS,
282 (u_int)szicode);
283 (void)copyout(initflags, (caddr_t)(VM_MIN_ADDRESS + szicode),
284 sizeof(initflags));
285 return; /* returns to icode */
286 }
287
288 /*
289 * Start up pageout daemon (process 2).
290 */
291 if (fork(p, NULL, rval))
292 panic("fork pager");
293 if (rval[1]) {
294 /*
295 * Now in process 2.
296 */
297 p = curproc;
298 pageproc = p;
299 p->p_flag |= SLOAD|SSYS; /* XXX */
300 bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
301 vm_pageout();
302 /*NOTREACHED*/
303 }
304
305 /*
306 * enter scheduling loop
307 */
308 sched();
309}