|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
1.1.1.4 ! root 33: * from: @(#)init_main.c 7.41 (Berkeley) 5/15/91
! 34: * init_main.c,v 1.19.2.5 1993/07/22 10:10:51 mycroft Exp
1.1 root 35: */
36:
37: #include "param.h"
38: #include "filedesc.h"
39: #include "kernel.h"
40: #include "mount.h"
41: #include "proc.h"
42: #include "resourcevar.h"
43: #include "signalvar.h"
44: #include "systm.h"
45: #include "vnode.h"
46: #include "conf.h"
47: #include "buf.h"
48: #include "malloc.h"
49: #include "protosw.h"
50: #include "reboot.h"
51: #include "user.h"
1.1.1.4 ! root 52: #include "utsname.h"
1.1 root 53:
54: #include "ufs/quota.h"
55:
56: #include "machine/cpu.h"
57:
58: #include "vm/vm.h"
59:
1.1.1.4 ! root 60: char copyright[] =
! 61: "Copyright (c) 1982,1986,1989,1991 The Regents of the University of California.\nAll rights reserved.\n\n";
1.1 root 62:
63: /*
64: * Components of process 0;
65: * never freed.
66: */
67: struct session session0;
68: struct pgrp pgrp0;
69: struct proc proc0;
70: struct pcred cred0;
71: struct filedesc0 filedesc0;
72: struct plimit limit0;
73: struct vmspace vmspace0;
74: struct proc *curproc = &proc0;
75: struct proc *initproc, *pageproc;
76:
77: int cmask = CMASK;
78: extern struct user *proc0paddr;
79: extern int (*mountroot)();
1.1.1.4 ! root 80: extern int cpu;
1.1 root 81:
82: struct vnode *rootvp, *swapdev_vp;
83: int boothowto;
84:
1.1.1.4 ! root 85: #if __GNUC__ >= 2
! 86: __main() {}
! 87: #endif
! 88:
1.1 root 89: /*
90: * System startup; initialize the world, create process 0,
91: * mount root filesystem, and fork to create init and pagedaemon.
92: * Most of the hard work is done in the lower-level initialization
93: * routines including startup(), which does memory initialization
94: * and autoconfiguration.
95: */
96: main()
97: {
98: register int i;
99: register struct proc *p;
100: register struct filedesc0 *fdp;
101: int s, rval[2];
1.1.1.4 ! root 102: char *cp;
1.1 root 103:
104: /*
105: * Initialize curproc before any possible traps/probes
106: * to simplify trap processing.
107: */
108: p = &proc0;
109: curproc = p;
110: /*
111: * Attempt to find console and initialize
112: * in case of early panic or other messages.
113: */
1.1.1.4 ! root 114: startrtclock(); /* XXX -- arguably should go where noted below */
1.1 root 115: consinit();
1.1.1.4 ! root 116: printf(copyright);
1.1 root 117:
118: vm_mem_init();
119: kmeminit();
120: cpu_startup();
121:
122: /*
123: * set up system process 0 (swapper)
124: */
125: p = &proc0;
126: curproc = p;
127:
128: allproc = p;
129: p->p_prev = &allproc;
130: p->p_pgrp = &pgrp0;
131: pgrphash[0] = &pgrp0;
132: pgrp0.pg_mem = p;
133: pgrp0.pg_session = &session0;
134: session0.s_count = 1;
135: session0.s_leader = p;
136:
137: p->p_flag = SLOAD|SSYS;
138: p->p_stat = SRUN;
139: p->p_nice = NZERO;
140: bcopy("swapper", p->p_comm, sizeof ("swapper"));
141:
142: /*
143: * Setup credentials
144: */
145: cred0.p_refcnt = 1;
146: p->p_cred = &cred0;
147: p->p_ucred = crget();
148: p->p_ucred->cr_ngroups = 1; /* group 0 */
149:
150: /*
151: * Create the file descriptor table for process 0.
152: */
153: fdp = &filedesc0;
154: p->p_fd = &fdp->fd_fd;
155: fdp->fd_fd.fd_refcnt = 1;
156: fdp->fd_fd.fd_cmask = cmask;
157: fdp->fd_fd.fd_ofiles = fdp->fd_dfiles;
158: fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags;
159: fdp->fd_fd.fd_nfiles = NDFILE;
160:
161: /*
162: * Set initial limits
163: */
164: p->p_limit = &limit0;
165: for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
166: limit0.pl_rlimit[i].rlim_cur =
167: limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY;
168: limit0.pl_rlimit[RLIMIT_OFILE].rlim_cur = NOFILE;
169: limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC;
170: limit0.p_refcnt = 1;
171:
172: /*
173: * Allocate a prototype map so we have something to fork
174: */
175: p->p_vmspace = &vmspace0;
176: vmspace0.vm_refcnt = 1;
177: pmap_pinit(&vmspace0.vm_pmap);
178: vm_map_init(&p->p_vmspace->vm_map, round_page(VM_MIN_ADDRESS),
179: trunc_page(VM_MAX_ADDRESS), TRUE);
180: vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
181: p->p_addr = proc0paddr; /* XXX */
182:
183: /*
184: * We continue to place resource usage info
185: * and signal actions in the user struct so they're pageable.
186: */
187: p->p_stats = &p->p_addr->u_stats;
188: p->p_sigacts = &p->p_addr->u_sigacts;
189:
190: rqinit();
191:
192: /*
193: * configure virtual memory system,
194: * set vm rlimits
195: */
196: vm_init_limits(p);
197:
198: /*
199: * Initialize the file systems.
200: *
201: * Get vnodes for swapdev and rootdev.
202: */
203: vfsinit();
204: if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
205: panic("can't setup bdevvp's");
206:
1.1.1.4 ! root 207: /* XXX -- startrtclock(); was here in net/2 */
1.1 root 208: #if defined(vax)
209: #include "kg.h"
210: #if NKG > 0
211: startkgclock();
212: #endif
213: #endif
214:
215: /*
216: * Initialize tables, protocols, and set up well-known inodes.
217: */
218: mbinit();
219: #ifdef SYSVSHM
220: shminit();
221: #endif
222: #include "sl.h"
223: #if NSL > 0
224: slattach(); /* XXX */
225: #endif
226: #include "loop.h"
227: #if NLOOP > 0
228: loattach(); /* XXX */
229: #endif
230: /*
231: * Block reception of incoming packets
232: * until protocols have been initialized.
233: */
234: s = splimp();
235: ifinit();
236: domaininit();
237: splx(s);
238:
239: #ifdef GPROF
240: kmstartup();
241: #endif
242:
243: /* kick off timeout driven events by calling first time */
1.1.1.4 ! root 244: roundrobin((caddr_t)0);
! 245: schedcpu((caddr_t)0);
1.1 root 246: enablertclock(); /* enable realtime clock interrupts */
247:
248: /*
249: * Set up the root file system and vnode.
250: */
251: if ((*mountroot)())
252: panic("cannot mount root");
253: /*
254: * Get vnode for '/'.
255: * Setup rootdir and fdp->fd_fd.fd_cdir to point to it.
256: */
257: if (VFS_ROOT(rootfs, &rootdir))
258: panic("cannot find root vnode");
259: fdp->fd_fd.fd_cdir = rootdir;
260: VREF(fdp->fd_fd.fd_cdir);
261: VOP_UNLOCK(rootdir);
262: fdp->fd_fd.fd_rdir = NULL;
263: swapinit();
264:
265: /*
266: * Now can look at time, having had a chance
267: * to verify the time from the file system.
268: */
269: boottime = p->p_stats->p_start = time;
270:
271: /*
1.1.1.4 ! root 272: * Setup version number for uname syscall
! 273: * XXX probably should go elsewhere.
! 274: */
! 275: bzero(utsname.sysname, sizeof(utsname.sysname));
! 276: for (cp = version, i= 0;
! 277: *cp && *cp != ' ' && i <= sizeof(utsname.sysname);
! 278: )
! 279: utsname.sysname[i++] = *cp++;
! 280: bzero(utsname.release, sizeof(utsname.release));
! 281: for (cp++, i= 0; *cp && *cp != ' ' && i <= sizeof(utsname.release);)
! 282: utsname.release[i++] = *cp++;
! 283: bzero(utsname.version, sizeof(utsname.version));
! 284: for (; *cp != '('; cp++);
! 285: for (cp++, i= 0; *cp && *cp != ')' && i <= sizeof(utsname.version);)
! 286: utsname.version[i++] = *cp++;
! 287: for (; *cp != '#'; cp++);
! 288: if(i <= sizeof(utsname.version))
! 289: utsname.version[i++] = '#';
! 290: for (cp++; *cp && *cp != ':' && i <= sizeof(utsname.version);)
! 291: utsname.version[i++] = *cp++;
! 292: strncpy(utsname.machine, MACHINE, sizeof(utsname.machine));
! 293: utsname.machine[sizeof(utsname.machine)-1] = '\0';
! 294:
! 295: /*
1.1 root 296: * make init process
297: */
298: siginit(p);
299: if (fork(p, (void *) NULL, rval))
300: panic("fork init");
301: if (rval[1]) {
302: static char initflags[] = "-sf";
303: char *ip = initflags + 1;
304: vm_offset_t addr = 0;
305: extern int icode[]; /* user init code */
306: extern int szicode; /* size of icode */
307:
308: /*
309: * Now in process 1. Set init flags into icode,
310: * get a minimal address space, copy out "icode",
311: * and return to it to do an exec of init.
312: */
313: p = curproc;
314: initproc = p;
315: if (boothowto&RB_SINGLE)
316: *ip++ = 's';
317: #ifdef notyet
318: if (boothowto&RB_FASTBOOT)
319: *ip++ = 'f';
320: #endif
1.1.1.4 ! root 321: if (ip == initflags + 1)
! 322: *ip++ = '-';
1.1 root 323: *ip++ = '\0';
324:
325: if (vm_allocate(&p->p_vmspace->vm_map, &addr,
326: round_page(szicode + sizeof(initflags)), FALSE) != 0 ||
327: addr != 0)
328: panic("init: couldn't allocate at zero");
329:
330: /* need just enough stack to exec from */
1.1.1.3 root 331: addr = trunc_page(USRSTACK - MAXSSIZ);
1.1 root 332: if (vm_allocate(&p->p_vmspace->vm_map, &addr,
1.1.1.3 root 333: MAXSSIZ, FALSE) != KERN_SUCCESS)
1.1 root 334: panic("vm_allocate init stack");
335: p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
1.1.1.3 root 336: p->p_vmspace->vm_ssize = 1;
1.1 root 337: (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode);
338: (void) copyout(initflags, (caddr_t)szicode, sizeof(initflags));
339: return; /* returns to icode */
340: }
341:
342: /*
343: * Start up pageout daemon (process 2).
344: */
345: if (fork(p, (void *) NULL, rval))
346: panic("fork pager");
347: if (rval[1]) {
348: /*
349: * Now in process 2.
350: */
351: p = curproc;
352: pageproc = p;
353: p->p_flag |= SLOAD|SSYS; /* XXX */
354: bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
355: vm_pageout();
356: /*NOTREACHED*/
357: }
358:
359: /*
360: * enter scheduling loop
361: */
362: sched();
363: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.