init_main.c (df8abd0bb91dd5686111bc0d6ac9f65aa3e66af9) | init_main.c (9c8b8baa38c9a8135d7602f127cb0c735010837d) |
---|---|
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 --- 25 unchanged lines hidden (view full) --- 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 | 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 --- 25 unchanged lines hidden (view full) --- 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.122 1999/05/11 10:08:10 jb Exp $ | 42 * $Id: init_main.c,v 1.123 1999/06/30 15:33:32 peter Exp $ |
43 */ 44 45#include "opt_devfs.h" 46#include "opt_init_path.h" 47 48#include <sys/param.h> 49#include <sys/file.h> 50#include <sys/filedesc.h> 51#include <sys/kernel.h> 52#include <sys/mount.h> 53#include <sys/sysctl.h> 54#include <sys/proc.h> | 43 */ 44 45#include "opt_devfs.h" 46#include "opt_init_path.h" 47 48#include <sys/param.h> 49#include <sys/file.h> 50#include <sys/filedesc.h> 51#include <sys/kernel.h> 52#include <sys/mount.h> 53#include <sys/sysctl.h> 54#include <sys/proc.h> |
55#include <sys/kthread.h> |
|
55#include <sys/resourcevar.h> 56#include <sys/signalvar.h> 57#include <sys/systm.h> 58#include <sys/vnode.h> 59#include <sys/sysent.h> 60#include <sys/reboot.h> 61#include <sys/sysproto.h> 62#include <sys/vmmeter.h> --- 112 unchanged lines hidden (view full) --- 175void 176mi_startup(framep) 177 void *framep; 178{ 179 180 register struct sysinit **sipp; /* system initialization*/ 181 register struct sysinit **xipp; /* interior loop of sort*/ 182 register struct sysinit *save; /* bubble*/ | 56#include <sys/resourcevar.h> 57#include <sys/signalvar.h> 58#include <sys/systm.h> 59#include <sys/vnode.h> 60#include <sys/sysent.h> 61#include <sys/reboot.h> 62#include <sys/sysproto.h> 63#include <sys/vmmeter.h> --- 112 unchanged lines hidden (view full) --- 176void 177mi_startup(framep) 178 void *framep; 179{ 180 181 register struct sysinit **sipp; /* system initialization*/ 182 register struct sysinit **xipp; /* interior loop of sort*/ 183 register struct sysinit *save; /* bubble*/ |
183 struct proc *p2; | |
184 185 /* 186 * Copy the locore.s frame pointer for proc0, this is forked into 187 * all other processes. 188 */ 189 init_framep = framep; 190 191restart: --- 23 unchanged lines hidden (view full) --- 215 for (sipp = sysinit; *sipp; sipp++) { 216 217 if ((*sipp)->subsystem == SI_SUB_DUMMY) 218 continue; /* skip dummy task(s)*/ 219 220 if ((*sipp)->subsystem == SI_SUB_DONE) 221 continue; 222 | 184 185 /* 186 * Copy the locore.s frame pointer for proc0, this is forked into 187 * all other processes. 188 */ 189 init_framep = framep; 190 191restart: --- 23 unchanged lines hidden (view full) --- 215 for (sipp = sysinit; *sipp; sipp++) { 216 217 if ((*sipp)->subsystem == SI_SUB_DUMMY) 218 continue; /* skip dummy task(s)*/ 219 220 if ((*sipp)->subsystem == SI_SUB_DONE) 221 continue; 222 |
223 switch( (*sipp)->type) { 224 case SI_TYPE_DEFAULT: 225 /* no special processing*/ 226 (*((*sipp)->func))((*sipp)->udata); 227 break; | 223 /* Call function */ 224 (*((*sipp)->func))((*sipp)->udata); |
228 | 225 |
229 case SI_TYPE_KTHREAD: 230 /* kernel thread*/ 231 if (fork1(&proc0, RFMEM|RFFDG|RFPROC, &p2)) 232 panic("fork kernel thread"); 233 cpu_set_fork_handler(p2, (*sipp)->func, (*sipp)->udata); 234 break; 235 236 case SI_TYPE_KPROCESS: 237 if (fork1(&proc0, RFFDG|RFPROC, &p2)) 238 panic("fork kernel process"); 239 cpu_set_fork_handler(p2, (*sipp)->func, (*sipp)->udata); 240 break; 241 242 default: 243 panic("init_main: unrecognized init type"); 244 } 245 | |
246 /* Check off the one we're just done */ 247 (*sipp)->subsystem = SI_SUB_DONE; 248 249 /* Check if we've installed more sysinit items via KLD */ 250 if (newsysinit != NULL) { 251 if (sysinit != (struct sysinit **)sysinit_set.ls_items) 252 free(sysinit, M_TEMP); 253 sysinit = newsysinit; 254 newsysinit = NULL; 255 goto restart; 256 } 257 } 258 259 panic("Shouldn't get here!"); 260 /* NOTREACHED*/ 261} 262 263 264/* | 226 /* Check off the one we're just done */ 227 (*sipp)->subsystem = SI_SUB_DONE; 228 229 /* Check if we've installed more sysinit items via KLD */ 230 if (newsysinit != NULL) { 231 if (sysinit != (struct sysinit **)sysinit_set.ls_items) 232 free(sysinit, M_TEMP); 233 sysinit = newsysinit; 234 newsysinit = NULL; 235 goto restart; 236 } 237 } 238 239 panic("Shouldn't get here!"); 240 /* NOTREACHED*/ 241} 242 243 244/* |
265 * Start a kernel process. This is called after a fork() call in 266 * mi_startup() in the file kern/init_main.c. 267 * 268 * This function is used to start "internal" daemons. 269 */ 270/* ARGSUSED*/ 271void 272kproc_start(udata) 273 const void *udata; 274{ 275 const struct kproc_desc *kp = udata; 276 struct proc *p = curproc; 277 278#ifdef DIAGNOSTIC 279 printf("Start pid=%d <%s>\n",p->p_pid, kp->arg0); 280#endif 281 282 /* save a global descriptor, if desired*/ 283 if( kp->global_procpp != NULL) 284 *kp->global_procpp = p; 285 286 /* this is a non-swapped system process*/ 287 p->p_flag |= P_INMEM | P_SYSTEM; 288 289 /* set up arg0 for 'ps', et al*/ 290 strcpy( p->p_comm, kp->arg0); 291 292 /* call the processes' main()...*/ 293 (*kp->func)(); 294 295 /* NOTREACHED */ 296 panic("kproc_start: %s", kp->arg0); 297} 298 299 300/* | |
301 *************************************************************************** 302 **** 303 **** The following SYSINIT's belong elsewhere, but have not yet 304 **** been moved. 305 **** 306 *************************************************************************** 307 */ 308#ifdef OMIT --- 237 unchanged lines hidden (view full) --- 546 **** 547 **** 1) This code returns to startup the system; this is 548 **** abnormal for a kernel thread. 549 **** 2) This code promiscuously uses init_frame 550 **** 551 *************************************************************************** 552 */ 553 | 245 *************************************************************************** 246 **** 247 **** The following SYSINIT's belong elsewhere, but have not yet 248 **** been moved. 249 **** 250 *************************************************************************** 251 */ 252#ifdef OMIT --- 237 unchanged lines hidden (view full) --- 490 **** 491 **** 1) This code returns to startup the system; this is 492 **** abnormal for a kernel thread. 493 **** 2) This code promiscuously uses init_frame 494 **** 495 *************************************************************************** 496 */ 497 |
554static void kthread_init __P((const void *dummy)); 555SYSINIT_KP(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kthread_init, NULL) 556 557 | |
558extern void prepare_usermode __P((void)); | 498extern void prepare_usermode __P((void)); |
559static void start_init __P((struct proc *p)); | 499static void create_init __P((const void *dummy)); 500static void start_init __P((void *dummy)); 501SYSINIT(init,SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, create_init, NULL) |
560 | 502 |
561/* ARGSUSED*/ | 503/* 504 * Like kthread_create(), but runs in it's own address space. 505 */ |
562static void | 506static void |
563kthread_init(dummy) 564 const void *dummy; | 507create_init(udata) 508 const void *udata; |
565{ | 509{ |
566 /* Create process 1 (init(8)). */ 567 start_init(curproc); | 510 int error; |
568 | 511 |
569 prepare_usermode(); 570 571 /* 572 * This returns to the fork trampoline, then to user mode. 573 */ 574 return; | 512 error = fork1(&proc0, RFFDG | RFPROC, &initproc); 513 if (error) 514 panic("cannot fork init: %d\n", error); 515 initproc->p_flag |= P_INMEM | P_SYSTEM; 516 cpu_set_fork_handler(initproc, start_init, NULL); |
575} 576 | 517} 518 |
577 | |
578/* 579 * List of paths to try when searching for "init". 580 */ 581static char init_path[MAXPATHLEN] = 582#ifdef INIT_PATH 583 __XSTRING(INIT_PATH); 584#else 585 "/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall"; 586#endif 587SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0, ""); 588 589/* 590 * Start the initial user process; try exec'ing each pathname in init_path. 591 * The program is invoked with one argument containing the boot flags. 592 */ 593static void | 519/* 520 * List of paths to try when searching for "init". 521 */ 522static char init_path[MAXPATHLEN] = 523#ifdef INIT_PATH 524 __XSTRING(INIT_PATH); 525#else 526 "/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall"; 527#endif 528SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0, ""); 529 530/* 531 * Start the initial user process; try exec'ing each pathname in init_path. 532 * The program is invoked with one argument containing the boot flags. 533 */ 534static void |
594start_init(p) 595 struct proc *p; | 535start_init(dummy) 536 void *dummy; |
596{ 597 vm_offset_t addr; 598 struct execve_args args; 599 int options, error; 600 char *var, *path, *next, *s; 601 char *ucp, **uap, *arg0, *arg1; | 537{ 538 vm_offset_t addr; 539 struct execve_args args; 540 int options, error; 541 char *var, *path, *next, *s; 542 char *ucp, **uap, *arg0, *arg1; |
543 struct proc *p; |
|
602 | 544 |
603 initproc = p; | 545 p = curproc; |
604 605 /* 606 * Need just enough stack to hold the faked-up "execve()" arguments. 607 */ 608 addr = trunc_page(USRSTACK - PAGE_SIZE); 609 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, 610 FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) 611 panic("init: couldn't allocate argument space"); --- 64 unchanged lines hidden (view full) --- 676 args.fname = arg0; 677 args.argv = uap; 678 args.envv = NULL; 679 680 /* 681 * Now try to exec the program. If can't for any reason 682 * other than it doesn't exist, complain. 683 * | 546 547 /* 548 * Need just enough stack to hold the faked-up "execve()" arguments. 549 */ 550 addr = trunc_page(USRSTACK - PAGE_SIZE); 551 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE, 552 FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0) 553 panic("init: couldn't allocate argument space"); --- 64 unchanged lines hidden (view full) --- 618 args.fname = arg0; 619 args.argv = uap; 620 args.envv = NULL; 621 622 /* 623 * Now try to exec the program. If can't for any reason 624 * other than it doesn't exist, complain. 625 * |
684 * Otherwise return to mi_startup() which returns to btext 685 * which completes the system startup. | 626 * Otherwise, return via the fork trampoline all the way 627 * to user mode as init! |
686 */ | 628 */ |
687 if ((error = execve(p, &args)) == 0) | 629 if ((error = execve(p, &args)) == 0) { 630 prepare_usermode(); |
688 return; | 631 return; |
632 } |
|
689 if (error != ENOENT) 690 printf("exec %.*s: error %d\n", (int)(next - path), 691 path, error); 692 } 693 printf("init: not found\n"); 694 panic("no init"); 695} | 633 if (error != ENOENT) 634 printf("exec %.*s: error %d\n", (int)(next - path), 635 path, error); 636 } 637 printf("init: not found\n"); 638 panic("no init"); 639} |