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}