Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
475798b6 | 2 | * Copyright (c) 1982, 1986, 1989 Regents of the University of California. |
be555728 KM |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
da7c5cc6 | 5 | * |
362786f8 | 6 | * @(#)init_main.c 7.31 (Berkeley) %G% |
da7c5cc6 | 7 | */ |
961945a8 | 8 | |
94368568 JB |
9 | #include "param.h" |
10 | #include "systm.h" | |
94368568 JB |
11 | #include "user.h" |
12 | #include "kernel.h" | |
94368568 JB |
13 | #include "mount.h" |
14 | #include "map.h" | |
15 | #include "proc.h" | |
475798b6 | 16 | #include "vnode.h" |
94368568 JB |
17 | #include "seg.h" |
18 | #include "conf.h" | |
19 | #include "buf.h" | |
94368568 | 20 | #include "clist.h" |
8fe87cbb | 21 | #include "malloc.h" |
94368568 | 22 | #include "protosw.h" |
f378da4c | 23 | #include "reboot.h" |
d301d150 | 24 | |
d301d150 KM |
25 | #include "machine/reg.h" |
26 | #include "machine/cpu.h" | |
961945a8 | 27 | |
9d4095a1 KM |
28 | #include "../vm/vm_param.h" |
29 | #include "../vm/vm_map.h" | |
30 | ||
28c7a4c5 | 31 | int cmask = CMASK; |
9d4095a1 | 32 | extern caddr_t proc0paddr; |
475798b6 | 33 | extern int (*mountroot)(); |
362786f8 WN |
34 | #if defined(i386) |
35 | extern char initflags[]; | |
36 | #endif | |
37 | ||
c4708522 BJ |
38 | /* |
39 | * Initialization code. | |
40 | * Called from cold start routine as | |
41 | * soon as a stack and segmentation | |
42 | * have been established. | |
43 | * Functions: | |
44 | * clear and free user core | |
45 | * turn on clock | |
46 | * hand craft 0th process | |
47 | * call all initialization routines | |
48 | * fork - process 0 to schedule | |
c4708522 | 49 | * - process 1 execute bootstrap |
a5829200 | 50 | * - process 2 to page out |
c4708522 BJ |
51 | */ |
52 | main(firstaddr) | |
b7892118 | 53 | int firstaddr; |
c4708522 | 54 | { |
73248996 | 55 | register int i; |
dd4b582c | 56 | register struct proc *p; |
8fe87cbb | 57 | register struct pgrp *pg; |
4f083fd7 | 58 | int s; |
c4708522 | 59 | |
c4708522 | 60 | rqinit(); |
362786f8 WN |
61 | #if defined(i386) |
62 | /* | |
63 | * set boot flags | |
64 | */ | |
65 | if (boothowto&RB_SINGLE) | |
66 | bcopy("-s", initflags, 3); | |
67 | else | |
68 | if (boothowto&RB_ASKNAME) | |
69 | bcopy("-a", initflags, 3); | |
70 | else | |
71 | bcopy("-", initflags, 2); | |
72 | #endif | |
9d4095a1 KM |
73 | #if defined(hp300) && defined(DEBUG) |
74 | /* | |
75 | * Assumes mapping is really on | |
76 | */ | |
77 | find_devs(); | |
78 | cninit(); | |
79 | #endif | |
80 | vm_mem_init(); | |
81 | kmeminit(); | |
c4708522 | 82 | startup(firstaddr); |
c4708522 BJ |
83 | |
84 | /* | |
85 | * set up system process 0 (swapper) | |
86 | */ | |
dd4b582c | 87 | p = &proc[0]; |
25d213eb | 88 | bcopy("swapper", p->p_comm, sizeof ("swapper")); |
dd4b582c BJ |
89 | p->p_stat = SRUN; |
90 | p->p_flag |= SLOAD|SSYS; | |
91 | p->p_nice = NZERO; | |
9d4095a1 KM |
92 | /* |
93 | * Allocate a prototype map so we have something to fork | |
94 | */ | |
95 | p->p_map = vm_map_create(pmap_create(0), | |
96 | round_page(VM_MIN_ADDRESS), | |
97 | trunc_page(VM_MAX_ADDRESS), TRUE); | |
98 | p->p_addr = proc0paddr; | |
dd4b582c | 99 | u.u_procp = p; |
8fe87cbb MT |
100 | MALLOC(pgrphash[0], struct pgrp *, sizeof (struct pgrp), |
101 | M_PGRP, M_NOWAIT); | |
102 | if ((pg = pgrphash[0]) == NULL) | |
103 | panic("no space to craft zero'th process group"); | |
104 | pg->pg_id = 0; | |
105 | pg->pg_hforw = 0; | |
106 | pg->pg_mem = p; | |
107 | pg->pg_jobc = 0; | |
108 | p->p_pgrp = pg; | |
109 | p->p_pgrpnxt = 0; | |
110 | MALLOC(pg->pg_session, struct session *, sizeof (struct session), | |
111 | M_SESSION, M_NOWAIT); | |
112 | if (pg->pg_session == NULL) | |
113 | panic("no space to craft zero'th session"); | |
114 | pg->pg_session->s_count = 1; | |
ca7a8dcb MT |
115 | pg->pg_session->s_leader = NULL; |
116 | pg->pg_session->s_ttyvp = NULL; | |
117 | pg->pg_session->s_ttyp = NULL; | |
27ef8b9b MT |
118 | #ifdef KTRACE |
119 | p->p_tracep = NULL; | |
120 | p->p_traceflag = 0; | |
121 | #endif | |
14fda239 | 122 | /* |
4898b838 KM |
123 | * These assume that the u. area is always mapped |
124 | * to the same virtual address. Otherwise must be | |
14fda239 KM |
125 | * handled when copying the u. area in newproc(). |
126 | */ | |
dc456b6b | 127 | ndinit(&u.u_nd); |
fb1db32c | 128 | |
28c7a4c5 | 129 | u.u_cmask = cmask; |
a5829200 | 130 | u.u_lastfile = -1; |
d3003a84 BJ |
131 | for (i = 0; i < sizeof(u.u_rlimit)/sizeof(u.u_rlimit[0]); i++) |
132 | u.u_rlimit[i].rlim_cur = u.u_rlimit[i].rlim_max = | |
133 | RLIM_INFINITY; | |
4898b838 | 134 | /* |
8ede3c1b MK |
135 | * configure virtual memory system, |
136 | * set vm rlimits | |
4898b838 KM |
137 | */ |
138 | vminit(); | |
8ede3c1b | 139 | |
475798b6 | 140 | /* |
85570e35 KM |
141 | * Initialize the file systems. |
142 | * | |
475798b6 KM |
143 | * Get vnodes for swapdev, argdev, and rootdev. |
144 | */ | |
85570e35 | 145 | vfsinit(); |
475798b6 KM |
146 | if (bdevvp(swapdev, &swapdev_vp) || |
147 | bdevvp(argdev, &argdev_vp) || | |
148 | bdevvp(rootdev, &rootvp)) | |
149 | panic("can't setup bdevvp's"); | |
150 | ||
151 | /* | |
152 | * Setup credentials | |
153 | */ | |
154 | u.u_cred = crget(); | |
d106268b | 155 | u.u_cred->cr_ngroups = 1; |
475798b6 | 156 | |
c70d0a8b | 157 | startrtclock(); |
5cb75b5d | 158 | #if defined(vax) |
f882447b SL |
159 | #include "kg.h" |
160 | #if NKG > 0 | |
d0ab60b1 | 161 | startkgclock(); |
fb1db32c | 162 | #endif |
d0ab60b1 | 163 | #endif |
c4708522 BJ |
164 | |
165 | /* | |
d872f034 | 166 | * Initialize tables, protocols, and set up well-known inodes. |
c4708522 | 167 | */ |
d872f034 | 168 | mbinit(); |
a5829200 | 169 | cinit(); |
933220e9 KM |
170 | #ifdef SYSVSHM |
171 | shminit(); | |
172 | #endif | |
730ff8ce MK |
173 | #include "sl.h" |
174 | #if NSL > 0 | |
175 | slattach(); /* XXX */ | |
176 | #endif | |
933220e9 | 177 | #include "loop.h" |
4f4caf05 BJ |
178 | #if NLOOP > 0 |
179 | loattach(); /* XXX */ | |
180 | #endif | |
4f083fd7 SL |
181 | /* |
182 | * Block reception of incoming packets | |
183 | * until protocols have been initialized. | |
184 | */ | |
185 | s = splimp(); | |
fbf9a431 | 186 | ifinit(); |
b7892118 | 187 | domaininit(); |
4f083fd7 | 188 | splx(s); |
1d348849 | 189 | pqinit(); |
fa1a0164 | 190 | swapinit(); |
e6254ffb BJ |
191 | #ifdef GPROF |
192 | kmstartup(); | |
193 | #endif | |
9d6d37ce | 194 | |
27b91f59 BJ |
195 | /* kick off timeout driven events by calling first time */ |
196 | roundrobin(); | |
197 | schedcpu(); | |
362786f8 | 198 | enablertclock(); /* enable realtime clock interrupts */ |
27b91f59 BJ |
199 | |
200 | /* set up the root file system */ | |
475798b6 KM |
201 | if ((*mountroot)()) |
202 | panic("cannot mount root"); | |
203 | /* | |
204 | * Get vnode for '/'. | |
205 | * Setup rootdir and u.u_cdir to point to it. | |
206 | */ | |
207 | if (VFS_ROOT(rootfs, &rootdir)) | |
208 | panic("cannot find root vnode"); | |
209 | u.u_cdir = rootdir; | |
8fe1c702 | 210 | VREF(u.u_cdir); |
3ca85ace | 211 | VOP_UNLOCK(rootdir); |
c4708522 | 212 | u.u_rdir = NULL; |
5ce8782f | 213 | boottime = u.u_start = time; |
c4708522 | 214 | |
28c7a4c5 MK |
215 | /* |
216 | * make init process | |
217 | */ | |
218 | ||
6d21bbfc | 219 | siginit(&proc[0]); |
28c7a4c5 | 220 | if (newproc(0)) { |
9d4095a1 KM |
221 | vm_offset_t addr = 0; |
222 | ||
223 | (void) vm_allocate(u.u_procp->p_map, | |
224 | &addr, round_page(szicode), FALSE); | |
225 | if (addr != 0) | |
226 | panic("init: couldn't allocate at zero"); | |
227 | ||
228 | /* need just enough stack to exec from */ | |
229 | addr = trunc_page(VM_MAX_ADDRESS - PAGE_SIZE); | |
230 | (void) vm_allocate(u.u_procp->p_map, &addr, PAGE_SIZE, FALSE); | |
231 | u.u_maxsaddr = (caddr_t)addr; | |
28c7a4c5 MK |
232 | (void) copyout((caddr_t)icode, (caddr_t)0, (unsigned)szicode); |
233 | /* | |
234 | * Return goes to loc. 0 of user init | |
235 | * code just copied out. | |
236 | */ | |
237 | return; | |
238 | } | |
c4708522 | 239 | /* |
9d4095a1 | 240 | * Start up pageout daemon (process 2). |
c4708522 | 241 | */ |
c4708522 BJ |
242 | if (newproc(0)) { |
243 | proc[2].p_flag |= SLOAD|SSYS; | |
25d213eb | 244 | bcopy("pagedaemon", proc[2].p_comm, sizeof ("pagedaemon")); |
9d4095a1 | 245 | vm_pageout(); |
b7892118 | 246 | /*NOTREACHED*/ |
c4708522 BJ |
247 | } |
248 | ||
249 | /* | |
c4708522 BJ |
250 | * enter scheduling loop |
251 | */ | |
c4708522 BJ |
252 | sched(); |
253 | } | |
254 | ||
94d38c1e KM |
255 | /* |
256 | * Initialize hash links for buffers. | |
257 | */ | |
258 | bhinit() | |
259 | { | |
260 | register int i; | |
261 | register struct bufhd *bp; | |
262 | ||
263 | for (bp = bufhash, i = 0; i < BUFHSZ; i++, bp++) | |
264 | bp->b_forw = bp->b_back = (struct buf *)bp; | |
c4708522 BJ |
265 | } |
266 | ||
c4708522 BJ |
267 | /* |
268 | * Initialize the buffer I/O system by freeing | |
269 | * all buffers and setting all device buffer lists to empty. | |
c4708522 BJ |
270 | */ |
271 | binit() | |
272 | { | |
21c39d9c | 273 | register struct buf *bp, *dp; |
c4708522 | 274 | register int i; |
af371633 | 275 | int base, residual; |
c4708522 | 276 | |
63e97a1d BJ |
277 | for (dp = bfreelist; dp < &bfreelist[BQUEUES]; dp++) { |
278 | dp->b_forw = dp->b_back = dp->av_forw = dp->av_back = dp; | |
279 | dp->b_flags = B_HEAD; | |
280 | } | |
af371633 KM |
281 | base = bufpages / nbuf; |
282 | residual = bufpages % nbuf; | |
6459ebe0 | 283 | for (i = 0; i < nbuf; i++) { |
c4708522 BJ |
284 | bp = &buf[i]; |
285 | bp->b_dev = NODEV; | |
4f083fd7 | 286 | bp->b_bcount = 0; |
29561cd7 KM |
287 | bp->b_rcred = NOCRED; |
288 | bp->b_wcred = NOCRED; | |
289 | bp->b_dirtyoff = 0; | |
290 | bp->b_dirtyend = 0; | |
6459ebe0 | 291 | bp->b_un.b_addr = buffers + i * MAXBSIZE; |
af371633 KM |
292 | if (i < residual) |
293 | bp->b_bufsize = (base + 1) * CLBYTES; | |
294 | else | |
295 | bp->b_bufsize = base * CLBYTES; | |
961945a8 | 296 | binshash(bp, &bfreelist[BQ_AGE]); |
63e97a1d | 297 | bp->b_flags = B_BUSY|B_INVAL; |
c4708522 BJ |
298 | brelse(bp); |
299 | } | |
fa1a0164 MK |
300 | } |
301 | ||
302 | /* | |
303 | * Set up swap devices. | |
304 | * Initialize linked list of free swap | |
305 | * headers. These do not actually point | |
306 | * to buffers, but rather to pages that | |
307 | * are being swapped in and out. | |
308 | */ | |
309 | swapinit() | |
310 | { | |
311 | register int i; | |
312 | register struct buf *sp = swbuf; | |
313 | struct swdevt *swp; | |
3f36033f | 314 | int error; |
fa1a0164 | 315 | |
41888f16 BJ |
316 | /* |
317 | * Count swap devices, and adjust total swap space available. | |
fa1a0164 | 318 | * Some of this space will not be available until a swapon() |
41888f16 BJ |
319 | * system is issued, usually when the system goes multi-user. |
320 | */ | |
321 | nswdev = 0; | |
d668d9ba SL |
322 | nswap = 0; |
323 | for (swp = swdevt; swp->sw_dev; swp++) { | |
41888f16 | 324 | nswdev++; |
d668d9ba SL |
325 | if (swp->sw_nblks > nswap) |
326 | nswap = swp->sw_nblks; | |
327 | } | |
41888f16 | 328 | if (nswdev == 0) |
fa1a0164 | 329 | panic("swapinit"); |
b2fdd14d | 330 | if (nswdev > 1) |
d668d9ba | 331 | nswap = ((nswap + dmmax - 1) / dmmax) * dmmax; |
41888f16 | 332 | nswap *= nswdev; |
475798b6 KM |
333 | if (bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp)) |
334 | panic("swapvp"); | |
3f36033f MK |
335 | if (error = swfree(0)) { |
336 | printf("swfree errno %d\n", error); /* XXX */ | |
337 | panic("swapinit swfree 0"); | |
338 | } | |
c4708522 | 339 | |
fa1a0164 MK |
340 | /* |
341 | * Now set up swap buffer headers. | |
342 | */ | |
c34926db | 343 | bswlist.av_forw = sp; |
0a34b6fd | 344 | for (i=0; i<nswbuf-1; i++, sp++) |
c34926db BJ |
345 | sp->av_forw = sp+1; |
346 | sp->av_forw = NULL; | |
c4708522 | 347 | } |
e7c7d88e BJ |
348 | |
349 | /* | |
350 | * Initialize clist by freeing all character blocks, then count | |
351 | * number of character devices. (Once-only routine) | |
352 | */ | |
353 | cinit() | |
354 | { | |
355 | register int ccp; | |
356 | register struct cblock *cp; | |
e7c7d88e BJ |
357 | |
358 | ccp = (int)cfree; | |
359 | ccp = (ccp+CROUND) & ~CROUND; | |
360 | for(cp=(struct cblock *)ccp; cp < &cfree[nclist-1]; cp++) { | |
361 | cp->c_next = cfreelist; | |
362 | cfreelist = cp; | |
363 | cfreecount += CBSIZE; | |
364 | } | |
e7c7d88e | 365 | } |