plan9fox/sys/src/9/port/userinit.c
cinap_lenrek 6f9838a6a5 kernel: make Page.txtflush into an array
To avoid a MAXMACH limit of 32 and make
txtflush into an array for the bitmap.

Provide portable macros for testing and clearing
the bits: needtxtflush(), donetxtflush().

On pc/pc64, define inittxtflush()/settxtflush()
as no-op macros, avoiding the storage overhead of
the txtflush array alltogether.
2022-01-16 19:25:11 +00:00

90 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);
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);
}