]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/userinit.c
kernel: use 64-bit virtual entry point for expanded header, document behaviour in...
[plan9front.git] / sys / src / 9 / port / userinit.c
1 #include        "u.h"
2 #include        "../port/lib.h"
3 #include        "mem.h"
4 #include        "dat.h"
5 #include        "fns.h"
6 #include        "../port/error.h"
7
8 /*
9  * The initcode array contains the binary text of the first
10  * user process. Its job is to invoke the exec system call
11  * for /boot/boot.
12  * Initcode does not link with standard plan9 libc _main()
13  * trampoline due to size constrains. Instead it is linked
14  * with a small machine specific trampoline init9.s that
15  * only sets the base address register and passes arguments
16  * to startboot() (see port/initcode.c).
17  */
18 #include        "initcode.i"
19
20 /*
21  * The first process kernel process starts here.
22  */
23 static void
24 proc0(void*)
25 {
26         KMap *k;
27         Page *p;
28
29         spllo();
30
31         up->pgrp = newpgrp();
32         up->egrp = smalloc(sizeof(Egrp));
33         up->egrp->ref = 1;
34         up->fgrp = dupfgrp(nil);
35         up->rgrp = newrgrp();
36
37         /*
38          * These are o.k. because rootinit is null.
39          * Then early kproc's will have a root and dot.
40          */
41         up->slash = namec("#/", Atodir, 0, 0);
42         pathclose(up->slash->path);
43         up->slash->path = newpath("/");
44         up->dot = cclone(up->slash);
45
46         /*
47          * Setup Text and Stack segments for initcode.
48          */
49         up->seg[SSEG] = newseg(SG_STACK | SG_NOEXEC, USTKTOP-USTKSIZE, USTKSIZE / BY2PG);
50         up->seg[TSEG] = newseg(SG_TEXT | SG_RONLY, UTZERO, 1);
51         p = newpage(1, 0, UTZERO);
52         k = kmap(p);
53         memmove((void*)VA(k), initcode, sizeof(initcode));
54         kunmap(k);
55         p->txtflush = ~0;
56         segpage(up->seg[TSEG], p);
57         up->seg[TSEG]->flushme = 1;
58
59         /*
60          * Become a user process.
61          */
62         up->kp = 0;
63         up->noswap = 0;
64         up->privatemem = 0;
65         procpriority(up, PriNormal, 0);
66         procsetup(up);
67
68         flushmmu();
69
70         /*
71          * init0():
72          *      call chandevinit()
73          *      setup environment variables
74          *      prepare the stack for initcode
75          *      switch to usermode to run initcode
76          */
77         init0();
78
79         /* init0 will never return */
80         panic("init0");
81 }
82
83 void
84 userinit(void)
85 {
86         up = nil;
87         kstrdup(&eve, "");
88         kproc("*init*", proc0, nil);
89 }