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.51 1996/10/28 11:34:42 phk Exp $ 43 */ 44 45 #include "opt_rlimit.h" 46 #include "opt_devfs.h" 47 48 #include <sys/param.h> 49 #include <sys/filedesc.h> 50 #include <sys/kernel.h> 51 #include <sys/sysctl.h> 52 #include <sys/proc.h> 53 #include <sys/resourcevar.h> 54 #include <sys/signalvar.h> 55 #include <sys/systm.h> 56 #include <sys/vnode.h> 57 #include <sys/sysent.h> 58 #include <sys/reboot.h> 59 #include <sys/sysproto.h> 60 #include <sys/vmmeter.h> 61 62 #include <machine/cpu.h> 63 64 #include <vm/vm.h> 65 #include <vm/vm_param.h> 66 #include <vm/vm_prot.h> 67 #include <vm/lock.h> 68 #include <vm/pmap.h> 69 #include <vm/vm_map.h> 70 #include <sys/user.h> 71 72 extern struct linker_set sysinit_set; /* XXX */ 73 74 extern void __main __P((void)); 75 extern void main __P((void *framep)); 76 77 /* Components of the first process -- never freed. */ 78 static struct session session0; 79 static struct pgrp pgrp0; 80 struct proc proc0; 81 static struct pcred cred0; 82 static struct filedesc0 filedesc0; 83 static struct plimit limit0; 84 static struct vmspace vmspace0; 85 struct proc *curproc = &proc0; 86 struct proc *initproc; 87 88 int cmask = CMASK; 89 extern struct user *proc0paddr; 90 91 struct vnode *rootvp; 92 int boothowto; 93 94 struct timeval boottime; 95 SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, 96 CTLFLAG_RW, &boottime, timeval, ""); 97 98 struct timeval runtime; 99 100 /* 101 * Promiscuous argument pass for start_init() 102 * 103 * This is a kludge because we use a return from main() rather than a call 104 * to a new routine in locore.s to kick the kernel alive from locore.s. 105 */ 106 static void *init_framep; 107 108 109 #if __GNUC__ >= 2 110 void __main() {} 111 #endif 112 113 114 /* 115 * This ensures that there is at least one entry so that the sysinit_set 116 * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never 117 * executed. 118 */ 119 SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL) 120 121 122 /* 123 * System startup; initialize the world, create process 0, mount root 124 * filesystem, and fork to create init and pagedaemon. Most of the 125 * hard work is done in the lower-level initialization routines including 126 * startup(), which does memory initialization and autoconfiguration. 127 * 128 * This allows simple addition of new kernel subsystems that require 129 * boot time initialization. It also allows substitution of subsystem 130 * (for instance, a scheduler, kernel profiler, or VM system) by object 131 * module. Finally, it allows for optional "kernel threads", like an LFS 132 * cleaner. 133 */ 134 void 135 main(framep) 136 void *framep; 137 { 138 139 register struct sysinit **sipp; /* system initialization*/ 140 register struct sysinit **xipp; /* interior loop of sort*/ 141 register struct sysinit *save; /* bubble*/ 142 int rval[2]; /* SI_TYPE_KTHREAD support*/ 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*/ 222 void 223 kproc_start(udata) 224 void *udata; 225 { 226 struct kproc_desc *kp = 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 */ 260 SYSINIT(swapinit, SI_SUB_SWAP, SI_ORDER_FIRST, swapinit, NULL) 261 #endif /* OMIT*/ 262 263 /* 264 * Should get its own file... 265 */ 266 #ifdef HPFPLIB 267 char 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 270 char copyright[] = 271 "Copyright (c) 1992-1996 FreeBSD Inc.\n" 272 #ifdef PC98 273 "Copyright (c) 1994-1996 FreeBSD(98) porting team.\n" 274 "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\n" 275 "Copyright (c) 1992 A.Kojima F.Ukai M.Ishii (KMC).\n" 276 "\tAll rights reserved.\n\n"; 277 #else 278 "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n"; 279 #endif 280 #endif 281 static void print_caddr_t __P((void *data)); 282 static void 283 print_caddr_t(data) 284 void *data; 285 { 286 printf("%s", (char *)data); 287 } 288 SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright) 289 290 291 /* 292 *************************************************************************** 293 **** 294 **** The two following SYSINT's are proc0 specific glue code. I am not 295 **** convinced that they can not be safely combined, but their order of 296 **** operation has been maintained as the same as the original init_main.c 297 **** for right now. 298 **** 299 **** These probably belong in init_proc.c or kern_proc.c, since they 300 **** deal with proc0 (the fork template process). 301 **** 302 *************************************************************************** 303 */ 304 /* ARGSUSED*/ 305 static void proc0_init __P((void *dummy)); 306 static void 307 proc0_init(dummy) 308 void *dummy; 309 { 310 register struct proc *p; 311 register struct filedesc0 *fdp; 312 register unsigned i; 313 314 /* 315 * Initialize the current process pointer (curproc) before 316 * any possible traps/probes to simplify trap processing. 317 */ 318 p = &proc0; 319 curproc = p; /* XXX redundant*/ 320 321 /* 322 * Initialize process and pgrp structures. 323 */ 324 procinit(); 325 326 /* 327 * Initialize sleep queue hash table 328 */ 329 sleepinit(); 330 331 /* 332 * Create process 0 (the swapper). 333 */ 334 LIST_INSERT_HEAD(&allproc, p, p_list); 335 p->p_pgrp = &pgrp0; 336 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); 337 LIST_INIT(&pgrp0.pg_members); 338 LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist); 339 340 pgrp0.pg_session = &session0; 341 session0.s_count = 1; 342 session0.s_leader = p; 343 344 p->p_sysent = &aout_sysvec; 345 346 p->p_flag = P_INMEM | P_SYSTEM; 347 p->p_stat = SRUN; 348 p->p_nice = NZERO; 349 p->p_rtprio.type = RTP_PRIO_NORMAL; 350 p->p_rtprio.prio = 0; 351 352 bcopy("swapper", p->p_comm, sizeof ("swapper")); 353 354 /* Create credentials. */ 355 cred0.p_refcnt = 1; 356 p->p_cred = &cred0; 357 p->p_ucred = crget(); 358 p->p_ucred->cr_ngroups = 1; /* group 0 */ 359 360 /* Create the file descriptor table. */ 361 fdp = &filedesc0; 362 p->p_fd = &fdp->fd_fd; 363 fdp->fd_fd.fd_refcnt = 1; 364 fdp->fd_fd.fd_cmask = cmask; 365 fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; 366 fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; 367 fdp->fd_fd.fd_nfiles = NDFILE; 368 369 /* Create the limits structures. */ 370 p->p_limit = &limit0; 371 for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) 372 limit0.pl_rlimit[i].rlim_cur = 373 limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; 374 limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; 375 limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; 376 i = ptoa(cnt.v_free_count); 377 limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i; 378 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i; 379 limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3; 380 limit0.p_refcnt = 1; 381 382 /* Allocate a prototype map so we have something to fork. */ 383 p->p_vmspace = &vmspace0; 384 vmspace0.vm_refcnt = 1; 385 pmap_pinit(&vmspace0.vm_pmap); 386 vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS), 387 trunc_page(VM_MAXUSER_ADDRESS), TRUE); 388 vmspace0.vm_map.pmap = &vmspace0.vm_pmap; 389 p->p_addr = proc0paddr; /* XXX */ 390 391 #define INCOMPAT_LITES2 392 #ifdef INCOMPAT_LITES2 393 /* 394 * proc0 needs to have a coherent frame base, too. 395 * This probably makes the identical call for the init proc 396 * that happens later unnecessary since it should inherit 397 * it during the fork. 398 */ 399 cpu_set_init_frame(p, init_framep); /* XXX! */ 400 #endif /* INCOMPAT_LITES2*/ 401 402 /* 403 * We continue to place resource usage info and signal 404 * actions in the user struct so they're pageable. 405 */ 406 p->p_stats = &p->p_addr->u_stats; 407 p->p_sigacts = &p->p_addr->u_sigacts; 408 409 /* 410 * Charge root for one process. 411 */ 412 (void)chgproccnt(0, 1); 413 } 414 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) 415 416 /* ARGSUSED*/ 417 static void proc0_post __P((void *dummy)); 418 static void 419 proc0_post(dummy) 420 void *dummy; 421 { 422 struct timeval tv; 423 424 /* 425 * Now can look at time, having had a chance to verify the time 426 * from the file system. Reset p->p_rtime as it may have been 427 * munched in mi_switch() after the time got set. 428 */ 429 proc0.p_stats->p_start = runtime = mono_time = boottime = time; 430 proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0; 431 432 /* 433 * Give the ``random'' number generator a thump. 434 */ 435 microtime(&tv); 436 srandom(tv.tv_sec ^ tv.tv_usec); 437 438 /* Initialize signal state for process 0. */ 439 siginit(&proc0); 440 } 441 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL) 442 443 444 445 446 /* 447 *************************************************************************** 448 **** 449 **** The following SYSINIT's and glue code should be moved to the 450 **** respective files on a per subsystem basis. 451 **** 452 *************************************************************************** 453 */ 454 /* ARGSUSED*/ 455 static void sched_setup __P((void *dummy)); 456 static void 457 sched_setup(dummy) 458 void *dummy; 459 { 460 /* Kick off timeout driven events by calling first time. */ 461 roundrobin(NULL); 462 schedcpu(NULL); 463 } 464 SYSINIT(sched_setup, SI_SUB_KICK_SCHEDULER, SI_ORDER_FIRST, sched_setup, NULL) 465 466 /* ARGSUSED*/ 467 static void xxx_vfs_mountroot __P((void *dummy)); 468 static void 469 xxx_vfs_mountroot(dummy) 470 void *dummy; 471 { 472 /* Mount the root file system. */ 473 if ((*mountroot)(mountrootvfsops)) 474 panic("cannot mount root"); 475 } 476 SYSINIT(mountroot, SI_SUB_ROOT, SI_ORDER_FIRST, xxx_vfs_mountroot, NULL) 477 478 /* ARGSUSED*/ 479 static void xxx_vfs_root_fdtab __P((void *dummy)); 480 static void 481 xxx_vfs_root_fdtab(dummy) 482 void *dummy; 483 { 484 register struct filedesc0 *fdp = &filedesc0; 485 486 /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ 487 if (VFS_ROOT(mountlist.cqh_first, &rootvnode)) 488 panic("cannot find root vnode"); 489 fdp->fd_fd.fd_cdir = rootvnode; 490 VREF(fdp->fd_fd.fd_cdir); 491 VOP_UNLOCK(rootvnode); 492 fdp->fd_fd.fd_rdir = NULL; 493 } 494 SYSINIT(retrofit, SI_SUB_ROOT_FDTAB, SI_ORDER_FIRST, xxx_vfs_root_fdtab, NULL) 495 496 497 /* 498 *************************************************************************** 499 **** 500 **** The following code probably belongs in another file, like 501 **** kern/init_init.c. It is here for two reasons only: 502 **** 503 **** 1) This code returns to startup the system; this is 504 **** abnormal for a kernel thread. 505 **** 2) This code promiscuously uses init_frame 506 **** 507 *************************************************************************** 508 */ 509 510 static void kthread_init __P((void *dummy)); 511 SYSINIT_KT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL) 512 513 514 static void start_init __P((struct proc *p, void *framep)); 515 516 /* ARGSUSED*/ 517 static void 518 kthread_init(dummy) 519 void *dummy; 520 { 521 522 /* Create process 1 (init(8)). */ 523 start_init(curproc, init_framep); 524 525 /* 526 * This is the only kernel thread allowed to return yo the 527 * caller!!! 528 */ 529 return; 530 } 531 532 533 /* 534 * List of paths to try when searching for "init". 535 */ 536 static char *initpaths[] = { 537 "/sbin/init", 538 "/sbin/oinit", 539 "/sbin/init.bak", 540 "/stand/sysinstall", 541 NULL, 542 }; 543 544 /* 545 * Start the initial user process; try exec'ing each pathname in "initpaths". 546 * The program is invoked with one argument containing the boot flags. 547 */ 548 static void 549 start_init(p, framep) 550 struct proc *p; 551 void *framep; 552 { 553 vm_offset_t addr; 554 struct execve_args args; 555 int options, i, retval[2], error; 556 char **pathp, *path, *ucp, **uap, *arg0, *arg1; 557 558 initproc = p; 559 560 /* 561 * We need to set the system call frame as if we were entered through 562 * a syscall() so that when we call execve() below, it will be able 563 * to set the entry point (see setregs) when it tries to exec. The 564 * startup code in "locore.s" has allocated space for the frame and 565 * passed a pointer to that space as main's argument. 566 */ 567 cpu_set_init_frame(p, framep); 568 569 /* 570 * Need just enough stack to hold the faked-up "execve()" arguments. 571 */ 572 addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE); 573 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) 574 panic("init: couldn't allocate argument space"); 575 p->p_vmspace->vm_maxsaddr = (caddr_t)addr; 576 p->p_vmspace->vm_ssize = 1; 577 578 for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) { 579 /* 580 * Move out the boot flag argument. 581 */ 582 options = 0; 583 ucp = (char *)USRSTACK; 584 (void)subyte(--ucp, 0); /* trailing zero */ 585 if (boothowto & RB_SINGLE) { 586 (void)subyte(--ucp, 's'); 587 options = 1; 588 } 589 #ifdef notyet 590 if (boothowto & RB_FASTBOOT) { 591 (void)subyte(--ucp, 'f'); 592 options = 1; 593 } 594 #endif 595 596 #ifdef BOOTCDROM 597 (void)subyte(--ucp, 'C'); 598 options = 1; 599 #endif 600 601 #if defined(DEVFS) && defined(DEVFS_ROOT) 602 (void)subyte(--ucp, 'd'); 603 options = 1; 604 #endif 605 if (options == 0) 606 (void)subyte(--ucp, '-'); 607 (void)subyte(--ucp, '-'); /* leading hyphen */ 608 arg1 = ucp; 609 610 /* 611 * Move out the file name (also arg 0). 612 */ 613 for (i = strlen(path) + 1; i >= 0; i--) 614 (void)subyte(--ucp, path[i]); 615 arg0 = ucp; 616 617 /* 618 * Move out the arg pointers. 619 */ 620 uap = (char **)((int)ucp & ~(NBPW-1)); 621 (void)suword((caddr_t)--uap, 0); /* terminator */ 622 (void)suword((caddr_t)--uap, (int)arg1); 623 (void)suword((caddr_t)--uap, (int)arg0); 624 625 /* 626 * Point at the arguments. 627 */ 628 args.fname = arg0; 629 args.argv = uap; 630 args.envv = NULL; 631 632 /* 633 * Now try to exec the program. If can't for any reason 634 * other than it doesn't exist, complain. 635 * 636 * Otherwise return to main() which returns to btext 637 * which completes the system startup. 638 */ 639 if ((error = execve(p, &args, &retval[0])) == 0) 640 return; 641 if (error != ENOENT) 642 printf("exec %s: error %d\n", path, error); 643 } 644 printf("init: not found\n"); 645 panic("no init"); 646 } 647