Deleted Added
full compact
init_main.c (10027) init_main.c (10358)
1/*
1/*
2 * Copyright (c) 1995 Terrence R. Lambert
3 * All rights reserved.
4 *
2 * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *

--- 57 unchanged lines hidden (view full) ---

67
68#include <ufs/ufs/quota.h>
69
70#include <machine/cpu.h>
71
72#include <vm/vm.h>
73#include <vm/vm_pageout.h>
74
5 * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 * (c) UNIX System Laboratories, Inc.
8 * All or some portions of this file are derived from material licensed
9 * to the University of California by American Telephone and Telegraph
10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11 * the permission of UNIX System Laboratories, Inc.
12 *

--- 57 unchanged lines hidden (view full) ---

70
71#include <ufs/ufs/quota.h>
72
73#include <machine/cpu.h>
74
75#include <vm/vm.h>
76#include <vm/vm_pageout.h>
77
75#ifdef HPFPLIB
76char copyright[] =
77"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";
78#else
79char copyright[] =
80"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n";
81#endif
82
83/* Components of the first process -- never freed. */
84struct session session0;
85struct pgrp pgrp0;
86struct proc proc0;
87struct pcred cred0;
88struct filedesc0 filedesc0;
89struct plimit limit0;
90struct vmspace vmspace0;
91struct proc *curproc = &proc0;
78
79/* Components of the first process -- never freed. */
80struct session session0;
81struct pgrp pgrp0;
82struct proc proc0;
83struct pcred cred0;
84struct filedesc0 filedesc0;
85struct plimit limit0;
86struct vmspace vmspace0;
87struct proc *curproc = &proc0;
92struct proc *initproc, *pageproc, *updateproc, *vmproc;
88struct proc *initproc;
93
94int cmask = CMASK;
95extern struct user *proc0paddr;
96
97struct vnode *rootvp;
98int boothowto;
99struct timeval boottime;
100struct timeval runtime;
101
89
90int cmask = CMASK;
91extern struct user *proc0paddr;
92
93struct vnode *rootvp;
94int boothowto;
95struct timeval boottime;
96struct timeval runtime;
97
102static void start_init __P((struct proc *p, void *framep));
98/*
99 * Promiscuous argument pass for start_init()
100 *
101 * This is a kludge because we use a return from main() rather than a call
102 * to a new reoutine in locore.s to kick the kernel alive from locore.s.
103 */
104static void *init_framep;
103
105
106
104#if __GNUC__ >= 2
105void __main() {}
106#endif
107
107#if __GNUC__ >= 2
108void __main() {}
109#endif
110
111
108/*
112/*
109 * This table is filled in by the linker with functions that need to be
110 * called to initialize various pseudo-devices and whatnot.
113 * This ensures that there is at least one entry so that the sysinit_set
114 * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never
115 * executed.
111 */
116 */
117SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
112
118
113static void dummyinit() {}
114TEXT_SET(pseudo_set, dummyinit);
115
119
116typedef void (*pseudo_func_t)(void);
117extern const struct linker_set pseudo_set;
118static const pseudo_func_t *pseudos =
119 (const pseudo_func_t *)&pseudo_set.ls_items[0];
120
121/*
122 * System startup; initialize the world, create process 0, mount root
123 * filesystem, and fork to create init and pagedaemon. Most of the
124 * hard work is done in the lower-level initialization routines including
125 * startup(), which does memory initialization and autoconfiguration.
120/*
121 * System startup; initialize the world, create process 0, mount root
122 * filesystem, and fork to create init and pagedaemon. Most of the
123 * hard work is done in the lower-level initialization routines including
124 * startup(), which does memory initialization and autoconfiguration.
125 *
126 * This allows simple addition of new kernel subsystems that require
127 * boot time initialization. It also allows substitution of subsystem
128 * (for instance, a scheduler, kernel profiler, or VM system) by object
129 * module. Finally, it allows for optional "kernel threads", like an LFS
130 * cleaner.
126 */
127void
128main(framep)
129 void *framep;
130{
131 */
132void
133main(framep)
134 void *framep;
135{
131 register struct proc *p;
132 register struct filedesc0 *fdp;
136
137 register struct sysinit **sipp; /* system initialization*/
138 register struct sysinit **xipp; /* interior loop of sort*/
139 register struct sysinit *save; /* bubble*/
140 int rval[2]; /* SI_TYPE_KTHREAD support*/
141
142 extern struct linker_set sysinit_set;
143
144 /*
145 * Save the locore.s frame pointer for start_init().
146 */
147 init_framep = framep;
148
149 /*
150 * Perform a bubble sort of the system initialization objects by
151 * their subsystem (primary key) and order (secondary key).
152 *
153 * Since some things care about execution order, this is the
154 * operation which ensures continued function.
155 */
156 for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
157 for( xipp = sipp + 1; *xipp; xipp++) {
158 if( (*sipp)->subsystem < (*xipp)->subsystem ||
159 ( (*sipp)->subsystem == (*xipp)->subsystem &&
160 (*sipp)->order < (*xipp)->order))
161 continue; /* skip*/
162 save = *sipp;
163 *sipp = *xipp;
164 *xipp = save;
165 }
166 }
167
168 /*
169 * Traverse the (now) ordered list of system initialization tasks.
170 * Perform each task, and continue on to the next task.
171 *
172 * The last item on the list is expected to be the scheduler,
173 * which will not return.
174 */
175 for( sipp = (struct sysinit **)sysinit_set.ls_items; *sipp; sipp++) {
176 if( (*sipp)->subsystem == SI_SUB_DUMMY)
177 continue; /* skip dummy task(s)*/
178
179 switch( (*sipp)->type) {
180 case SI_TYPE_DEFAULT:
181 /* no special processing*/
182 (*((*sipp)->func))( (*sipp)->udata);
183 break;
184
185 case SI_TYPE_KTHREAD:
186 /* kernel thread*/
187 if (fork(&proc0, NULL, rval))
188 panic("fork kernel process");
189 if (rval[1]) {
190 (*((*sipp)->func))( (*sipp)->udata);
191 /*
192 * The call to start "init" returns
193 * here after the scheduler has been
194 * started, and returns to the caller
195 * in i386/i386/locore.s. This is a
196 * necessary part of initialization
197 * and is rather non-obvious.
198 *
199 * No other "kernel threads" should
200 * return here. Call panic() instead.
201 */
202 return;
203 }
204 break;
205
206 default:
207 panic( "init_main: unrecognized init type");
208 }
209 }
210
211 /* NOTREACHED*/
212}
213
214
215/*
216 * Start a kernel process. This is called after a fork() call in
217 * main() in the file kern/init_main.c.
218 *
219 * This function is used to start "internal" daemons.
220 */
221/* ARGSUSED*/
222void
223kproc_start( udata)
224caddr_t udata; /* not used*/
225{
226 struct kproc_desc *kp = (struct kproc_desc *)udata;
227 struct proc *p = curproc;
228
229 /* save a global descriptor, if desired*/
230 if( kp->global_procpp != NULL)
231 *kp->global_procpp = p;
232
233 /* this is a non-swapped system process*/
234 p->p_flag |= P_INMEM | P_SYSTEM;
235
236 /* set up arg0 for 'ps', et al*/
237 strcpy( p->p_comm, kp->arg0);
238
239 /* call the processes' main()...*/
240 (*kp->func)();
241
242 /* NOTREACHED */
243 panic( "kproc_start: %s", kp->arg0);
244}
245
246
247/*
248 ***************************************************************************
249 ****
250 **** The following SYSINIT's belong elsewhere, but have not yet
251 **** been moved.
252 ****
253 ***************************************************************************
254 */
255#ifdef OMIT
256/*
257 * Handled by vfs_mountroot (bad idea) at this time... should be
258 * done the same as 4.4Lite2.
259 */
260SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL)
261#endif /* OMIT*/
262
263/*
264 * Should get its own file...
265 */
266#ifdef HPFPLIB
267char copyright[] =
268"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";
269#else
270char copyright[] =
271"Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n";
272#endif
273SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, printf, (caddr_t)copyright)
274
275
276/*
277 ***************************************************************************
278 ****
279 **** The two following SYSINT's are proc0 specific glue code. I am not
280 **** convinced that they can not be safely combined, but their order of
281 **** operation has been maintained as the same as the original init_main.c
282 **** for right now.
283 ****
284 **** These probably belong in init_proc.c or kern_proc.c, since they
285 **** deal with proc0 (the fork template process).
286 ****
287 ***************************************************************************
288 */
289/* ARGSUSED*/
290void
291proc0_init( udata)
292caddr_t udata; /* not used*/
293{
294 register struct proc *p;
295 register struct filedesc0 *fdp;
133 register int i;
296 register int i;
134 int s, rval[2];
135
136 /*
137 * Initialize the current process pointer (curproc) before
138 * any possible traps/probes to simplify trap processing.
139 */
140 p = &proc0;
297
298 /*
299 * Initialize the current process pointer (curproc) before
300 * any possible traps/probes to simplify trap processing.
301 */
302 p = &proc0;
141 curproc = p;
142 printf(copyright);
303 curproc = p; /* XXX redundant*/
143
304
144 vm_mem_init();
145 kmeminit();
146 cpu_startup();
147
148 /*
149 * Create process 0 (the swapper).
150 */
151 allproc = (volatile struct proc *)p;
152 p->p_prev = (struct proc **)&allproc;
153 p->p_pgrp = &pgrp0;
154 pgrphash[0] = &pgrp0;
155 pgrp0.pg_mem = p;

--- 43 unchanged lines hidden (view full) ---

199 p->p_vmspace = &vmspace0;
200 vmspace0.vm_refcnt = 1;
201 pmap_pinit(&vmspace0.vm_pmap);
202 vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
203 trunc_page(VM_MAX_ADDRESS), TRUE);
204 vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
205 p->p_addr = proc0paddr; /* XXX */
206
305 /*
306 * Create process 0 (the swapper).
307 */
308 allproc = (volatile struct proc *)p;
309 p->p_prev = (struct proc **)&allproc;
310 p->p_pgrp = &pgrp0;
311 pgrphash[0] = &pgrp0;
312 pgrp0.pg_mem = p;

--- 43 unchanged lines hidden (view full) ---

356 p->p_vmspace = &vmspace0;
357 vmspace0.vm_refcnt = 1;
358 pmap_pinit(&vmspace0.vm_pmap);
359 vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
360 trunc_page(VM_MAX_ADDRESS), TRUE);
361 vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
362 p->p_addr = proc0paddr; /* XXX */
363
364#define INCOMPAT_LITES2
365#ifdef INCOMPAT_LITES2
207 /*
208 * proc0 needs to have a coherent frame base, too.
209 * This probably makes the identical call for the init proc
210 * that happens later unnecessary since it should inherit
211 * it during the fork.
212 */
366 /*
367 * proc0 needs to have a coherent frame base, too.
368 * This probably makes the identical call for the init proc
369 * that happens later unnecessary since it should inherit
370 * it during the fork.
371 */
213 cpu_set_init_frame(p, framep); /* XXX! */
372 cpu_set_init_frame(p, init_framep); /* XXX! */
373#endif /* INCOMPAT_LITES2*/
214
215 /*
216 * We continue to place resource usage info and signal
217 * actions in the user struct so they're pageable.
218 */
219 p->p_stats = &p->p_addr->u_stats;
220 p->p_sigacts = &p->p_addr->u_sigacts;
221
222 /*
223 * Initialize per uid information structure and charge
224 * root for one process.
225 */
226 usrinfoinit();
227 (void)chgproccnt(0, 1);
374
375 /*
376 * We continue to place resource usage info and signal
377 * actions in the user struct so they're pageable.
378 */
379 p->p_stats = &p->p_addr->u_stats;
380 p->p_sigacts = &p->p_addr->u_sigacts;
381
382 /*
383 * Initialize per uid information structure and charge
384 * root for one process.
385 */
386 usrinfoinit();
387 (void)chgproccnt(0, 1);
388}
389SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
228
390
229 rqinit();
230
231 /* Configure virtual memory system, set vm rlimits. */
232 vm_init_limits(p);
233
234 /* Initialize the file systems. */
235 vfsinit();
236
237 /* Start real time and statistics clocks. */
238 initclocks();
239
240 /* Initialize mbuf's. */
241 mbinit();
242
243 /* Initialize clists. */
244 clist_init();
245
246#ifdef SYSVSHM
247 /* Initialize System V style shared memory. */
248 shminit();
249#endif
250
251#ifdef SYSVSEM
252 /* Initialize System V style semaphores. */
253 seminit();
254#endif
255
256#ifdef SYSVMSG
257 /* Initialize System V style message queues. */
258 msginit();
259#endif
260
391/* ARGSUSED*/
392void
393proc0_post( udata)
394caddr_t udata; /* not used*/
395{
261 /*
396 /*
262 * Attach pseudo-devices.
397 * Now can look at time, having had a chance to verify the time
398 * from the file system. Reset p->p_rtime as it may have been
399 * munched in mi_switch() after the time got set.
263 */
400 */
264 while(*pseudos) {
265 (**pseudos++)();
266 }
401 proc0.p_stats->p_start = runtime = mono_time = boottime = time;
402 proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0;
267
403
268 /*
269 * Initialize protocols. Block reception of incoming packets
270 * until everything is ready.
271 */
272 s = splimp();
273 ifinit();
274 domaininit();
275 splx(s);
404 /* Initialize signal state for process 0. */
405 siginit(&proc0);
406}
407SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
276
408
277#ifdef GPROF
278 /* Initialize kernel profiling. */
279 kmstartup();
280#endif
281
409
410
411
412/*
413 ***************************************************************************
414 ****
415 **** The following SYSINIT's and glue code should be moved to the
416 **** respective files on a per subsystem basis.
417 ****
418 ***************************************************************************
419 */
420/* ARGSUSED*/
421void
422sched_setup( udata)
423caddr_t udata; /* not used*/
424{
282 /* Kick off timeout driven events by calling first time. */
283 roundrobin(NULL);
284 schedcpu(NULL);
425 /* Kick off timeout driven events by calling first time. */
426 roundrobin(NULL);
427 schedcpu(NULL);
428}
429SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL)
285
430
431/* ARGSUSED*/
432void
433xxx_vfs_mountroot( udata)
434caddr_t udata; /* not used*/
435{
286 /* Mount the root file system. */
436 /* Mount the root file system. */
287 if ((*mountroot)())
437 if ((*mountroot)( (caddr_t)mountrootvfsops))
288 panic("cannot mount root");
438 panic("cannot mount root");
439}
440SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL)
289
441
442/* ARGSUSED*/
443void
444xxx_vfs_root_fdtab( udata)
445caddr_t udata; /* not used*/
446{
447 register struct filedesc0 *fdp = &filedesc0;
448
290 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
291 if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
292 panic("cannot find root vnode");
293 fdp->fd_fd.fd_cdir = rootvnode;
294 VREF(fdp->fd_fd.fd_cdir);
295 VOP_UNLOCK(rootvnode);
296 fdp->fd_fd.fd_rdir = NULL;
449 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */
450 if (VFS_ROOT(mountlist.cqh_first, &rootvnode))
451 panic("cannot find root vnode");
452 fdp->fd_fd.fd_cdir = rootvnode;
453 VREF(fdp->fd_fd.fd_cdir);
454 VOP_UNLOCK(rootvnode);
455 fdp->fd_fd.fd_rdir = NULL;
456}
457SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL)
297
458
298 /*
299 * Now can look at time, having had a chance to verify the time
300 * from the file system. Reset p->p_rtime as it may have been
301 * munched in mi_switch() after the time got set.
302 */
303 p->p_stats->p_start = runtime = mono_time = boottime = time;
304 p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
305
459
306 /* Initialize signal state for process 0. */
307 siginit(p);
460/*
461 ***************************************************************************
462 ****
463 **** The following code probably belongs in another file, like
464 **** kern/init_init.c. It is here for two reasons only:
465 ****
466 **** 1) This code returns to startup the system; this is
467 **** abnormal for a kernel thread.
468 **** 2) This code promiscuously uses init_frame
469 ****
470 ***************************************************************************
471 */
308
472
309 /* Create process 1 (init(8)). */
310 if (fork(p, NULL, rval))
311 panic("fork init");
312 if (rval[1]) {
313 start_init(curproc, framep);
314 return;
315 }
473static void kthread_init __P(( caddr_t udata));
474SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL)
316
475
317 /* Create process 2 (the pageout daemon). */
318 if (fork(p, NULL, rval))
319 panic("fork pager");
320 if (rval[1]) {
321 /*
322 * Now in process 2.
323 */
324 p = curproc;
325 pageproc = p;
326 p->p_flag |= P_INMEM | P_SYSTEM; /* XXX */
327 bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon"));
328 vm_pageout();
329 /* NOTREACHED */
330 }
331
476
332 /*
333 * Start high level vm daemon (process 3).
334 */
335 if (fork(p, (void *) NULL, rval))
336 panic("failed fork vm daemon");
337 if (rval[1]) {
338 p = curproc;
339 vmproc = p;
340 p->p_flag |= P_INMEM | P_SYSTEM;
341 bcopy("vmdaemon", p->p_comm, sizeof("vmdaemon"));
342 vm_daemon();
343 /*NOTREACHED*/
344 }
477static void start_init __P((struct proc *p, void *framep));
345
478
479/* ARGSUSED*/
480static void
481kthread_init( udata)
482caddr_t udata; /* not used*/
483{
484
485 /* Create process 1 (init(8)). */
486 start_init(curproc, init_framep);
487
346 /*
488 /*
347 * Start update daemon (process 4).
489 * This is the only kernel thread allowed to return yo the
490 * caller!!!
348 */
491 */
349 if (fork(p, (void *) NULL, rval))
350 panic("failed fork update daemon");
351 if (rval[1]) {
352 p = curproc;
353 updateproc = p;
354 p->p_flag |= P_INMEM | P_SYSTEM;
355 bcopy("update", p->p_comm, sizeof("update"));
356 vfs_update();
357 /*NOTREACHED*/
358 }
359
360 /* The scheduler is an infinite loop. */
361 scheduler();
362 /* NOTREACHED */
492 return;
363}
364
493}
494
495
365/*
366 * List of paths to try when searching for "init".
367 */
368static char *initpaths[] = {
369 "/sbin/init",
370 "/sbin/oinit",
371 "/sbin/init.bak",
372 "/stand/sysinstall",

--- 81 unchanged lines hidden (view full) ---

454 */
455 args.fname = arg0;
456 args.argv = uap;
457 args.envv = NULL;
458
459 /*
460 * Now try to exec the program. If can't for any reason
461 * other than it doesn't exist, complain.
496/*
497 * List of paths to try when searching for "init".
498 */
499static char *initpaths[] = {
500 "/sbin/init",
501 "/sbin/oinit",
502 "/sbin/init.bak",
503 "/stand/sysinstall",

--- 81 unchanged lines hidden (view full) ---

585 */
586 args.fname = arg0;
587 args.argv = uap;
588 args.envv = NULL;
589
590 /*
591 * Now try to exec the program. If can't for any reason
592 * other than it doesn't exist, complain.
593 *
594 * Otherwise return to main() which returns to btext
595 * which completes the system startup.
462 */
463 if ((error = execve(p, &args, &retval[0])) == 0)
464 return;
465 if (error != ENOENT)
466 printf("exec %s: error %d\n", path, error);
467 }
468 printf("init: not found\n");
469 panic("no init");
470}
596 */
597 if ((error = execve(p, &args, &retval[0])) == 0)
598 return;
599 if (error != ENOENT)
600 printf("exec %s: error %d\n", path, error);
601 }
602 printf("init: not found\n");
603 panic("no init");
604}