FreeBSD/Linux Kernel Cross Reference
sys/kern/init_main.c
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 */
43
44 #include <sys/cdefs.h>
45 __FBSDID("$FreeBSD$");
46
47 #include "opt_ddb.h"
48 #include "opt_init_path.h"
49 #include "opt_mac.h"
50
51 #include <sys/param.h>
52 #include <sys/kernel.h>
53 #include <sys/exec.h>
54 #include <sys/file.h>
55 #include <sys/filedesc.h>
56 #include <sys/ktr.h>
57 #include <sys/lock.h>
58 #include <sys/mount.h>
59 #include <sys/mutex.h>
60 #include <sys/syscallsubr.h>
61 #include <sys/sysctl.h>
62 #include <sys/proc.h>
63 #include <sys/resourcevar.h>
64 #include <sys/systm.h>
65 #include <sys/signalvar.h>
66 #include <sys/vnode.h>
67 #include <sys/sysent.h>
68 #include <sys/reboot.h>
69 #include <sys/sched.h>
70 #include <sys/sx.h>
71 #include <sys/sysproto.h>
72 #include <sys/vmmeter.h>
73 #include <sys/unistd.h>
74 #include <sys/malloc.h>
75 #include <sys/conf.h>
76
77 #include <machine/cpu.h>
78
79 #include <security/audit/audit.h>
80 #include <security/mac/mac_framework.h>
81
82 #include <vm/vm.h>
83 #include <vm/vm_param.h>
84 #include <vm/pmap.h>
85 #include <vm/vm_map.h>
86 #include <sys/copyright.h>
87
88 #include <ddb/ddb.h>
89 #include <ddb/db_sym.h>
90
91 void mi_startup(void); /* Should be elsewhere */
92
93 /* Components of the first process -- never freed. */
94 static struct session session0;
95 static struct pgrp pgrp0;
96 struct proc proc0;
97 struct thread thread0 __aligned(16);
98 struct vmspace vmspace0;
99 struct proc *initproc;
100
101 int boothowto = 0; /* initialized so that it can be patched */
102 SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0, "");
103 int bootverbose;
104 SYSCTL_INT(_debug, OID_AUTO, bootverbose, CTLFLAG_RW, &bootverbose, 0, "");
105
106 /*
107 * This ensures that there is at least one entry so that the sysinit_set
108 * symbol is not undefined. A sybsystem ID of SI_SUB_DUMMY is never
109 * executed.
110 */
111 SYSINIT(placeholder, SI_SUB_DUMMY, SI_ORDER_ANY, NULL, NULL)
112
113 /*
114 * The sysinit table itself. Items are checked off as the are run.
115 * If we want to register new sysinit types, add them to newsysinit.
116 */
117 SET_DECLARE(sysinit_set, struct sysinit);
118 struct sysinit **sysinit, **sysinit_end;
119 struct sysinit **newsysinit, **newsysinit_end;
120
121 /*
122 * Merge a new sysinit set into the current set, reallocating it if
123 * necessary. This can only be called after malloc is running.
124 */
125 void
126 sysinit_add(struct sysinit **set, struct sysinit **set_end)
127 {
128 struct sysinit **newset;
129 struct sysinit **sipp;
130 struct sysinit **xipp;
131 int count;
132
133 count = set_end - set;
134 if (newsysinit)
135 count += newsysinit_end - newsysinit;
136 else
137 count += sysinit_end - sysinit;
138 newset = malloc(count * sizeof(*sipp), M_TEMP, M_NOWAIT);
139 if (newset == NULL)
140 panic("cannot malloc for sysinit");
141 xipp = newset;
142 if (newsysinit)
143 for (sipp = newsysinit; sipp < newsysinit_end; sipp++)
144 *xipp++ = *sipp;
145 else
146 for (sipp = sysinit; sipp < sysinit_end; sipp++)
147 *xipp++ = *sipp;
148 for (sipp = set; sipp < set_end; sipp++)
149 *xipp++ = *sipp;
150 if (newsysinit)
151 free(newsysinit, M_TEMP);
152 newsysinit = newset;
153 newsysinit_end = newset + count;
154 }
155
156 /*
157 * System startup; initialize the world, create process 0, mount root
158 * filesystem, and fork to create init and pagedaemon. Most of the
159 * hard work is done in the lower-level initialization routines including
160 * startup(), which does memory initialization and autoconfiguration.
161 *
162 * This allows simple addition of new kernel subsystems that require
163 * boot time initialization. It also allows substitution of subsystem
164 * (for instance, a scheduler, kernel profiler, or VM system) by object
165 * module. Finally, it allows for optional "kernel threads".
166 */
167 void
168 mi_startup(void)
169 {
170
171 register struct sysinit **sipp; /* system initialization*/
172 register struct sysinit **xipp; /* interior loop of sort*/
173 register struct sysinit *save; /* bubble*/
174
175 #if defined(VERBOSE_SYSINIT)
176 int last;
177 int verbose;
178 #endif
179
180 if (sysinit == NULL) {
181 sysinit = SET_BEGIN(sysinit_set);
182 sysinit_end = SET_LIMIT(sysinit_set);
183 }
184
185 restart:
186 /*
187 * Perform a bubble sort of the system initialization objects by
188 * their subsystem (primary key) and order (secondary key).
189 */
190 for (sipp = sysinit; sipp < sysinit_end; sipp++) {
191 for (xipp = sipp + 1; xipp < sysinit_end; xipp++) {
192 if ((*sipp)->subsystem < (*xipp)->subsystem ||
193 ((*sipp)->subsystem == (*xipp)->subsystem &&
194 (*sipp)->order <= (*xipp)->order))
195 continue; /* skip*/
196 save = *sipp;
197 *sipp = *xipp;
198 *xipp = save;
199 }
200 }
201
202 #if defined(VERBOSE_SYSINIT)
203 last = SI_SUB_COPYRIGHT;
204 verbose = 0;
205 #if !defined(DDB)
206 printf("VERBOSE_SYSINIT: DDB not enabled, symbol lookups disabled.\n");
207 #endif
208 #endif
209
210 /*
211 * Traverse the (now) ordered list of system initialization tasks.
212 * Perform each task, and continue on to the next task.
213 *
214 * The last item on the list is expected to be the scheduler,
215 * which will not return.
216 */
217 for (sipp = sysinit; sipp < sysinit_end; sipp++) {
218
219 if ((*sipp)->subsystem == SI_SUB_DUMMY)
220 continue; /* skip dummy task(s)*/
221
222 if ((*sipp)->subsystem == SI_SUB_DONE)
223 continue;
224
225 #if defined(VERBOSE_SYSINIT)
226 if ((*sipp)->subsystem > last) {
227 verbose = 1;
228 last = (*sipp)->subsystem;
229 printf("subsystem %x\n", last);
230 }
231 if (verbose) {
232 #if defined(DDB)
233 const char *name;
234 c_db_sym_t sym;
235 db_expr_t offset;
236
237 sym = db_search_symbol((vm_offset_t)(*sipp)->func,
238 DB_STGY_PROC, &offset);
239 db_symbol_values(sym, &name, NULL);
240 if (name != NULL)
241 printf(" %s(%p)... ", name, (*sipp)->udata);
242 else
243 #endif
244 printf(" %p(%p)... ", (*sipp)->func,
245 (*sipp)->udata);
246 }
247 #endif
248
249 /* Call function */
250 (*((*sipp)->func))((*sipp)->udata);
251
252 #if defined(VERBOSE_SYSINIT)
253 if (verbose)
254 printf("done.\n");
255 #endif
256
257 /* Check off the one we're just done */
258 (*sipp)->subsystem = SI_SUB_DONE;
259
260 /* Check if we've installed more sysinit items via KLD */
261 if (newsysinit != NULL) {
262 if (sysinit != SET_BEGIN(sysinit_set))
263 free(sysinit, M_TEMP);
264 sysinit = newsysinit;
265 sysinit_end = newsysinit_end;
266 newsysinit = NULL;
267 newsysinit_end = NULL;
268 goto restart;
269 }
270 }
271
272 panic("Shouldn't get here!");
273 /* NOTREACHED*/
274 }
275
276
277 /*
278 ***************************************************************************
279 ****
280 **** The following SYSINIT's belong elsewhere, but have not yet
281 **** been moved.
282 ****
283 ***************************************************************************
284 */
285 static void
286 print_caddr_t(void *data __unused)
287 {
288 printf("%s", (char *)data);
289 }
290 SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
291 SYSINIT(trademark, SI_SUB_COPYRIGHT, SI_ORDER_SECOND, print_caddr_t, trademark)
292 SYSINIT(version, SI_SUB_COPYRIGHT, SI_ORDER_THIRD, print_caddr_t, version)
293
294 #ifdef WITNESS
295 static char wit_warn[] =
296 "WARNING: WITNESS option enabled, expect reduced performance.\n";
297 SYSINIT(witwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1,
298 print_caddr_t, wit_warn)
299 SYSINIT(witwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 1,
300 print_caddr_t, wit_warn)
301 #endif
302
303 #ifdef DIAGNOSTIC
304 static char diag_warn[] =
305 "WARNING: DIAGNOSTIC option enabled, expect reduced performance.\n";
306 SYSINIT(diagwarn, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 2,
307 print_caddr_t, diag_warn)
308 SYSINIT(diagwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 2,
309 print_caddr_t, diag_warn)
310 #endif
311
312 static void
313 set_boot_verbose(void *data __unused)
314 {
315
316 if (boothowto & RB_VERBOSE)
317 bootverbose++;
318 }
319 SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL)
320
321 struct sysentvec null_sysvec = {
322 0,
323 NULL,
324 0,
325 0,
326 NULL,
327 0,
328 NULL,
329 NULL,
330 NULL,
331 NULL,
332 NULL,
333 NULL,
334 NULL,
335 "null",
336 NULL,
337 NULL,
338 0,
339 PAGE_SIZE,
340 VM_MIN_ADDRESS,
341 VM_MAXUSER_ADDRESS,
342 USRSTACK,
343 PS_STRINGS,
344 VM_PROT_ALL,
345 NULL,
346 NULL,
347 NULL
348 };
349
350 /*
351 ***************************************************************************
352 ****
353 **** The two following SYSINIT's are proc0 specific glue code. I am not
354 **** convinced that they can not be safely combined, but their order of
355 **** operation has been maintained as the same as the original init_main.c
356 **** for right now.
357 ****
358 **** These probably belong in init_proc.c or kern_proc.c, since they
359 **** deal with proc0 (the fork template process).
360 ****
361 ***************************************************************************
362 */
363 /* ARGSUSED*/
364 static void
365 proc0_init(void *dummy __unused)
366 {
367 struct proc *p;
368 unsigned i;
369 struct thread *td;
370
371 GIANT_REQUIRED;
372 p = &proc0;
373 td = &thread0;
374
375 /*
376 * Initialize magic number and osrel.
377 */
378 p->p_magic = P_MAGIC;
379 p->p_osrel = osreldate;
380
381 /*
382 * Initialize thread and process structures.
383 */
384 procinit(); /* set up proc zone */
385 threadinit(); /* set up UMA zones */
386
387 /*
388 * Initialise scheduler resources.
389 * Add scheduler specific parts to proc, thread as needed.
390 */
391 schedinit(); /* scheduler gets its house in order */
392 /*
393 * Initialize sleep queue hash table
394 */
395 sleepinit();
396
397 /*
398 * additional VM structures
399 */
400 vm_init2();
401
402 /*
403 * Create process 0 (the swapper).
404 */
405 LIST_INSERT_HEAD(&allproc, p, p_list);
406 LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
407 mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK);
408 p->p_pgrp = &pgrp0;
409 LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
410 LIST_INIT(&pgrp0.pg_members);
411 LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
412
413 pgrp0.pg_session = &session0;
414 mtx_init(&session0.s_mtx, "session", NULL, MTX_DEF);
415 session0.s_count = 1;
416 session0.s_leader = p;
417
418 p->p_sysent = &null_sysvec;
419 p->p_flag = P_SYSTEM | P_INMEM;
420 p->p_state = PRS_NORMAL;
421 knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL);
422 STAILQ_INIT(&p->p_ktr);
423 p->p_nice = NZERO;
424 td->td_state = TDS_RUNNING;
425 td->td_pri_class = PRI_TIMESHARE;
426 td->td_user_pri = PUSER;
427 td->td_base_user_pri = PUSER;
428 td->td_priority = PVM;
429 td->td_base_pri = PUSER;
430 td->td_oncpu = 0;
431 td->td_flags = TDF_INMEM;
432 p->p_peers = 0;
433 p->p_leader = p;
434
435
436 bcopy("swapper", p->p_comm, sizeof ("swapper"));
437
438 callout_init(&p->p_itcallout, CALLOUT_MPSAFE);
439 callout_init_mtx(&p->p_limco, &p->p_mtx, 0);
440 callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
441
442 /* Create credentials. */
443 p->p_ucred = crget();
444 p->p_ucred->cr_ngroups = 1; /* group 0 */
445 p->p_ucred->cr_uidinfo = uifind(0);
446 p->p_ucred->cr_ruidinfo = uifind(0);
447 p->p_ucred->cr_prison = NULL; /* Don't jail it. */
448 #ifdef AUDIT
449 audit_cred_kproc0(p->p_ucred);
450 #endif
451 #ifdef MAC
452 mac_create_proc0(p->p_ucred);
453 #endif
454 td->td_ucred = crhold(p->p_ucred);
455
456 /* Create sigacts. */
457 p->p_sigacts = sigacts_alloc();
458
459 /* Initialize signal state for process 0. */
460 siginit(&proc0);
461
462 /* Create the file descriptor table. */
463 p->p_fd = fdinit(NULL);
464 p->p_fdtol = NULL;
465
466 /* Create the limits structures. */
467 p->p_limit = lim_alloc();
468 for (i = 0; i < RLIM_NLIMITS; i++)
469 p->p_limit->pl_rlimit[i].rlim_cur =
470 p->p_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
471 p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_cur =
472 p->p_limit->pl_rlimit[RLIMIT_NOFILE].rlim_max = maxfiles;
473 p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_cur =
474 p->p_limit->pl_rlimit[RLIMIT_NPROC].rlim_max = maxproc;
475 i = ptoa(cnt.v_free_count);
476 p->p_limit->pl_rlimit[RLIMIT_RSS].rlim_max = i;
477 p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i;
478 p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3;
479 p->p_cpulimit = RLIM_INFINITY;
480
481 p->p_stats = pstats_alloc();
482
483 /* Allocate a prototype map so we have something to fork. */
484 pmap_pinit0(vmspace_pmap(&vmspace0));
485 p->p_vmspace = &vmspace0;
486 vmspace0.vm_refcnt = 1;
487 vm_map_init(&vmspace0.vm_map, p->p_sysent->sv_minuser,
488 p->p_sysent->sv_maxuser);
489 vmspace0.vm_map.pmap = vmspace_pmap(&vmspace0);
490 /*-
491 * call the init and ctor for the new thread and proc
492 * we wait to do this until all other structures
493 * are fairly sane.
494 */
495 EVENTHANDLER_INVOKE(process_init, p);
496 EVENTHANDLER_INVOKE(thread_init, td);
497 EVENTHANDLER_INVOKE(process_ctor, p);
498 EVENTHANDLER_INVOKE(thread_ctor, td);
499
500 /*
501 * Charge root for one process.
502 */
503 (void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
504 }
505 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL)
506
507 /* ARGSUSED*/
508 static void
509 proc0_post(void *dummy __unused)
510 {
511 struct timespec ts;
512 struct proc *p;
513 struct rusage ru;
514
515 /*
516 * Now we can look at the time, having had a chance to verify the
517 * time from the filesystem. Pretend that proc0 started now.
518 */
519 sx_slock(&allproc_lock);
520 FOREACH_PROC_IN_SYSTEM(p) {
521 microuptime(&p->p_stats->p_start);
522 PROC_SLOCK(p);
523 rufetch(p, &ru); /* Clears thread stats */
524 PROC_SUNLOCK(p);
525 p->p_rux.rux_runtime = 0;
526 p->p_rux.rux_uticks = 0;
527 p->p_rux.rux_sticks = 0;
528 p->p_rux.rux_iticks = 0;
529 }
530 sx_sunlock(&allproc_lock);
531 PCPU_SET(switchtime, cpu_ticks());
532 PCPU_SET(switchticks, ticks);
533
534 /*
535 * Give the ``random'' number generator a thump.
536 */
537 nanotime(&ts);
538 srandom(ts.tv_sec ^ ts.tv_nsec);
539 }
540 SYSINIT(p0post, SI_SUB_INTRINSIC_POST, SI_ORDER_FIRST, proc0_post, NULL)
541
542 /*
543 ***************************************************************************
544 ****
545 **** The following SYSINIT's and glue code should be moved to the
546 **** respective files on a per subsystem basis.
547 ****
548 ***************************************************************************
549 */
550
551
552 /*
553 ***************************************************************************
554 ****
555 **** The following code probably belongs in another file, like
556 **** kern/init_init.c.
557 ****
558 ***************************************************************************
559 */
560
561 /*
562 * List of paths to try when searching for "init".
563 */
564 static char init_path[MAXPATHLEN] =
565 #ifdef INIT_PATH
566 __XSTRING(INIT_PATH);
567 #else
568 "/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init:/stand/sysinstall";
569 #endif
570 SYSCTL_STRING(_kern, OID_AUTO, init_path, CTLFLAG_RD, init_path, 0,
571 "Path used to search the init process");
572
573 /*
574 * Shutdown timeout of init(8).
575 * Unused within kernel, but used to control init(8), hence do not remove.
576 */
577 #ifndef INIT_SHUTDOWN_TIMEOUT
578 #define INIT_SHUTDOWN_TIMEOUT 120
579 #endif
580 static int init_shutdown_timeout = INIT_SHUTDOWN_TIMEOUT;
581 SYSCTL_INT(_kern, OID_AUTO, init_shutdown_timeout,
582 CTLFLAG_RW, &init_shutdown_timeout, 0, "");
583
584 /*
585 * Start the initial user process; try exec'ing each pathname in init_path.
586 * The program is invoked with one argument containing the boot flags.
587 */
588 static void
589 start_init(void *dummy)
590 {
591 vm_offset_t addr;
592 struct execve_args args;
593 int options, error;
594 char *var, *path, *next, *s;
595 char *ucp, **uap, *arg0, *arg1;
596 struct thread *td;
597 struct proc *p;
598
599 mtx_lock(&Giant);
600
601 GIANT_REQUIRED;
602
603 td = curthread;
604 p = td->td_proc;
605
606 vfs_mountroot();
607
608 /*
609 * Need just enough stack to hold the faked-up "execve()" arguments.
610 */
611 addr = p->p_sysent->sv_usrstack - PAGE_SIZE;
612 if (vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr, PAGE_SIZE,
613 FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != 0)
614 panic("init: couldn't allocate argument space");
615 p->p_vmspace->vm_maxsaddr = (caddr_t)addr;
616 p->p_vmspace->vm_ssize = 1;
617
618 if ((var = getenv("init_path")) != NULL) {
619 strlcpy(init_path, var, sizeof(init_path));
620 freeenv(var);
621 }
622
623 for (path = init_path; *path != '\0'; path = next) {
624 while (*path == ':')
625 path++;
626 if (*path == '\0')
627 break;
628 for (next = path; *next != '\0' && *next != ':'; next++)
629 /* nothing */ ;
630 if (bootverbose)
631 printf("start_init: trying %.*s\n", (int)(next - path),
632 path);
633
634 /*
635 * Move out the boot flag argument.
636 */
637 options = 0;
638 ucp = (char *)p->p_sysent->sv_usrstack;
639 (void)subyte(--ucp, 0); /* trailing zero */
640 if (boothowto & RB_SINGLE) {
641 (void)subyte(--ucp, 's');
642 options = 1;
643 }
644 #ifdef notyet
645 if (boothowto & RB_FASTBOOT) {
646 (void)subyte(--ucp, 'f');
647 options = 1;
648 }
649 #endif
650
651 #ifdef BOOTCDROM
652 (void)subyte(--ucp, 'C');
653 options = 1;
654 #endif
655
656 if (options == 0)
657 (void)subyte(--ucp, '-');
658 (void)subyte(--ucp, '-'); /* leading hyphen */
659 arg1 = ucp;
660
661 /*
662 * Move out the file name (also arg 0).
663 */
664 (void)subyte(--ucp, 0);
665 for (s = next - 1; s >= path; s--)
666 (void)subyte(--ucp, *s);
667 arg0 = ucp;
668
669 /*
670 * Move out the arg pointers.
671 */
672 uap = (char **)((intptr_t)ucp & ~(sizeof(intptr_t)-1));
673 (void)suword((caddr_t)--uap, (long)0); /* terminator */
674 (void)suword((caddr_t)--uap, (long)(intptr_t)arg1);
675 (void)suword((caddr_t)--uap, (long)(intptr_t)arg0);
676
677 /*
678 * Point at the arguments.
679 */
680 args.fname = arg0;
681 args.argv = uap;
682 args.envv = NULL;
683
684 /*
685 * Now try to exec the program. If can't for any reason
686 * other than it doesn't exist, complain.
687 *
688 * Otherwise, return via fork_trampoline() all the way
689 * to user mode as init!
690 */
691 if ((error = execve(td, &args)) == 0) {
692 mtx_unlock(&Giant);
693 return;
694 }
695 if (error != ENOENT)
696 printf("exec %.*s: error %d\n", (int)(next - path),
697 path, error);
698 }
699 printf("init: not found in path %s\n", init_path);
700 panic("no init");
701 }
702
703 /*
704 * Like kthread_create(), but runs in it's own address space.
705 * We do this early to reserve pid 1.
706 *
707 * Note special case - do not make it runnable yet. Other work
708 * in progress will change this more.
709 */
710 static void
711 create_init(const void *udata __unused)
712 {
713 struct ucred *newcred, *oldcred;
714 int error;
715
716 error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc);
717 if (error)
718 panic("cannot fork init: %d\n", error);
719 KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
720 /* divorce init's credentials from the kernel's */
721 newcred = crget();
722 PROC_LOCK(initproc);
723 initproc->p_flag |= P_SYSTEM | P_INMEM;
724 oldcred = initproc->p_ucred;
725 crcopy(newcred, oldcred);
726 #ifdef MAC
727 mac_create_proc1(newcred);
728 #endif
729 #ifdef AUDIT
730 audit_cred_proc1(newcred);
731 #endif
732 initproc->p_ucred = newcred;
733 PROC_UNLOCK(initproc);
734 crfree(oldcred);
735 cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
736 cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
737 }
738 SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
739
740 /*
741 * Make it runnable now.
742 */
743 static void
744 kick_init(const void *udata __unused)
745 {
746 struct thread *td;
747
748 td = FIRST_THREAD_IN_PROC(initproc);
749 thread_lock(td);
750 TD_SET_CAN_RUN(td);
751 sched_add(td, SRQ_BORING);
752 thread_unlock(td);
753 }
754 SYSINIT(kickinit, SI_SUB_KTHREAD_INIT, SI_ORDER_FIRST, kick_init, NULL)
Cache object: ac9c1e82f674d9df1be7e0b68e6b1b43
|