Now it is lab 6 and it is time to compile “something” – kernel of inferno, but we are going to compile without worrying that it would not work (even would not link). We just need inferno kernel which can be compiled okay for R-Pi using a lot of stabs.
Files/Folders structure:
inferno-os/
|-os/
| |-rpi/
| | |-rpi
| | |-mkfile
| | |-load.s
| | |-main.c
mkfile:
1<../../mkconfig
2
3CONF=rpi
4CONFLIST=rpi
5loadaddr=0x00008000
6
7SYSTARG=$OSTARG
8OBJTYPE=arm
9INSTALLDIR=$ROOT/Inferno/$OBJTYPE/bin
10
11<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE
12
13<| $SHELLNAME ../port/mkdevlist $CONF
14
15OBJ=\
16 load.$O\
17 main.$O\
18 $IP\
19 $DEVS\
20 $ETHERS\
21 $LINKS\
22 $PORT\
23 $MISC\
24 $OTHERS\
25 $CONF.root.$O\
26
27LIBNAMES=${LIBS:%=lib%.a}
28LIBDIRS=$LIBS
29
30CFLAGS=-wFV -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp
31KERNDATE=`{$NDATE}
32
33default:V: i$CONF
34
35i$CONF: $OBJ $CONF.c $CONF.root.h $LIBNAMES
36 $CC $CFLAGS -DKERNDATE=$KERNDATE $CONF.c
37 $LD -l -o $target -R4 -T$loadaddr $OBJ $CONF.$O $LIBFILES
38
39<../port/portmkfile
40
41main.$O: $ROOT/Inferno/$OBJTYPE/include/ureg.h
rpi:
1dev
2 root
3 cons
4 env
5 mnt
6 pipe
7 prog
8 srv
9 dup
10
11lib
12 interp
13 math
14 kern
15 sec
16
17mod
18 math
19 sys
20
21port
22 alarm
23 alloc
24 allocb
25 chan
26 dev
27 dial
28 dis
29 discall
30 exception
31 exportfs
32 inferno
33 latin1
34 nocache
35 nodynld
36 parse
37 pgrp
38 print
39 proc
40 qio
41 qlock
42 random
43 sysfile
44 taslock
45 xalloc
46
47init
48 bootinit
49
50root
51 /chan /
52 /dev /
53 /dis /
54 /env /
55 /fd /
56 /net /
57 /prog /
58 /dis/lib
59 /dis/disk
Now if we try to compile with “mk” we will find fast that some header files are required:
# touch dat.h fns.h io.h mem.h
- fns.h - define signatures of required methods, also should include “../port/portfns.h”
- dat.h - kernel rpi specific data structures, also should include “../port/portdat.h”
- io.h - input/output defines and enums
- mem.h - defines related to our memory model
Also add the section for header files to “mkfile”:
1HFILES=\
2 mem.h\
3 dat.h\
4 fns.h\
5 io.h\
After mutiple times (well, not bazillion times) of change+compile+compare-with-ipaq1110/sa1110 we will reveal that minimal content of these header files is:
io.h:
--EMPTY--
fns.h:
1#define KADDR(p) ((void *)p)
2#define PADDR(p) ((ulong)p)
3
4int waserror();
5void (*screenputs)(char*, int);
6
7#include "../port/portfns.h"
mem.h:
1#define KiB 1024u /*! Kibi 0x0000000000000400 */
2#define MiB 1048576u /*! Mebi 0x0000000000100000 */
3#define GiB 1073741824u /*! Gibi 000000000040000000 */
4
5#define KZERO 0 /*! kernel address space */
6#define BY2PG (4*KiB) /*! bytes per page */
7#define BY2V 8 /*! only used in xalloc.c */
8#define MACHADDR (KZERO+0x2000) /*! Mach structure */
9#define ROUND(s,sz) (((s)+(sz-1))&~(sz-1))
10
11#define KSTKSIZE (8*KiB)
12#define KSTACK KSTKSIZE
dat.h:
1#define HZ (100) /*! clock frequency */
2#define MS2HZ (1000/HZ) /*! millisec per clock tick */
3#define TK2SEC(t) ((t)/HZ) /*! ticks to seconds */
4#define MS2TK(t) ((t)/MS2HZ) /*! milliseconds to ticks */
5
6#define MACHP(n) (n == 0 ? (Mach*)(MACHADDR) : (Mach*)0)
7
8typedef struct Lock Lock;
9typedef struct Ureg Ureg;
10typedef struct Label Label;
11typedef struct FPenv FPenv;
12typedef struct Mach Mach;
13typedef struct FPU FPU;
14typedef ulong Instr;
15typedef struct Conf Conf;
16
17struct Lock
18{
19 ulong key;
20 ulong sr;
21 ulong pc;
22 int pri;
23};
24
25struct Label
26{
27 int x;
28};
29
30enum /* FPenv.status */
31{
32 FPINIT,
33 FPACTIVE,
34 FPINACTIVE
35};
36
37struct FPenv
38{
39 int x;
40};
41
42struct FPU
43{
44 FPenv env;
45};
46
47struct Conf
48{
49 ulong nmach; /* processors */
50 ulong nproc; /* processes */
51 ulong npage0; /* total physical pages of memory */
52 ulong npage1; /* total physical pages of memory */
53 ulong base0; /* base of bank 0 */
54 ulong base1; /* base of bank 1 */
55 ulong ialloc; /* max interrupt time allocation in bytes */
56};
57
58#include "../port/portdat.h"
59
60struct Mach
61{
62 int machno; /* physical id of processor */
63 ulong ticks; /* of the clock since boot time */
64 Proc* proc; /* current process on this processor */
65 Label sched; /* scheduler wakeup */
66};
67
68extern Mach *m;
69extern Proc *up;
So, with this minimal “set” we already can compile all files of our inferno kernel, but of course we failed on the linking stage because we definitely need an implementation of referenced functions:
(2358) BL ,waserror+0(SB)
iprint: undefined: splhi
(2495) BL ,splhi+0(SB)
iprint: undefined: splx
(2502) BL ,splx+0(SB)
panic: undefined: setpanic
(2514) BL ,setpanic+0(SB)
panic: undefined: spllo
(2522) BL ,spllo+0(SB)
panic: undefined: dumpstack
(2523) BL ,dumpstack+0(SB)
panic: undefined: exit
(2525) BL ,exit+0(SB)
conswrite: undefined: reboot
(3391) BL ,reboot+0(SB)
conswrite: undefined: halt
(3394) BL ,halt+0(SB)
uartreset: undefined: addclock0link
(2106) BL.NE ,addclock0link+0(SB)
poolimmutable: undefined: getcallerpc
(2207) BL ,getcallerpc+0(SB)
too many errors
Anyway this is very good start to move to actual implementation of required routines to have our kernel linked and then we can retry our hello world example and move further to have some codes for the initialization stage.
ps: again this minimum set can be used as starting point for another arm boards with tweaking of mem.h for specifying addresses where if kernel is placed, kernel stack, etc.
FILES: