/*
* 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;
/*
* 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);
p->txtflush = ~0;
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();