ref: f6ac182f86bf0bcc777a76db50f94227ef6f7962
dir: /sys/src/9/port/userinit.c/
#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" /* * The initcode array contains the binary text of the first * user process. Its job is to invoke the exec system call * for /boot/boot. * Initcode does not link with standard plan9 libc _main() * trampoline due to size constrains. Instead it is linked * with a small machine specific trampoline init9.s that * only sets the base address register and passes arguments * to startboot() (see port/initcode.c). */ #include "initcode.i" /* * The first process kernel process starts here. */ static void proc0(void*) { KMap *k; Page *p; spllo(); up->pgrp = newpgrp(); up->egrp = smalloc(sizeof(Egrp)); up->egrp->ref = 1; up->fgrp = dupfgrp(nil); up->rgrp = newrgrp(); /* * These are o.k. because rootinit is null. * Then early kproc's will have a root and dot. */ up->slash = namec("#/", Atodir, 0, 0); pathclose(up->slash->path); up->slash->path = newpath("/"); up->dot = cclone(up->slash); /* * Setup Text and Stack segments for initcode. */ up->seg[SSEG] = newseg(SG_STACK | SG_NOEXEC, USTKTOP-USTKSIZE, USTKSIZE / BY2PG); up->seg[TSEG] = newseg(SG_TEXT | SG_RONLY, UTZERO, 1); p = newpage(1, 0, UTZERO); k = kmap(p); memmove((void*)VA(k), initcode, sizeof(initcode)); kunmap(k); settxtflush(p, 1); segpage(up->seg[TSEG], p); up->seg[TSEG]->flushme = 1; /* * Become a user process. */ up->kp = 0; up->noswap = 0; up->privatemem = 0; procpriority(up, PriNormal, 0); procsetup(up); flushmmu(); /* * init0(): * call chandevinit() * setup environment variables * prepare the stack for initcode * switch to usermode to run initcode */ init0(); /* init0 will never return */ panic("init0"); } void userinit(void) { up = nil; kstrdup(&eve, ""); kproc("*init*", proc0, nil); }