- /*
- * Push the boot args onto the stack.
- * The initial value of the user stack must be such
- * that the total used is larger than the maximum size
- * of the argument list checked in syscall.
- */
- i = oargblen+1;
- p = UINT2PTR(STACKALIGN(base + BY2PG - sizeof(up->s.args) - i));
- memmove(p, oargb, i);
-
- /*
- * Now push argc and the argv pointers.
- * This isn't strictly correct as the code jumped to by
- * touser in init9.s calls startboot (port/initcode.c) which
- * expects arguments
- * startboot(char *argv0, char **argv)
- * not the usual (int argc, char* argv[]), but argv0 is
- * unused so it doesn't matter (at the moment...).
- */
- av = (char**)(p - (oargc+2)*sizeof(char*));
- ssize = base + BY2PG - PTR2UINT(av);
- *av++ = (char*)oargc;
- for(i = 0; i < oargc; i++)
- *av++ = (oargv[i] - oargb) + (p - base) + (USTKTOP - BY2PG);
- *av = nil;
-
- /*
- * Leave space for the return PC of the
- * caller of initcode.
- */
- sp = USTKTOP - ssize - sizeof(void*);
-}
-
-/*
- * create the first process
- */
-void
-userinit(void)
-{
- Proc *p;
- Segment *s;
- KMap *k;
- Page *pg;
-
- /* no processes yet */
- up = nil;
-
- p = newproc();
- p->pgrp = newpgrp();
- p->egrp = smalloc(sizeof(Egrp));
- p->egrp->ref = 1;
- p->fgrp = dupfgrp(nil);
- p->rgrp = newrgrp();
- p->procmode = 0640;
-
- kstrdup(&eve, "");
- kstrdup(&p->text, "*init*");
- kstrdup(&p->user, eve);
-
- /*
- * Kernel Stack
- */
- p->sched.pc = PTR2UINT(init0);
- p->sched.sp = PTR2UINT(p->kstack+KSTACK-sizeof(up->s.args)-sizeof(uintptr));
- p->sched.sp = STACKALIGN(p->sched.sp);
-
- /*
- * User Stack
- *
- * Technically, newpage can't be called here because it
- * should only be called when in a user context as it may
- * try to sleep if there are no pages available, but that
- * shouldn't be the case here.
- */
- s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG);
- s->flushme++;
- p->seg[SSEG] = s;
- pg = newpage(1, 0, USTKTOP-BY2PG);
- segpage(s, pg);
- k = kmap(pg);
- bootargs(VA(k));
- kunmap(k);
-
- /*
- * Text
- */
- s = newseg(SG_TEXT, UTZERO, 1);
- p->seg[TSEG] = s;
- pg = newpage(1, 0, UTZERO);
- memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));
- segpage(s, pg);
- k = kmap(s->map[0]->pages[0]);
- memmove(UINT2PTR(VA(k)), initcode, sizeof initcode);
- kunmap(k);
-
- ready(p);