use inb and outb from locore
[unix-history] / usr / src / sys / kern / init_main.c
CommitLineData
da7c5cc6 1/*
1acdbcea
KB
2 * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
3 * The Regents of the University of California. All rights reserved.
da7c5cc6 4 *
2d9d8fa8
MK
5 * %sccs.include.redist.c%
6 *
1acdbcea 7 * @(#)init_main.c 8.1 (Berkeley) %G%
da7c5cc6 8 */
961945a8 9
d89c95b4
KM
10#include <sys/param.h>
11#include <sys/filedesc.h>
12#include <sys/kernel.h>
13#include <sys/mount.h>
14#include <sys/map.h>
15#include <sys/proc.h>
16#include <sys/resourcevar.h>
17#include <sys/signalvar.h>
18#include <sys/systm.h>
19#include <sys/vnode.h>
20#include <sys/conf.h>
21#include <sys/buf.h>
22#include <sys/clist.h>
0d6eb1b7 23#include <sys/device.h>
d89c95b4
KM
24#include <sys/protosw.h>
25#include <sys/reboot.h>
26#include <sys/user.h>
c040c6b1 27
d301d150 28
d89c95b4 29#include <machine/cpu.h>
961945a8 30
d89c95b4 31#include <vm/vm.h>
d7db4999 32
875b0815
KM
33#ifdef HPFPLIB
34char copyright[] =
d8c34843 35"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n";
875b0815 36#else
94d045fa 37char copyright[] =
d8c34843 38"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n";
875b0815 39#endif
94d045fa 40
d7db4999
MK
41/*
42 * Components of process 0;
43 * never freed.
44 */
45struct session session0;
46struct pgrp pgrp0;
47struct proc proc0;
48struct pcred cred0;
c040c6b1 49struct filedesc0 filedesc0;
d7db4999
MK
50struct plimit limit0;
51struct vmspace vmspace0;
c040c6b1 52struct proc *curproc = &proc0;
d7db4999 53struct proc *initproc, *pageproc;
9d4095a1 54
28c7a4c5 55int cmask = CMASK;
f657c741 56extern struct user *proc0paddr;
475798b6 57extern int (*mountroot)();
362786f8 58
94d045fa
MK
59struct vnode *rootvp, *swapdev_vp;
60int boothowto;
31390dba 61struct timeval boottime;
571f7085 62struct timeval runtime;
94d045fa 63
c4708522 64/*
d7db4999
MK
65 * System startup; initialize the world, create process 0,
66 * mount root filesystem, and fork to create init and pagedaemon.
67 * Most of the hard work is done in the lower-level initialization
68 * routines including startup(), which does memory initialization
69 * and autoconfiguration.
c4708522 70 */
27bff27d 71main()
c4708522 72{
73248996 73 register int i;
dd4b582c 74 register struct proc *p;
c040c6b1 75 register struct filedesc0 *fdp;
0d6eb1b7 76 register struct pdevinit *pdev;
d7db4999 77 int s, rval[2];
0d6eb1b7 78 extern struct pdevinit pdevinit[];
571f7085
CT
79 extern void roundrobin __P((void *));
80 extern void schedcpu __P((void *));
083baeb6 81
362786f8 82 /*
d7db4999
MK
83 * Initialize curproc before any possible traps/probes
84 * to simplify trap processing.
362786f8 85 */
d7db4999
MK
86 p = &proc0;
87 curproc = p;
9d4095a1 88 /*
d7db4999
MK
89 * Attempt to find console and initialize
90 * in case of early panic or other messages.
9d4095a1 91 */
d7db4999 92 consinit();
94d045fa 93 printf(copyright);
d7db4999 94
9d4095a1
KM
95 vm_mem_init();
96 kmeminit();
27bff27d 97 cpu_startup();
c4708522
BJ
98
99 /*
100 * set up system process 0 (swapper)
101 */
d7db4999
MK
102 p = &proc0;
103 curproc = p;
104
571f7085
CT
105 allproc = (volatile struct proc *)p;
106 p->p_prev = (struct proc **)&allproc;
d7db4999
MK
107 p->p_pgrp = &pgrp0;
108 pgrphash[0] = &pgrp0;
109 pgrp0.pg_mem = p;
110 pgrp0.pg_session = &session0;
111 session0.s_count = 1;
112 session0.s_leader = p;
113
114 p->p_flag = SLOAD|SSYS;
dd4b582c 115 p->p_stat = SRUN;
dd4b582c 116 p->p_nice = NZERO;
d7db4999
MK
117 bcopy("swapper", p->p_comm, sizeof ("swapper"));
118
9d4095a1 119 /*
d7db4999 120 * Setup credentials
14fda239 121 */
2dd3075b 122 cred0.p_refcnt = 1;
d7db4999
MK
123 p->p_cred = &cred0;
124 p->p_ucred = crget();
125 p->p_ucred->cr_ngroups = 1; /* group 0 */
fb1db32c 126
5e00df3b
KM
127 /*
128 * Create the file descriptor table for process 0.
129 */
d7db4999 130 fdp = &filedesc0;
c040c6b1
MK
131 p->p_fd = &fdp->fd_fd;
132 fdp->fd_fd.fd_refcnt = 1;
133 fdp->fd_fd.fd_cmask = cmask;
134 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
135 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
136 fdp->fd_fd.fd_nfiles = NDFILE;
d7db4999
MK
137
138 /*
139 * Set initial limits
140 */
141 p->p_limit = &limit0;
142 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
143 limit0.pl_rlimit[i].rlim_cur =
144 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
50b95cfe 145 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE;
d7db4999 146 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
6db5115e
KM
147 i = ptoa(cnt.v_free_count);
148 limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i;
149 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
150 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
d7db4999
MK
151 limit0.p_refcnt = 1;
152
153 /*
154 * Allocate a prototype map so we have something to fork
155 */
156 p->p_vmspace = &vmspace0;
157 vmspace0.vm_refcnt = 1;
158 pmap_pinit(&vmspace0.vm_pmap);
159 vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS),
160 trunc_page(VM_MAX_ADDRESS), TRUE);
161 vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
162 p->p_addr = proc0paddr; /* XXX */
163
164 /*
165 * We continue to place resource usage info
166 * and signal actions in the user struct so they're pageable.
167 */
f657c741
MK
168 p->p_stats = &p->p_addr->u_stats;
169 p->p_sigacts = &p->p_addr->u_sigacts;
d7db4999 170
06a043ee
KM
171 /*
172 * Initialize per uid information structure and charge
173 * root for one process.
174 */
175 usrinfoinit();
176 (void)chgproccnt(0, 1);
177
d7db4999
MK
178 rqinit();
179
0d6eb1b7 180 /* Configure virtual memory system, set vm rlimits. */
d7db4999 181 vm_init_limits(p);
8ede3c1b 182
0d6eb1b7 183 /* Initialize the file systems. */
85570e35 184 vfsinit();
475798b6 185
0d6eb1b7 186 /* Start real time and statistics clocks. */
571f7085 187 initclocks();
c4708522 188
0d6eb1b7 189 /* Initialize tables. */
d872f034 190 mbinit();
a5829200 191 cinit();
933220e9
KM
192#ifdef SYSVSHM
193 shminit();
194#endif
0d6eb1b7
CT
195
196 /* Attach pseudo-devices. */
197 for (pdev = pdevinit; pdev->pdev_attach != NULL; pdev++)
198 (*pdev->pdev_attach)(pdev->pdev_count);
199
4f083fd7 200 /*
0d6eb1b7
CT
201 * Initialize protocols. Block reception of incoming packets
202 * until everything is ready.
4f083fd7
SL
203 */
204 s = splimp();
fbf9a431 205 ifinit();
b7892118 206 domaininit();
4f083fd7 207 splx(s);
d7db4999 208
e6254ffb
BJ
209#ifdef GPROF
210 kmstartup();
211#endif
9d6d37ce 212
d7db4999 213 /* kick off timeout driven events by calling first time */
571f7085
CT
214 roundrobin(NULL);
215 schedcpu(NULL);
27b91f59 216
d7db4999
MK
217 /*
218 * Set up the root file system and vnode.
219 */
475798b6
KM
220 if ((*mountroot)())
221 panic("cannot mount root");
222 /*
223 * Get vnode for '/'.
c040c6b1 224 * Setup rootdir and fdp->fd_fd.fd_cdir to point to it.
475798b6
KM
225 */
226 if (VFS_ROOT(rootfs, &rootdir))
227 panic("cannot find root vnode");
c040c6b1
MK
228 fdp->fd_fd.fd_cdir = rootdir;
229 VREF(fdp->fd_fd.fd_cdir);
3ca85ace 230 VOP_UNLOCK(rootdir);
c040c6b1 231 fdp->fd_fd.fd_rdir = NULL;
d7db4999 232 swapinit();
c4708522 233
28c7a4c5 234 /*
38fab586
KM
235 * Now can look at time, having had a chance to verify the time
236 * from the file system. Reset p->p_rtime as it may have been
237 * munched in swtch() after the time got set.
28c7a4c5 238 */
d4f004e2 239 p->p_stats->p_start = runtime = mono_time = boottime = time;
38fab586 240 p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
28c7a4c5 241
d7db4999
MK
242 /*
243 * make init process
244 */
245 siginit(p);
fb06b384 246 if (fork(p, NULL, rval))
d7db4999
MK
247 panic("fork init");
248 if (rval[1]) {
94d045fa
MK
249 extern int icode[]; /* user init code */
250 extern int szicode; /* size of icode */
fb06b384
KB
251 static char initflags[] = "-sf";
252 vm_offset_t addr;
253 char *ip;
9d4095a1 254
d7db4999 255 /*
fb06b384
KB
256 * Now in process 1. Set init flags into icode, get a minimal
257 * address space, copy out "icode", and return to it to do an
258 * exec of init.
d7db4999 259 */
fb06b384 260 ip = initflags + 1;
d7db4999
MK
261 if (boothowto&RB_SINGLE)
262 *ip++ = 's';
263#ifdef notyet
264 if (boothowto&RB_FASTBOOT)
265 *ip++ = 'f';
d7db4999 266#endif
fb06b384
KB
267 if (ip == initflags + 1)
268 *ip++ = '-';
83cf086b 269 *ip++ = '\0';
d7db4999 270
f5c2666f 271 addr = VM_MIN_ADDRESS;
fb06b384 272 initproc = p = curproc;
d7db4999 273 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
83cf086b 274 round_page(szicode + sizeof(initflags)), FALSE) != 0 ||
f5c2666f 275 addr != VM_MIN_ADDRESS)
9d4095a1
KM
276 panic("init: couldn't allocate at zero");
277
278 /* need just enough stack to exec from */
f657c741 279 addr = trunc_page(USRSTACK - PAGE_SIZE);
d7db4999
MK
280 if (vm_allocate(&p->p_vmspace->vm_map, &addr,
281 PAGE_SIZE, FALSE) != KERN_SUCCESS)
282 panic("vm_allocate init stack");
283 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
f5c2666f
CT
284 (void)copyout((caddr_t)icode, (caddr_t)VM_MIN_ADDRESS,
285 (u_int)szicode);
286 (void)copyout(initflags, (caddr_t)(VM_MIN_ADDRESS + szicode),
287 sizeof(initflags));
d7db4999 288 return; /* returns to icode */
28c7a4c5 289 }
d7db4999 290
c4708522 291 /*
9d4095a1 292 * Start up pageout daemon (process 2).
c4708522 293 */
fb06b384 294 if (fork(p, NULL, rval))
d7db4999
MK
295 panic("fork pager");
296 if (rval[1]) {
297 /*
298 * Now in process 2.
299 */
300 p = curproc;
301 pageproc = p;
302 p->p_flag |= SLOAD|SSYS; /* XXX */
303 bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
9d4095a1 304 vm_pageout();
b7892118 305 /*NOTREACHED*/
c4708522
BJ
306 }
307
308 /*
c4708522
BJ
309 * enter scheduling loop
310 */
c4708522
BJ
311 sched();
312}