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} |