It is our 15-th Lab and it is the time came to make birth of the process Eve, run Dis virtual machine and our first Limbo program!
First create file archrpi.c where we all R-Pi platform specific code. We need to implement kprocchild() call:
1static void
2linkproc(void)
3{
4 spllo();
5 if (waserror())
6 print("error() underflow: %r\n");
7 else (*up->kpfun)(up->arg);
8 pexit("end proc", 1);
9}
10
11void
12kprocchild(Proc *p, void (*func)(void*), void *arg)
13{
14 p->sched.pc = (ulong)linkproc;
15 p->sched.sp = (ulong)p->kstack+KSTACK-8;
16 p->kpfun = func;
17 p->arg = arg;
18}
As it is ready we just add initializations that are left to main.c:
1...
2trapinit();
3printinit();
4
5print("\nARM %ld MHz id %8.8lux\n", (m->cpuhz+500000)/1000000, getcpuid());
6print("Inferno OS %s Vita Nuova\n\n", VERSION);
7
8procinit();
9links();
10chandevreset();
11
12eve = strdup("inferno");
13
14userinit();
15schedinit();
16
17pl011_puts("to inifinite loop\n\n");
18for (;;);
Where our initialization of first process init0() and run first Dis program:
1void
2init0(void)
3{
4 Osenv *o;
5 char buf[2*KNAMELEN];
6
7 up->nerrlab = 0;
8
9 print("Starting init0()\n");
10 spllo();
11
12 if(waserror())
13 panic("init0 %r");
14
15 /* These are o.k. because rootinit is null.
16 * Then early kproc's will have a root and dot. */
17
18 o = up->env;
19 o->pgrp->slash = namec("#/", Atodir, 0, 0);
20 cnameclose(o->pgrp->slash->name);
21 o->pgrp->slash->name = newcname("/");
22 o->pgrp->dot = cclone(o->pgrp->slash);
23
24 chandevinit();
25
26 if(!waserror()){
27 ksetenv("cputype", "arm", 0);
28 snprint(buf, sizeof(buf), "arm %s", conffile);
29 ksetenv("terminal", buf, 0);
30 poperror();
31 }
32
33 poperror();
34
35 disinit("/osinit.dis");
36}
37
38void
39userinit(void)
40{
41 Proc *p;
42 Osenv *o;
43
44 p = newproc();
45 o = p->env;
46
47 o->fgrp = newfgrp(nil);
48 o->pgrp = newpgrp();
49 o->egrp = newegrp();
50 kstrdup(&o-;>user, eve);
51
52 strcpy(p->text, "interp");
53
54 p->fpstate = FPINIT;
55
56 /* Kernel Stack
57 N.B. The -12 for the stack pointer is important.
58 4 bytes for gotolabel's return PC */
59 p->sched.pc = (ulong)init0;
60 p->sched.sp = (ulong)p->kstack+KSTACK-8;
61
62 ready(p);
63}
Now go to folder ../init/ and create simple Limbo program rpiinit.b:
1implement Init;
2
3include "sys.m";
4 sys: Sys;
5
6Bootpreadlen: con 128;
7
8Init: module
9{
10 init: fn();
11};
12
13init()
14{
15 sys = load Sys Sys->PATH;
16 sys->print("Hey, this is Hello World from Dis!\n\n");
17}
Now edit platform definition file rpi, section init and section root to use rpiinit.b:
1...
2init
3 rpiinit
4
5root
6 /chan /
7 /dev /
8 /dis /
9 /env /
10 /fd /
11 /net /
12 /prog /
13 /dis/lib
14 /dis/disk
15 /osinit.dis
Compile, start Raspberry Pi device with expectations and:
Load address: 0x7fe0
Loading: T #T #####################################
done
Bytes transferred = 552620 (86eac hex)
## Starting application at 0x00008000 ...
Entered main() at 00009114 with SP=00002FE8
Clearing Mach: 00002000-00002060
Clearing edata: 00065B08-0006CC30
Conf: top=134217728, npage0=32659, ialloc=26750976, nproc=735
ARM 0 MHz id 410fb767
Inferno OS Fourth Edition (20121207) Vita Nuova
Starting init0()
Initial Dis: "/osinit.dis"
Hey, this is Hello World from Dis!
Wow, Success!
FILES: