1 /* 2 * Copyright (c) 1995 Terrence R. Lambert 3 * All rights reserved. 4 * 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 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgement: 23 * This product includes software developed by the University of 24 * California, Berkeley and its contributors. 25 * 4. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * @(#)init_main.c 8.9 (Berkeley) 1/21/94 42 * $Id: init_main.c,v 1.98 1998/10/09 23:42:47 peter Exp $ 43 */ 44 45 #include "opt_devfs.h" 46 47 #include <sys/param.h> 48 #include <sys/file.h> 49 #include <sys/filedesc.h> 50 #include <sys/kernel.h> 51 #include <sys/mount.h> 52 #include <sys/sysctl.h> 53 #include <sys/proc.h> 54 #include <sys/resourcevar.h> 55 #include <sys/signalvar.h> 56 #include <sys/systm.h> 57 #include <sys/vnode.h> 58 #include <sys/sysent.h> 59 #include <sys/reboot.h> 60 #include <sys/sysproto.h> 61 #include <sys/vmmeter.h> 62 #include <sys/unistd.h> 63 #include <sys/malloc.h> 64 65 #include <machine/cpu.h> 66 67 #include <vm/vm.h> 68 #include <vm/vm_param.h> 69 #include <vm/vm_prot.h> 70 #include <sys/lock.h> 71 #include <vm/pmap.h> 72 #include <vm/vm_map.h> 73 #include <sys/user.h> 74 #include <sys/copyright.h> 75 76 extern struct linker_set sysinit_set; /* XXX */ 77 78 extern void __main __P((void)); 79 extern void main __P((void *framep)); 80 81 /* Components of the first process -- never freed. */ 82 static struct session session0; 83 static struct pgrp pgrp0; 84 struct proc proc0; 85 static struct pcred cred0; 86 static struct filedesc0 filedesc0; 87 static struct plimit limit0; 88 static struct vmspace vmspace0; 89 struct proc *initproc; 90 91 int cmask = CMASK; 92 extern struct user *proc0paddr; 93 94 struct vnode *rootvp; 95 int boothowto = 0; /* initialized so that it can be patched */ 96 97 struct timeval boottime; 98 SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, 99 CTLFLAG_RD, &boottime, timeval, ""); 100 101 static int shutdowntimeout = 120; 102 SYSCTL_INT(_kern, OID_AUTO, shutdown_timeout, 103 CTLFLAG_RW, &shutdowntimeout, 0, ""); 104 105 /* 106 * Promiscuous argument pass for start_init() 107 * 108 * This is a kludge because we use a return from main() rather than a call 109 * to a new routine in locore.s to kick the kernel alive from locore.s. 110 */ 111 static void *init_framep; 112 113 114 #if __GNUC__ >= 2 115 void __main() {} 116 #endif 117 118 119 /* 120 * This ensures that there is at least one entry so that the sysinit_set 121 * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never 122 * executed. 123 */ 124 SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL) 125 126 /* 127 * The sysinit table itself. Items are checked off as the are run. 128 * If we want to register new sysinit types, add them to newsysinit. 129 */ 130 struct sysinit **sysinit = (struct sysinit **)sysinit_set.ls_items; 131 struct sysinit **newsysinit; 132 133 /* 134 * Merge a new sysinit set into the current set, reallocating it if 135 * necessary. This can only be called after malloc is running. 136 */ 137 void 138 sysinit_add(set) 139 struct sysinit **set; 140 { 141 struct sysinit **newset; 142 struct sysinit **sipp; 143 struct sysinit **xipp; 144 int count = 0; 145 146 if (newsysinit) 147 for (sipp = newsysinit; *sipp; sipp++) 148 count++; 149 else 150 for (sipp = sysinit; *sipp; sipp++) 151 count++; 152 for (sipp = set; *sipp; sipp++) 153 count++; 154 count++; /* Trailing NULL */ 155 newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT); 156 if (newset == NULL) 157 panic("cannot malloc for sysinit"); 158 xipp = newset; 159 if (newsysinit) 160 for (sipp = newsysinit; *sipp; sipp++) 161 *xipp++ = *sipp; 162 else 163 for (sipp = sysinit; *sipp; sipp++) 164 *xipp++ = *sipp; 165 for (sipp = set; *sipp; sipp++) 166 *xipp++ = *sipp; 167 *xipp = NULL; 168 if (newsysinit) 169 free(newsysinit, M_TEMP); 170 newsysinit = newset; 171 } 172 173 /* 174 * System startup; initialize the world, create process 0, mount root 175 * filesystem, and fork to create init and pagedaemon. Most of the 176 * hard work is done in the lower-level initialization routines including 177 * startup(), which does memory initialization and autoconfiguration. 178 * 179 * This allows simple addition of new kernel subsystems that require 180 * boot time initialization. It also allows substitution of subsystem 181 * (for instance, a scheduler, kernel profiler, or VM system) by object 182 * module. Finally, it allows for optional "kernel threads". 183 */ 184 void 185 main(framep) 186 void *framep; 187 { 188 189 register struct sysinit **sipp; /* system initialization*/ 190 register struct sysinit **xipp; /* interior loop of sort*/ 191 register struct sysinit *save; /* bubble*/ 192 193 /* 194 * Copy the locore.s frame pointer for proc0, this is forked into 195 * all other processes. 196 */ 197 init_framep = framep; 198 199 restart: 200 /* 201 * Perform a bubble sort of the system initialization objects by 202 * their subsystem (primary key) and order (secondary key). 203 */ 204 for (sipp = sysinit; *sipp; sipp++) { 205 for (xipp = sipp + 1; *xipp; xipp++) { 206 if ((*sipp)->subsystem < (*xipp)->subsystem || 207 ((*sipp)->subsystem == (*xipp)->subsystem && 208 (*sipp)->order < (*xipp)->order)) 209 continue; /* skip*/ 210 save = *sipp; 211 *sipp = *xipp; 212 *xipp = save; 213 } 214 } 215 216 /* 217 * Traverse the (now) ordered list of system initialization tasks. 218 * Perform each task, and continue on to the next task. 219 * 220 * The last item on the list is expected to be the scheduler, 221 * which will not return. 222 */ 223 for (sipp = sysinit; *sipp; sipp++) { 224 225 if ((*sipp)->subsystem == SI_SUB_DUMMY) 226 continue; /* skip dummy task(s)*/ 227 228 if ((*sipp)->subsystem == SI_SUB_DONE) 229 continue; 230 231 switch( (*sipp)->type) { 232 case SI_TYPE_DEFAULT: 233 /* no special processing*/ 234 (*((*sipp)->func))((*sipp)->udata); 235 break; 236 237 case SI_TYPE_KTHREAD: 238 #if !defined(SMP) 239 /* kernel thread*/ 240 if (fork1(&proc0, RFMEM|RFFDG|RFPROC)) 241 panic("fork kernel thread"); 242 cpu_set_fork_handler(pfind(proc0.p_retval[0]), 243 (*sipp)->func, (*sipp)->udata); 244 break; 245 #endif 246 247 case SI_TYPE_KPROCESS: 248 if (fork1(&proc0, RFFDG|RFPROC)) 249 panic("fork kernel process"); 250 cpu_set_fork_handler(pfind(proc0.p_retval[0]), 251 (*sipp)->func, (*sipp)->udata); 252 break; 253 254 default: 255 panic("init_main: unrecognized init type"); 256 } 257 258 /* Check off the one we're just done */ 259 (*sipp)->subsystem = SI_SUB_DONE; 260 261 /* Check if we've installed more sysinit items via KLD */ 262 if (newsysinit != NULL) { 263 if (sysinit != (struct sysinit **)sysinit_set.ls_items) 264 free(sysinit, M_TEMP); 265 sysinit = newsysinit; 266 newsysinit = NULL; 267 goto restart; 268 } 269 } 270 271 panic("Shouldn't get here!"); 272 /* NOTREACHED*/ 273 } 274 275 276 /* 277 * Start a kernel process. This is called after a fork() call in 278 * main() in the file kern/init_main.c. 279 * 280 * This function is used to start "internal" daemons. 281 */ 282 /* ARGSUSED*/ 283 void 284 kproc_start(udata) 285 void *udata; 286 { 287 struct kproc_desc *kp = udata; 288 struct proc *p = curproc; 289 290 #ifdef DIAGNOSTIC 291 printf("Start pid=%d <%s>\n",p->p_pid, kp->arg0); 292 #endif 293 294 /* save a global descriptor, if desired*/ 295 if( kp->global_procpp != NULL) 296 *kp->global_procpp = p; 297 298 /* this is a non-swapped system process*/ 299 p->p_flag |= P_INMEM | P_SYSTEM; 300 301 /* set up arg0 for 'ps', et al*/ 302 strcpy( p->p_comm, kp->arg0); 303 304 /* call the processes' main()...*/ 305 (*kp->func)(); 306 307 /* NOTREACHED */ 308 panic("kproc_start: %s", kp->arg0); 309 } 310 311 312 /* 313 *************************************************************************** 314 **** 315 **** The following SYSINIT's belong elsewhere, but have not yet 316 **** been moved. 317 **** 318 *************************************************************************** 319 */ 320 #ifdef OMIT 321 /* 322 * Handled by vfs_mountroot (bad idea) at this time... should be 323 * done the same as 4.4Lite2. 324 */ 325 SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL) 326 #endif /* OMIT*/ 327 328 static void print_caddr_t __P((void *data)); 329 static void 330 print_caddr_t(data) 331 void *data; 332 { 333 printf("%s", (char *)data); 334 } 335 SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) 336 337 338 /* 339 *************************************************************************** 340 **** 341 **** The two following SYSINT's are proc0 specific glue code. I am not 342 **** convinced that they can not be safely combined, but their order of 343 **** operation has been maintained as the same as the original init_main.c 344 **** for right now. 345 **** 346 **** These probably belong in init_proc.c or kern_proc.c, since they 347 **** deal with proc0 (the fork template process). 348 **** 349 *************************************************************************** 350 */ 351 /* ARGSUSED*/ 352 static void proc0_init __P((void *dummy)); 353 static void 354 proc0_init(dummy) 355 void *dummy; 356 { 357 register struct proc *p; 358 register struct filedesc0 *fdp; 359 register unsigned i; 360 361 /* 362 * Initialize the current process pointer (curproc) before 363 * any possible traps/probes to simplify trap processing. 364 */ 365 p = &proc0; 366 curproc = p; /* XXX redundant*/ 367 368 /* 369 * Initialize process and pgrp structures. 370 */ 371 procinit(); 372 373 /* 374 * Initialize sleep queue hash table 375 */ 376 sleepinit(); 377 378 /* 379 * additional VM structures 380 */ 381 vm_init2(); 382 383 /* 384 * Create process 0 (the swapper). 385 */ 386 LIST_INSERT_HEAD(&allproc, p, p_list); 387 p->p_pgrp = &pgrp0; 388 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); 389 LIST_INIT(&pgrp0.pg_members); 390 LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); 391 392 pgrp0.pg_session = &session0; 393 session0.s_count = 1; 394 session0.s_leader = p; 395 396 p->p_sysent = &aout_sysvec; 397 398 p->p_flag = P_INMEM | P_SYSTEM; 399 p->p_stat = SRUN; 400 p->p_nice = NZERO; 401 p->p_rtprio.type = RTP_PRIO_NORMAL; 402 p->p_rtprio.prio = 0; 403 404 /* 405 * Link for kernel based threads 406 */ 407 p->p_peers = 0; 408 p->p_leader = p; 409 410 bcopy("swapper", p->p_comm, sizeof ("swapper")); 411 412 /* Create credentials. */ 413 cred0.p_refcnt = 1; 414 p->p_cred = &cred0; 415 p->p_ucred = crget(); 416 p->p_ucred->cr_ngroups = 1; /* group 0 */ 417 418 /* Create the file descriptor table. */ 419 fdp = &filedesc0; 420 p->p_fd = &fdp->fd_fd; 421 fdp->fd_fd.fd_refcnt = 1; 422 fdp->fd_fd.fd_cmask = cmask; 423 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 424 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 425 fdp->fd_fd.fd_nfiles = NDFILE; 426 427 /* Create the limits structures. */ 428 p->p_limit = &limit0; 429 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 430 limit0.pl_rlimit[i].rlim_cur = 431 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 432 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = 433 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles; 434 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = 435 limit0.pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc; 436 i = ptoa(cnt.v_free_count); 437 limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i; 438 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i; 439 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3; 440 limit0.p_cpulimit = RLIM_INFINITY; 441 limit0.p_refcnt = 1; 442 443 444 /* Allocate a prototype map so we have something to fork. */ 445 pmap_pinit0(&vmspace0.vm_pmap); 446 p->p_vmspace = &vmspace0; 447 vmspace0.vm_refcnt = 1; 448 vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS), 449 trunc_page(VM_MAXUSER_ADDRESS)); 450 vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 451 p->p_addr = proc0paddr; /* XXX */ 452 453 #ifndef __alpha__ /* XXX what is this? */ 454 #define INCOMPAT_LITES2 455 #ifdef INCOMPAT_LITES2 456 /* 457 * proc0 needs to have a coherent frame base in its stack. 458 */ 459 cpu_set_init_frame(p, init_framep); /* XXX! */ 460 #endif /* INCOMPAT_LITES2*/ 461 #endif 462 463 /* 464 * We continue to place resource usage info and signal 465 * actions in the user struct so they're pageable. 466 */ 467 p->p_stats = &p->p_addr->u_stats; 468 p->p_sigacts = &p->p_addr->u_sigacts; 469 470 /* 471 * Charge root for one process. 472 */ 473 (void)chgproccnt(0, 1); 474 475 /* 476 * Initialize the procfs flags (to 0, of course) 477 */ 478 p->p_stops = p->p_stype = p->p_step = 0; 479 480 } 481 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) 482 483 /* ARGSUSED*/ 484 static void proc0_post __P((void *dummy)); 485 static void 486 proc0_post(dummy) 487 void *dummy; 488 { 489 struct timespec ts; 490 491 /* 492 * Now can look at time, having had a chance to verify the time 493 * from the file system. Reset p->p_runtime as it may have been 494 * munched in mi_switch() after the time got set. Set 495 * p->p_switchtime to be consistent with this unmunching. 496 */ 497 microtime(&proc0.p_stats->p_start); 498 proc0.p_runtime = 0; 499 microuptime(&proc0.p_switchtime); 500 501 /* 502 * Give the ``random'' number generator a thump. 503 * XXX: Does read_random() contain enough bits to be used here ? 504 */ 505 nanotime(&ts); 506 srandom(ts.tv_sec ^ ts.tv_nsec); 507 508 /* Initialize signal state for process 0. */ 509 siginit(&proc0); 510 } 511 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL) 512 513 514 515 516 /* 517 *************************************************************************** 518 **** 519 **** The following SYSINIT's and glue code should be moved to the 520 **** respective files on a per subsystem basis. 521 **** 522 *************************************************************************** 523 */ 524 525 /* ARGSUSED */ 526 static void root_conf __P((void *dummy)); 527 static void 528 root_conf(dummy) 529 void *dummy; 530 { 531 cpu_rootconf(); 532 } 533 SYSINIT(root_conf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, root_conf, NULL) 534 535 /* ARGSUSED*/ 536 static void xxx_vfs_root_fdtab __P((void *dummy)); 537 static void 538 xxx_vfs_root_fdtab(dummy) 539 void *dummy; 540 { 541 register struct filedesc0 *fdp = &filedesc0; 542 543 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ 544 if (VFS_ROOT(mountlist.cqh_first, &rootvnode)) 545 panic("cannot find root vnode"); 546 fdp->fd_fd.fd_cdir = rootvnode; 547 VREF(fdp->fd_fd.fd_cdir); 548 VOP_UNLOCK(rootvnode, 0, &proc0); 549 fdp->fd_fd.fd_rdir = rootvnode; 550 } 551 SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL) 552 553 554 /* 555 *************************************************************************** 556 **** 557 **** The following code probably belongs in another file, like 558 **** kern/init_init.c. It is here for two reasons only: 559 **** 560 **** 1) This code returns to startup the system; this is 561 **** abnormal for a kernel thread. 562 **** 2) This code promiscuously uses init_frame 563 **** 564 *************************************************************************** 565 */ 566 567 static void kthread_init __P((void *dummy)); 568 SYSINIT_KP(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL) 569 570 571 extern void prepare_usermode __P((void)); 572 static void start_init __P((struct proc *p)); 573 574 /* ARGSUSED*/ 575 static void 576 kthread_init(dummy) 577 void *dummy; 578 { 579 /* Create process 1 (init(8)). */ 580 start_init(curproc); 581 582 prepare_usermode(); 583 584 /* 585 * This returns to the fork trampoline, then to user mode. 586 */ 587 return; 588 } 589 590 591 /* 592 * List of paths to try when searching for "init". 593 */ 594 static char *initpaths[] = { 595 "/sbin/init", 596 "/sbin/oinit", 597 "/sbin/init.bak", 598 "/stand/sysinstall", 599 NULL, 600 }; 601 602 /* 603 * Start the initial user process; try exec'ing each pathname in "initpaths". 604 * The program is invoked with one argument containing the boot flags. 605 */ 606 static void 607 start_init(p) 608 struct proc *p; 609 { 610 vm_offset_t addr; 611 struct execve_args args; 612 int options, i, error; 613 char **pathp, *path, *ucp, **uap, *arg0, *arg1; 614 615 initproc = p; 616 617 /* 618 * Need just enough stack to hold the faked-up "execve()" arguments. 619 */ 620 addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE); 621 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) 622 panic("init: couldn't allocate argument space"); 623 p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 624 p->p_vmspace->vm_ssize = 1; 625 626 for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) { 627 /* 628 * Move out the boot flag argument. 629 */ 630 options = 0; 631 ucp = (char *)USRSTACK; 632 (void)subyte(--ucp, 0); /* trailing zero */ 633 if (boothowto & RB_SINGLE) { 634 (void)subyte(--ucp, 's'); 635 options = 1; 636 } 637 #ifdef notyet 638 if (boothowto & RB_FASTBOOT) { 639 (void)subyte(--ucp, 'f'); 640 options = 1; 641 } 642 #endif 643 644 #ifdef BOOTCDROM 645 (void)subyte(--ucp, 'C'); 646 options = 1; 647 #endif 648 if (options == 0) 649 (void)subyte(--ucp, '-'); 650 (void)subyte(--ucp, '-'); /* leading hyphen */ 651 arg1 = ucp; 652 653 /* 654 * Move out the file name (also arg 0). 655 */ 656 for (i = strlen(path) + 1; i >= 0; i--) 657 (void)subyte(--ucp, path[i]); 658 arg0 = ucp; 659 660 /* 661 * Move out the arg pointers. 662 */ 663 uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1)); 664 (void)suword((caddr_t)--uap, (long)0); /* terminator */ 665 (void)suword((caddr_t)--uap, (long)(intptr_t)arg1); 666 (void)suword((caddr_t)--uap, (long)(intptr_t)arg0); 667 668 /* 669 * Point at the arguments. 670 */ 671 args.fname = arg0; 672 args.argv = uap; 673 args.envv = NULL; 674 675 /* 676 * Now try to exec the program. If can't for any reason 677 * other than it doesn't exist, complain. 678 * 679 * Otherwise return to main() which returns to btext 680 * which completes the system startup. 681 */ 682 if ((error = execve(p, &args)) == 0) 683 return; 684 if (error != ENOENT) 685 printf("exec %s: error %d\n", path, error); 686 } 687 printf("init: not found\n"); 688 panic("no init"); 689 } 690