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