89 lines
1.8 KiB
C
89 lines
1.8 KiB
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);
|
||
|
p->txtflush = ~0;
|
||
|
segpage(up->seg[TSEG], p);
|
||
|
up->seg[TSEG]->flushme++;
|
||
|
|
||
|
/*
|
||
|
* Become a user process.
|
||
|
*/
|
||
|
up->kp = 0;
|
||
|
up->noswap = 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);
|
||
|
}
|