Stage 3. Init inferno

The very second thing we should do right after blinking THE LED is string printing.

Substage 1. Enabling UART

Actually UART is already enabled for us by U-Boot. We will write some UART-related code and put it into uart.c and uart.h. The same code will be later used for OS needs.

uart.c:

#include <stdbool.h>
#include <stdint.h>

#include "LPC24xx.h"

#define PCLK_SEL0_UART0_11 (1<<6 | 1<<7)

#define PCONP_UART0 (1<<3)

#define PINSEL0_UART0_P02 (1<<4)
#define PINSEL0_UART0_P03 (1<<6)

#define UXLCR_BREAKCONTROL (1<<6)
#define UXLCR_DLAB         (1<<7)
#define UXFDR_DIVADDVAL(v) ((v << 0) & 0x0F)
#define UXFDR_MULVAL(v)    ((v<<4) & 0xF0)
#define UXFCR_FIFO         (1)
#define UXLSR_THRE         (1<<5)

void uart0_init (void) {
  PCONP |= PCONP_UART0;
  //leave clock by default
  PCLKSEL0 &= ~PCLK_SEL0_UART0_11;

  //enable dll/dlm regs
  U0LCR |= UXLCR_DLAB;

  // set baudrate
  U0DLM = 0;
  U0DLL = 5;
  U0FDR |= (UXFDR_DIVADDVAL(5) | UXFDR_MULVAL(9));

  // enable FIFO
  U0FCR |= UXFCR_FIFO;

  // set pins
  PINSEL0 |= (PINSEL0_UART0_P02 | PINSEL0_UART0_P03);

  // usnet DLAB
  U0LCR &= ~UXLCR_DLAB;
}

void uart0_putc(uint16_t c) {
  for (;;) {
    if (U0LSR & UXLSR_THRE) {
      break;
    }
  }
  U0THR = c & 0xFF;
}

bool uart0_txready(void) {
  if (U0LSR & UXLSR_THRE) {
    return true;
  }
  return false;
}

void uart0_puts(char *s) {
  int i = 0;
  while (s[i] != 0) {
    uart0_putc(s[i]);
    i++;
  }
}

void uart0_putn(char *s, int n) {
  int i = 0;
  for (; i<n; i++) {
    uart0_putc(s[i]);
  }
}

void uart0_itoa(unsigned int a)
{
    int i;
    unsigned char h,l;
  unsigned char *ca = (unsigned char *)&a;

    for (i=3;i>=0;--i) {
        h = (ca[i])/16;
        l = (ca[i])%16;
        uart0_putc(h<10 ? h+0x30 : h-10+0x41);
        uart0_putc(l<10 ? l+0x30 : l-10+0x41);
    }
}

void uart0_addr(void *a)
{
  uart0_itoa((uint32_t)a);
}

void uart0_setbreak(void) {
  U0LCR |= UXLCR_BREAKCONTROL;
}

void uart0_unsetbreak(void) {
  U0LCR &= ~UXLCR_BREAKCONTROL;
}

uart.h :

#ifndef __UART_H__
#define __UART_H__

#include <stdint.h>

void uart0_init (void);
void uart0_putc(uint16_t c);
bool uart0_txready(void);
void uart0_puts(char *s);
void uart0_putn(char *s, int n);
void uart0_itoa(unsigned int a);
void uart0_addr(void *a);
void uart0_setbreak(void);
void uart0_unsetbreak(void);

#endif/*__UART_H__*/

We can now print some message from our main procedure. Lets put that:

  uart0_puts("Inferno OS compiled by GCC\r\n");

After LED switching code in main. Oh, right, dont forget to update mkfile. Add new files there:

<../../mkconfig

CONF=lpc-e2468
CONFLIST=lpc-e2468

SYSTARG=Inferno
OBJTYPE=arm-gcc
INSTALLDIR=$ROOT/Inferno/$OBJTYPE/bin

<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE

<| $SHELLNAME ../port/mkdevlist $CONF

OBJ=\
    load.$O\
    main.$O\
    uart.$O\
    $IP\
    $DEVS\
    $ETHERS\
    $LINKS\
    $PORT\
    $MISC\
    $OTHERS\
    $CONF.root.$O\

LIBNAMES=${LIBS:%=lib%.a}
LIBDIRS=$LIBS
CP=arm-none-eabi-objcopy

CFLAGS= -mcpu=arm7tdmi-s -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp -I./ -DLINUX_ARM
KERNDATE=`{$NDATE}

HFILES=\
    uart.h\
    dat.h\
    mem.h\
    io.h\
    fns.h\
    LPC24xx.h

default:V: i$CONF

i$CONF: $OBJ $CONF.c $CONF.root.h $LIBNAMES
    $CC $CFLAGS -DKERNDATE=$KERNDATE $CONF.c
    $LD -mcpu=arm7tdmi-s  -nostartfiles -Wl,-Map=main.map,--cref,--gc-sections -Tlpc_e2468.ld $OBJ $CONF.$O $LIBFILES -lgcc -lm -o ilpc-e2468.elf
    $CP -O binary ilpc-e2468.elf ilpc-e2468.bin
    arm-none-eabi-size ./ilpc-e2468.elf

<../port/portmkfile

Here is the diff:

diff -r 857f33069dc2 os/lpc-e2468-olimex/mkfile
--- a/os/lpc-e2468-olimex/mkfile    Sun May 24 15:03:38 2015 +0300
+++ b/os/lpc-e2468-olimex/mkfile    Tue May 26 02:44:59 2015 +0300
@@ -14,6 +14,7 @@
 OBJ=\
     load.$O\
     main.$O\
+    uart.$O\
     $IP\
     $DEVS\
     $ETHERS\
@@ -30,7 +31,13 @@
 CFLAGS= -mcpu=arm7tdmi-s -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp -I./ -DLINUX_ARM
 KERNDATE=`{$NDATE}

-HFILES=
+HFILES=\
+    uart.h\
+    dat.h\
+    mem.h\
+    io.h\
+    fns.h\
+    LPC24xx.h

Go ahead and compile it:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk clean

...

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk

...

   arm-none-eabi-objcopy -O binary ilpc-e2468.elf ilpc-e2468.bin
   arm-none-eabi-size ./ilpc-e2468.elf
   text    data     bss     dec     hex filename
   1328       0       0    1328     530 ./ilpc-e2468.elf

Hooray, we have some binary to flash! Lets TFTP to check that this is working, so copy the binary to tftp directory, start TFTP server and restart your board:

Load address: 0xa0008000
Loading: T T T T T T T T T #
done
Bytes transferred = 1328 (530 hex)
## Starting application at 0xA0008000 ...
Inferno OS compiled by GCC

Now we have some way to debug our port by the means of printing. Not bad for a start.

Substage 2. Initing

Lets examine ipaq1110 main procedure:

void
main(void)
{
    memset(edata, 0, end-edata);        /* clear the BSS */
    memset(m, 0, sizeof(Mach)); /* clear the mach struct */
    conf.nmach = 1;
    archreset();
    dmareset();
    quotefmtinstall();
    confinit();
    xinit();
    mmuinit();
    poolinit();
    poolsizeinit();
    trapinit();
    clockinit(); 
    printinit();
    screeninit();
    procinit();
    links();
    chandevreset();

    eve = strdup("inferno");

    archconsole();
    kbdinit();

    print("%ld MHz id %8.8lux\n", (m->cpuhz+500000)/1000000, getcpuid());
    print("\nInferno %s\n", VERSION);
    print("Vita Nuova\n");
    print("conf %s (%lud) jit %d\n\n",conffile, kerndate, cflag);

    userinit();
    schedinit();
}

Looks like we have a bunch of initing ahead. Our goal for today is to get to print lines.

We dont have to clean the BSS, because this is already done in our load.s. Lets check what the structure is Mach. Open our own dat.h:

struct Mach
{
  ulong splpc; /* pc of last caller to splhi */
  int     machno;     /* physical id of processor */
  ulong   ticks;      /* of the clock since boot time */
  Proc*   proc;       /* current process on this processor */
  Label   sched;      /* scheduler wakeup */
  ulong cpuhz;

  /* stacks for exceptions */
  ulong   fiqstack[4];
  ulong   irqstack[4];
  ulong   abtstack[4];
  ulong   undstack[4];
  int   stack[1];
};

Ok, ipaq1110 has the following code in main.c:

Mach *m = (Mach*)MACHADDR;

MACHADDR is defined in ipaq1110/mem.h:

#define KZERO       0xC0000000
#define MACHADDR    (KZERO+0x00001000)

That looks understandable. Lets add the following to our own mem.h:

#define KZERO       0xa0008000              /*! kernel address space */
#define MACHADDR    (KZERO+0x00001000)          /*! Mach structure */

And alter main.c accordingly:

#include <stdbool.h>

#include "LPC24xx.h"

#include "u.h"
#include "../port/lib.h"
#include "dat.h"
#include "../port/portfns.h"
#include "../port/error.h"
#include "mem.h"

#include "uart.h"

#define STAT_LED1 (1<<17) //red
#define STAT_LED2 (1<<16) //green
#define STAT_LED1_PS9_bits (1<<2 | 1<<3)
#define STAT_LED2_PS9_bits (1 | 1<<1)
#define STAT_LED1_PM9_bits (1<<2 | 1<<3)
#define STAT_LED2_PM9_bits (1 | 1<<1)

Mach *m = (Mach*)MACHADDR;

int main(void) {
  PINSEL9 &= ~(STAT_LED1_PS9_bits | STAT_LED2_PS9_bits); //make sure pin configuration is in default state
  PINMODE9 &= ~(STAT_LED1_PM9_bits | STAT_LED2_PM9_bits);

  FIO4MASK &= ~(STAT_LED1 | STAT_LED2);
  FIO4DIR |= (STAT_LED1 | STAT_LED2);
  FIO4CLR |= STAT_LED1; // turn on the red
  FIO4SET |= STAT_LED2; //turn off the green

  uart0_puts("Inferno OS compiled by GCC\r\n");

  memset(m, 0, sizeof(Mach));   /* clear the mach struct */
  uart0_puts("memset Mach\r\n");

  while(true) {

  }
  return 0;
}

Compile and run, the message should be printed:

Bytes transferred = 1636 (664 hex)
## Starting application at 0xA0008000 ...
Inferno OS compiled by GCC
memset Mach

Thats good, first step in real OS loading is complete =)

Substage 3. ARCHRESET

Grepping for archreset gives that:

inferno-os-lpc2468/os/lpc-e2468-olimex$ grep archreset ../ -R
../cerf250/fns.h:void   archreset(void);
../cerf250/archcerf.c:archreset(void)
../cerf250/main.c:  archreset();
../cerf1110/fns.h:void  archreset(void);
../cerf1110/archcerf.c:archreset(void)
../cerf1110/main.c: archreset();
../ks32/fns.h:void  archreset(void);
../ks32/main.c: archreset();
../ks32/archevaluator7t.c:archreset(void)
../manga/fns.h:void archreset(void);
../manga/archmanga.c:archreset(void)
../manga/main.c:    archreset();
../ipengine/fns.h:void  archresetvideo(void);
../ipaq1110/fns.h:void  archreset(void);
../ipaq1110/archipaq.c:archreset(void)
../ipaq1110/main.c: archreset();
../cerf405/fns.h:void   archresetvideo(void);
../rpcg/fns.h:void  archresetvideo(void);
../fads/fns.h:void  archresetvideo(void);
../fads/archfads.c:archresetvideo(void)

Looks like port-related procedure. Lets check ipaq1110's archreset:

void
archreset(void)
{
    GpioReg *g;
    PpcReg *p;

    g = GPIOREG;
    g->grer = 0;
    g->gfer = 0;
    g->gedr = g->gedr;
    g->gpcr = ~0;
    g->gpdr = GPIO_CLK_SET0_o | GPIO_CLK_SET1_o;    // | GPIO_LDD8_15_o;
    g->gafr |= GPIO_SYS_CLK_i;  // | GPIO_LDD8_15_o;
    p = PPCREG;
    p->ppdr |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;  /* not sure about PPC_TXD4 here */
    p->ppsr &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);

    archuartpower(3, 1);    /* allow console to work sooner rather than later */
    L3init();

Thats pretty much what we have done before! I propose to follow the way of ipaq1110 and create archlpc2468.c file:

#include <stdbool.h>
#include "uart.h"
#include "LPC24xx.h"

#define STAT_LED1 (1<<17) //red
#define STAT_LED2 (1<<16) //green
#define STAT_LED1_PS9_bits (1<<2 | 1<<3)
#define STAT_LED2_PS9_bits (1 | 1<<1)
#define STAT_LED1_PM9_bits (1<<2 | 1<<3)
#define STAT_LED2_PM9_bits (1 | 1<<1)

void
archreset(void) {
  PINSEL9 &= ~(STAT_LED1_PS9_bits | STAT_LED2_PS9_bits); //make sure pin configuration is in default state
  PINMODE9 &= ~(STAT_LED1_PM9_bits | STAT_LED2_PM9_bits);

  FIO4MASK &= ~(STAT_LED1 | STAT_LED2);
  FIO4DIR |= (STAT_LED1 | STAT_LED2);
  FIO4CLR |= STAT_LED1; // turn on the red
  FIO4SET |= STAT_LED2; //turn off the green

  uart0_puts("Inferno OS compiled by GCC\r\n");
}

Also dont forget to add archreset definition to fns.h:

#include "../port/portfns.h"

void    archreset(void);

Notice that I've added portfns.h include in fns.h file, so it can be removed from main.c. So now our main.c looks the following way:

#include <stdbool.h>

#include "u.h"
#include "../port/lib.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "mem.h"

#include "uart.h"

Mach *m = (Mach*)MACHADDR;

int main(void) {
  memset(m, 0, sizeof(Mach));   /* clear the mach struct */
  conf.nmach = 1;
  uart0_puts("memset Mach\r\n");
  archreset();
  uart0_puts("archreset\r\n");

  while(true) {

  }
  return 0;
}

Before we can try to build, we should add archlpc2468.c to the mkfile.

diff:

 OBJ=\
     load.$O\
     main.$O\
     uart.$O\
+    archlpc2468.$O\
     $IP\
     $DEVS\
     $ETHERS\

The build fails with:

main.o: In function `main':
main.c:(.text+0x48): undefined reference to `conf'
collect2: error: ld returned 1 exit status
mk:    ...  : exit status=exit(1)

Oops. This was copypasted from ipaq1110 without proper additions. The fixed makefile looks like this:

#include <stdbool.h>

#include "u.h"
#include "../port/lib.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "mem.h"

#include "uart.h"

Mach *m = (Mach*)MACHADDR;
Conf conf;

int main(void) {
  memset(m, 0, sizeof(Mach));   /* clear the mach struct */
  conf.nmach = 1;
  uart0_puts("memset Mach\r\n");
  archreset();
  uart0_puts("archreset\r\n");

  while(true) {

  }
  return 0;
}

Compile and run, then check on device:

Bytes transferred = 1716 (6b4 hex)
## Starting application at 0xA0008000 ...
memset Mach
Inferno OS compiled by GCC
archreset

Lets assume archreset finished.

Substage 4. DMARESET

Not quite sure what to reset here. Lets just add the difinition to fns.h:

#include "../port/portfns.h"

void archreset(void);
void dmareset(void);

Substage 5. QUOTEFMTINSTALL

Grepping this procedure shows that it is not port-specific. Conveniently all the inner implementations of various procedures are written in the following format in Inferno:

type
procname(blah)

So to find the function implementation you just have to grep ^procname.

inferno-os-lpc2468/os/lpc-e2468-olimex$ grep ^quotefmtinstall ../../ -R
../../lib9/fmtquote.c:quotefmtinstall(void)
../../libkern/fmtquote.c:quotefmtinstall(void)

So this is something OS-specific. Lets try to add the call to this procedure and pray.

/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libkern.a(fmt.o): In function `fmtinstall':
fmt.c:(.text+0x28): undefined reference to `_fmtlock'
fmt.c:(.text+0x90): undefined reference to `_fmtunlock'
fmt.c:(.text+0xc0): undefined reference to `_fmtunlock'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libkern.a(fmt.o):(.data+0x8c): undefined reference to `errfmt'
collect2: error: ld returned 1 exit status
mk:    ...  : exit status=exit(1)

Hm.. lets find where _fmtlock is defined:

inferno-os-lpc2468/os/lpc-e2468-olimex$ grep _fmtlock ../ -R
../port/print.c:_fmtlock(void)
../boot/pc/print.c:_fmtlock(void)

Add these lines to lpc-e2468:

port
  print

So that it looks this way:

dev

port
  print

code

lib
    kern

init
    bootinit

root
  /dev  /

Lets try to build:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
arm-none-eabi-gcc -c -x assembler-with-cpp -mcpu=arm7tdmi-s -c load.s
arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM main.c
arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM uart.c
arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM archlpc2468.c
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/print.c
../port/print.c: In function '_efgfmt':
../port/print.c:22:1: error: parameter name omitted
 _efgfmt(Fmt*)
 ^
../port/print.c: In function 'errfmt':
../port/print.c:28:1: error: parameter name omitted
 errfmt(Fmt*)
 ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

What? again!? Ok, at least we know how to fix that.

diff -r 857f33069dc2 os/port/print.c
--- a/os/port/print.c   Sun May 24 15:03:38 2015 +0300
+++ b/os/port/print.c   Wed May 27 02:43:33 2015 +0300
@@ -19,13 +19,13 @@
 }

 int
-_efgfmt(Fmt*)
+_efgfmt(Fmt* f)
 {
    return -1;
 }

 int
-errfmt(Fmt*)
+errfmt(Fmt* f)
 {
    return -1;
 }

The attempt to rebuild fails again:

   arm-none-eabi-objcopy -O binary ilpc-e2468.elf ilpc-e2468.bin
   arm-none-eabi-size ./ilpc-e2468.elf
print.o: In function `_fmtlock':
print.c:(.text+0xc): undefined reference to `lock'
print.o: In function `_fmtunlock':
print.c:(.text+0x2c): undefined reference to `unlock'
collect2: error: ld returned 1 exit status
mk:    ...  : exit status=exit(1)

Grep for lock:

inferno-os-lpc2468/os/lpc-e2468-olimex$ grep ^lock ../ -R
../lpc-e2468-olimex/main.map:lock                                              print.o
../port/taslock.c:lockloop(Lock *l, ulong pc)
../port/taslock.c:lock(Lock *l)

Lets add taslock to port section of lpc-2468:

port
  print
  taslock

This fails with:

   arm-none-eabi-objcopy -O binary ilpc-e2468.elf ilpc-e2468.bin
   arm-none-eabi-size ./ilpc-e2468.elf
taslock.o: In function `lockloop':
taslock.c:(.text+0x14): undefined reference to `setpanic'
taslock.c:(.text+0x3c): undefined reference to `print'
taslock.c:(.text+0x44): undefined reference to `panic'
taslock.o: In function `lock':
taslock.c:(.text+0x74): undefined reference to `getcallerpc'
taslock.c:(.text+0x94): undefined reference to `_tas'
taslock.c:(.text+0xb4): undefined reference to `_tas'
taslock.c:(.text+0x11c): undefined reference to `_tas'
taslock.c:(.text+0x174): undefined reference to `islo'
taslock.c:(.text+0x194): undefined reference to `sched'
taslock.c:(.text+0x1e4): undefined reference to `up'
taslock.o: In function `ilock':
taslock.c:(.text+0x208): undefined reference to `getcallerpc'
taslock.c:(.text+0x210): undefined reference to `splhi'
taslock.c:(.text+0x224): undefined reference to `_tas'
taslock.c:(.text+0x274): undefined reference to `panic'
taslock.c:(.text+0x294): undefined reference to `clockcheck'
taslock.o: In function `canlock':
taslock.c:(.text+0x300): undefined reference to `_tas'
taslock.c:(.text+0x358): undefined reference to `getcallerpc'
taslock.c:(.text+0x378): undefined reference to `up'
taslock.o: In function `unlock':
taslock.c:(.text+0x3a4): undefined reference to `getcallerpc'
taslock.c:(.text+0x3b4): undefined reference to `print'
taslock.c:(.text+0x3dc): undefined reference to `coherence'
taslock.c:(.text+0x414): undefined reference to `anyhigher'
taslock.c:(.text+0x424): undefined reference to `sched'
taslock.c:(.text+0x438): undefined reference to `up'
taslock.o: In function `iunlock':
taslock.c:(.text+0x464): undefined reference to `getcallerpc'
taslock.c:(.text+0x474): undefined reference to `print'
taslock.c:(.text+0x49c): undefined reference to `coherence'
taslock.c:(.text+0x4a8): undefined reference to `splxpc'
collect2: error: ld returned 1 exit status
mk:    ...  : exit status=exit(1)

Which means we should add more entries to port section.

Checking of these undefined references one by one:

  • setpanic - should be defined in our port
  • print, panic - are defined in os/port/devcons.c
  • getcallerpc, _tas, islo - should be defined in our port
  • sched - is defined in os/port/proc.c
  • up, splhi, clockcheck. coherence - should be defined in our port
  • anyhigher - is defined in os/port/proc.c
  • splxpc - should be defined in our port

  • Lets go on and define setpanic in a new file os/lpc-e2468-olimex/main.c:

void
setpanic(void) {
  uart0_puts("Infernal panic\r\n");
  while (1);
}
  1. add devcons to port section in lpc-e2468:
dev

port
  print
  taslock
  devcons

code

lib
    kern

init
    bootinit

root
  /dev  /

3.1 define getcallerpc in port.s:

.global getcallerpc

getcallerpc:
       MOV r0, sp
       MOV pc, lr

Don't forget to add port.s to mkfile:

+++ b/os/lpc-e2468-olimex/mkfile    Sun May 31 01:44:02 2015 +0300
@@ -14,6 +14,9 @@
 OBJ=\
     load.$O\
     main.$O\
     uart.$O\
     archlpc2468.$O\
+    port.$O\
     $IP\
     $DEVS\
     $ETHERS\

3.2 define _tas in main.c:

uint32_t
__swp(uint32_t x, volatile uint32_t *p) {
  uint32_t ret;
  __asm__ __volatile__ (
    "swp %[ret], %[x], [%[m]]\n"
    : [ret] "=&r" (ret)
    : [m] "r" (p), [x] "r" (x)
    );
  return ret;
}

ulong
_tas(ulong* u) {
  return __swp(0xDEADDEAD, u);
}

On a more modern ARM processors swp instruction is deprecated, but out processor still has it, so we use it.

3.3 define islo:

int
islo(void) {
  register uint32_t ret;
  uint32_t val = PsrDirq;

  __asm__ __volatile__
  (
    "mrs %[r0], CPSR\n\t"
    "and %[r0], %[val]\n\t"
    "eor %[r0], %[val]\n\t"
    : [r0] "=r"(ret)
    : [val] "r" (val)
  );

  return ret;
}
  1. add proc module to port section in lpc-e2468:
dev

port
  print
  taslock
  devcons
  port

code

lib
    kern

init
    bootinit

root
  /dev  /

5.1 define up.

up is actually not a procedure. but global variable. Add the following before main procedure in main.c

Proc *up = 0;

5.2 define splhi:

int
splhi(void) { 
  register uint32_t ret, tmp;

  __asm__ __volatile__
  (
    "mrs %[r0], CPSR" "\n\t"
    "orr %[r1], %[r0], #0x80" "\n\t"
    "msr CPSR_c, %[r1]" "\n\t"
    "mov %[dst], lr\n"
    : [dst] "=&r" (m->splpc), [r0] "=r"(ret), [r1] "=r"(tmp)
  );

  return ret;
}

5.3 define clockcheck:

void
clockcheck(void) {
}

5.4 define coherence:

Add the following to fns.h:

#define coherence()     /* nothing needed for uniprocessor */
  1. anyhigher is defined in proc, which is already included.

  2. define splxpc.

void
splxpc(int i) {
  register uint32_t ret;

  __asm__ __volatile__
  (
    "mrs %[r0], CPSR" "\n\t"
    "msr CPSR_c, %[r1]" "\n\t"
    : [r0] "=r"(ret)
    : [r1] "r"(i)
  );

  return;
}

Thats it, lets try to build:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM main.c
main.c: In function 'islo':
main.c:56:18: error: 'PsrDirq' undeclared (first use in this function)
   uint32_t val = PsrDirq;
                  ^
main.c:56:18: note: each undeclared identifier is reported only once for each function it appears in
mk: arm-none-eabi-gcc -O0 -std=c1x ...  : exit status=exit(1)

Lets fix that. We will add some definitions to mem.h, so the result is:

#define KZERO       0xa0008000              /*! kernel address space */
#define MACHADDR    (KZERO+0x00001000)          /*! Mach structure */

/*
 * PSR
 */
#define PsrMusr     0x10    /* mode */
#define PsrMfiq     0x11 
#define PsrMirq     0x12
#define PsrMsvc     0x13
#define PsrMabt     0x17
#define PsrMund     0x1B
#define PsrMsys     0x1F
#define PsrMask     0x1F

#define PsrDfiq     0x00000040  /* disable FIQ interrupts */
#define PsrDirq     0x00000080  /* disable IRQ interrupts */

#define PsrV        0x10000000  /* overflow */
#define PsrC        0x20000000  /* carry/borrow/extend */
#define PsrZ        0x40000000  /* zero */
#define PsrN        0x80000000  /* negative/less than */

Rebuild, observe lots of undeclared and undefined stuff:

../port/devcons.c:106:24: error: 'HZ' undeclared (first use in this function)
../port/devcons.c:144:10: error: 'screenputs' undeclared (first use in this function)
../port/devcons.c: In function 'dbgwork':
../port/devcons.c:414:1: error: parameter name omitted
 dbgwork(void *)
../port/devcons.c: In function 'dbgproc':
../port/devcons.c:420:1: error: parameter name omitted
 dbgproc(void *)
../port/devcons.c: In function 'dbgtoggle':
../port/devcons.c:502:1: error: parameter name omitted
 dbgtoggle(Rune)
../port/devcons.c:665:2: warning: implicit declaration of function 'TK2SEC' [-Wimplicit-function-declaration]
../port/devcons.c:665:35: error: invalid type argument of '->' (have 'int')
  return boottime + TK2SEC(MACHP(0)->ticks);
../port/devcons.c: In function 'qpanic':
../port/devcons.c:734:1: error: parameter name omitted
 qpanic(Rune)
../port/devcons.c: In function 'rexit':
../port/devcons.c:740:1: error: parameter name omitted
 rexit(Rune)

Its just a bunch of omitted parameter names and some undefined macros. Nothing catastrophic so far.

  1. Define HZ, MACHP, TK2SEC and other stuff in dat.h. The resulting file should look this way:
#define HZ          (100)       /*! clock frequency */
#define MS2HZ       (1000/HZ)   /*! millisec per clock tick */
#define TK2SEC(t)   ((t)/HZ)    /*! ticks to seconds */
#define MS2TK(t)    ((t)/MS2HZ) /*! milliseconds to ticks */

#define MACHP(n)    (n == 0 ? (Mach*)(MACHADDR) : (Mach*)0)

typedef struct Lock Lock;
typedef struct Ureg Ureg;
typedef struct Label Label;
typedef struct FPenv FPenv;
typedef struct Mach Mach;
typedef struct FPU FPU;
typedef ulong Instr;
typedef struct Conf Conf;

struct Lock
{
    ulong   key;
    ulong   sr;
    ulong   pc;
    int pri;
};

struct Label
{
  ulong sp;
  ulong pc;
};

enum
{
    FPINIT,
    FPACTIVE,
    FPINACTIVE
};

struct FPenv
{
    int x;
};

struct  FPU
{
    FPenv env;
};

struct Conf
{
    ulong   nmach;          /* processors */
    ulong   nproc;          /* processes */
    ulong   npage0;         /* total physical pages of memory */
    ulong   npage1;         /* total physical pages of memory */
    ulong   topofmem;       /* highest physical address + 1 */
    ulong   npage;          /* total physical pages of memory */
    ulong   base0;          /* base of bank 0 */
    ulong   base1;          /* base of bank 1 */
    ulong   ialloc;         /* max interrupt time allocation in bytes */
};

#include "../port/portdat.h"

struct Mach
{
  ulong splpc; /* pc of last caller to splhi */
    int     machno;     /* physical id of processor */
    ulong   ticks;      /* of the clock since boot time */
    Proc*   proc;       /* current process on this processor */
    Label   sched;      /* scheduler wakeup */
    ulong   cpuhz;

    /* stacks for exceptions */
    ulong   fiqstack[4];
    ulong   irqstack[4];
    ulong   abtstack[4];
    ulong   undstack[4];
    int stack[1];
};

extern Mach *m;
extern Proc *up;

typedef struct Vectorpage {
    void    (*vectors[8])(void);
    uint    vtable[8];
} Vectorpage;
extern Vectorpage *page0;
  1. Define screenputs in fns.h:
#include "../port/portfns.h"

#define coherence()     /* nothing needed for uniprocessor */

void    (*screenputs)(char*, int);

void archreset(void);
void dmareset(void);
  1. Fix dbgwork, dbgproc, dbgtoggle, qpanic, rexit in port/devcons.c:
diff -r 857f33069dc2 os/port/devcons.c
--- a/os/port/devcons.c Sun May 24 15:03:38 2015 +0300
+++ b/os/port/devcons.c Sun May 31 02:11:06 2015 +0300
@@ -411,13 +411,13 @@
 }

 static int
-dbgwork(void *)
+dbgwork(void *v)
 {
    return dbg.work != 0;
 }

 static void
-dbgproc(void *)
+dbgproc(void *v)
 {
    Dbgkey *dp;

@@ -499,7 +499,7 @@
 }

 static void
-dbgtoggle(Rune)
+dbgtoggle(Rune r)
 {
    dbg.on = !dbg.on;
    print("Debug keys %s\n", dbg.on ? "HOT" : "COLD");
@@ -731,13 +731,13 @@
 }

 static void
-qpanic(Rune)
+qpanic(Rune r)
 {
    panic("User requested panic.");
 }

 static void
-rexit(Rune)
+rexit(Rune r)
 {
    exit(0);
 }
diff -r 857f33069dc2 os/port/print.c
--- a/os/port/print.c   Sun May 24 15:03:38 2015 +0300
+++ b/os/port/print.c   Sun May 31 02:11:06 2015 +0300
@@ -19,13 +19,13 @@
 }

 int
-_efgfmt(Fmt*)
+_efgfmt(Fmt* f)
 {
    return -1;
 }

 int
-errfmt(Fmt*)
+errfmt(Fmt* f)
 {
    return -1;
 }

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    sed 's/extern //;s,;.*/\* , = ",;s, \*/,";,' < ../port/error.h > errstr.h
/bin/sh ../port/mkroot lpc-e2468
    /bin/sh ../port/mkdevc lpc-e2468 > lpc-e2468.c
awk: cmd. line:63: warning: escape sequence `\.' treated as plain `.'
(cd /home/snegovick/dev/inferno/inferno-os-lpc2468/libkern ; mk SHELLTYPE=sh SYSTARG=Inferno OBJTYPE=arm-gcc install)
warning: skipping missing include file: mkfile-arm-gcc: No such file or directory
arm-none-eabi-ar ruvs /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libkern.a fmtstr.o fmtvprint.o getfields.o log.o memccpy.o memchr.o memcmp.o pow.o pow10.o qsort.o rune.o runestrlen.o sin.o seprint.o smprint.o snprint.o sqrt.o strcat.o strcmp.o strcpy.o strdup.o strecpy.o strlen.o strncmp.o strncpy.o strrchr.o strstr.o strtod.o strtol.o strtoll.o strtoul.o strtoull.o tokenize.o toupper.o u16.o u32.o u64.o utfecpy.o utflen.o utfnlen.o utfrrune.o utfrune.o vseprint.o vsmprint.o vsnprint.o
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/proc.c
../port/proc.c: In function 'sched':
../port/proc.c:89:3: warning: implicit declaration of function 'procsave' [-Wimplicit-function-declaration]
   procsave(up);
   ^
../port/proc.c: In function 'runproc':
../port/proc.c:171:4: warning: implicit declaration of function 'idlehands' [-Wimplicit-function-declaration]
    idlehands();
    ^
../port/proc.c: In function 'newproc':
../port/proc.c:278:23: error: 'KSTACK' undeclared (first use in this function)
   p->kstack = smalloc(KSTACK);
                       ^
../port/proc.c:278:23: note: each undeclared identifier is reported only once for each function it appears in
../port/proc.c: In function 'tsleep':
../port/proc.c:400:2: warning: implicit declaration of function 'waserror' [-Wimplicit-function-declaration]
  if(waserror()){
  ^
../port/proc.c: In function 'pexit':
../port/proc.c:465:1: error: parameter name omitted
 pexit(char*, int)
 ^
../port/proc.c:465:1: error: parameter name omitted
../port/proc.c: In function 'errorf':
../port/proc.c:570:2: warning: useless type name in empty declaration [enabled by default]
  va_end(arg);
  ^
../port/proc.c: In function 'kwerrstr':
../port/proc.c:622:2: warning: useless type name in empty declaration [enabled by default]
  va_end(arg);
  ^
../port/proc.c: In function 'werrstr':
../port/proc.c:634:2: warning: useless type name in empty declaration [enabled by default]
  va_end(arg);
  ^
../port/proc.c: In function 'return0':
../port/proc.c:694:1: error: parameter name omitted
 return0(void*)
 ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Ok, some more things to fix.

  1. Define KSTACK in mem.h:
#define KiB     1024u       /*! Kibi 0x0000000000000400 */
#define MiB     1048576u    /*! Mebi 0x0000000000100000 */
#define GiB     1073741824u /*! Gibi 000000000040000000 */

#define KSTKSIZE    (8*KiB*2)
#define KSTACK      KSTKSIZE

#define KZERO       0xa0008000              /*! kernel address space */
#define MACHADDR    (KZERO+0x00001000)          /*! Mach structure */

/*
 * PSR
 */
#define PsrMusr     0x10    /* mode */
#define PsrMfiq     0x11 
#define PsrMirq     0x12
#define PsrMsvc     0x13
#define PsrMabt     0x17
#define PsrMund     0x1B
#define PsrMsys     0x1F
#define PsrMask     0x1F

#define PsrDfiq     0x00000040  /* disable FIQ interrupts */
#define PsrDirq     0x00000080  /* disable IRQ interrupts */

#define PsrV        0x10000000  /* overflow */
#define PsrC        0x20000000  /* carry/borrow/extend */
#define PsrZ        0x40000000  /* zero */
#define PsrN        0x80000000  /* negative/less than */
  1. Define procsave in fns.h:
#include "../port/portfns.h"

#define coherence()     /* nothing needed for uniprocessor */
#define procsave(p)     /* Save the mach part of the current */ 
                        /* process state, no need for one cpu */

void    (*screenputs)(char*, int);

void archreset(void);
void dmareset(void);
  1. Define idlehands in main.c:
void
idlehands(void) {
  uart0_puts("bsp::idlehands\r\n");
  idle();
}

Also, add declaration to fns.h:

#include "../port/portfns.h"

#define coherence()     /* nothing needed for uniprocessor */
#define procsave(p)     /* Save the mach part of the current */ 
                        /* process state, no need for one cpu */

void    (*screenputs)(char*, int);

void archreset(void);
void dmareset(void);
void idlehands(void);
  1. Define waserror in fns.h:
#include "../port/portfns.h"

#define coherence()     /* nothing needed for uniprocessor */
#define procsave(p)     /* Save the mach part of the current */ 
                        /* process state, no need for one cpu */
#define waserror()  (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))

void    (*screenputs)(char*, int);

void archreset(void);
void dmareset(void);
void idlehands(void);
  1. Fix pexit, return0 in port/proc.c:
diff -r 857f33069dc2 os/port/proc.c
--- a/os/port/proc.c    Sun May 24 15:03:38 2015 +0300
+++ b/os/port/proc.c    Sun May 31 02:29:02 2015 +0300
@@ -462,7 +462,7 @@
 }

 void
-pexit(char*, int)
+pexit(char* c, int i)
 {
    Osenv *o;

@@ -691,7 +691,7 @@
 }

 int
-return0(void*)
+return0(void* v)
 {
    return 0;
 }

Rebuild:

main.o: In function `idlehands':
main.c:(.text+0x1b4): undefined reference to `idle'
proc.o: In function `schedinit':
proc.c:(.text+0x18): undefined reference to `setlabel'
proc.o: In function `sched':
proc.c:(.text+0x10c): undefined reference to `setlabel'
proc.c:(.text+0x11c): undefined reference to `spllo'
proc.c:(.text+0x134): undefined reference to `gotolabel'
proc.c:(.text+0x1a4): undefined reference to `gotolabel'
proc.o: In function `ready':
proc.c:(.text+0x2a0): undefined reference to `splx'
proc.o: In function `runproc':
proc.c:(.text+0x43c): undefined reference to `spllo'
proc.o: In function `newproc':
proc.c:(.text+0x8a4): undefined reference to `kstrdup'
proc.c:(.text+0x8dc): undefined reference to `incref'
proc.c:(.text+0x910): undefined reference to `resrcwait'
proc.c:(.text+0x93c): undefined reference to `smalloc'
proc.c:(.text+0x950): undefined reference to `addprog'
proc.o: In function `procinit':
proc.c:(.text+0x9b0): undefined reference to `xalloc'
proc.o: In function `sleep':
proc.c:(.text+0xb58): undefined reference to `dumpstack'
proc.c:(.text+0xc50): undefined reference to `splx'
proc.c:(.text+0xc74): undefined reference to `splx'
proc.o: In function `tsleep':
proc.c:(.text+0xef0): undefined reference to `setlabel'
proc.c:(.text+0xf68): undefined reference to `talarm'
proc.c:(.text+0xf6c): undefined reference to `talarm'
proc.o: In function `wakeup':
proc.c:(.text+0xfec): undefined reference to `splx'
proc.o: In function `swiproc':
proc.c:(.text+0x10ec): undefined reference to `splx'
proc.o: In function `pexit':
proc.c:(.text+0x1198): undefined reference to `closefgrp'
proc.c:(.text+0x11a8): undefined reference to `closepgrp'
proc.c:(.text+0x11b8): undefined reference to `closeegrp'
proc.c:(.text+0x11c8): undefined reference to `closesigs'
proc.o: In function `kproc':
proc.c:(.text+0x1440): undefined reference to `kstrdup'
proc.c:(.text+0x1470): undefined reference to `incref'
proc.c:(.text+0x14b4): undefined reference to `incref'
proc.c:(.text+0x1500): undefined reference to `incref'
proc.c:(.text+0x1520): undefined reference to `kprocchild'
proc.o: In function `error':
proc.c:(.text+0x15d4): undefined reference to `spllo'
proc.c:(.text+0x162c): undefined reference to `kstrcpy'
proc.c:(.text+0x1640): undefined reference to `setlabel'
proc.o: In function `kerrstr':
proc.c:(.text+0x1694): undefined reference to `kstrcpy'
proc.c:(.text+0x16b4): undefined reference to `kstrcpy'
proc.c:(.text+0x16cc): undefined reference to `kstrcpy'
proc.o: In function `kgerrstr':
proc.c:(.text+0x1714): undefined reference to `kstrcpy'
proc.c:(.text+0x1734): undefined reference to `kstrcpy'
proc.o:proc.c:(.text+0x174c): more undefined references to `kstrcpy' follow
proc.o: In function `nexterror':
proc.c:(.text+0x1880): undefined reference to `gotolabel'
proc.o: In function `renameuser':
proc.c:(.text+0x1a38): undefined reference to `kstrdup'
proc.o: In function `setid':
proc.c:(.text+0x1ad8): undefined reference to `kstrdup'
proc.o: In function `rproc':
proc.c:(.text+0x1cb0): undefined reference to `setlabel'
proc.c:(.text+0x1d2c): undefined reference to `acquire'
proc.c:(.text+0x1d6c): undefined reference to `setlabel'
proc.c:(.text+0x1d7c): undefined reference to `release'
proc.c:(.text+0x1dac): undefined reference to `release'
proc.o: In function `rptproc':
proc.c:(.text+0x1e04): undefined reference to `mallocz'
devcons.o: In function `printinit':
devcons.c:(.text+0x18): undefined reference to `qopen'
devcons.c:(.text+0x50): undefined reference to `qnoblock'
devcons.o: In function `consactive':
devcons.c:(.text+0xf0): undefined reference to `qlen'
devcons.o: In function `putstrn0':
devcons.c:(.text+0x1c0): undefined reference to `canrlock'
devcons.c:(.text+0x21c): undefined reference to `setlabel'
devcons.c:(.text+0x230): undefined reference to `runlock'
devcons.c:(.text+0x258): undefined reference to `qwrite'
devcons.c:(.text+0x274): undefined reference to `qiwrite'
devcons.c:(.text+0x298): undefined reference to `runlock'
devcons.c:(.text+0x3ec): undefined reference to `qwrite'
devcons.c:(.text+0x414): undefined reference to `qiwrite'
devcons.c:(.text+0x45c): undefined reference to `qwrite'
devcons.c:(.text+0x478): undefined reference to `qiwrite'
devcons.c:(.text+0x49c): undefined reference to `consoleprint'
devcons.o: In function `kprint':
devcons.c:(.text+0x714): undefined reference to `qfull'
devcons.c:(.text+0x730): undefined reference to `qflush'
devcons.c:(.text+0x74c): undefined reference to `qproduce'
devcons.o: In function `iprint':
devcons.c:(.text+0x80c): undefined reference to `uartputs'
devcons.c:(.text+0x814): undefined reference to `splx'
devcons.o: In function `panic':
devcons.c:(.text+0x8f0): undefined reference to `spllo'
devcons.c:(.text+0x8f4): undefined reference to `dumpstack'
devcons.o: In function `pprint':
devcons.c:(.text+0xae8): undefined reference to `setlabel'
devcons.o: In function `echo':
devcons.c:(.text+0xc28): undefined reference to `qiwrite'
devcons.c:(.text+0xca8): undefined reference to `qiwrite'
devcons.c:(.text+0xcc8): undefined reference to `consoleprint'
devcons.o: In function `isdbgkey':
devcons.c:(.text+0x10a0): undefined reference to `qproduce'
devcons.o: In function `kbdputc':
devcons.c:(.text+0x13c0): undefined reference to `latin1'
devcons.c:(.text+0x1428): undefined reference to `qproduce'
devcons.c:(.text+0x14b8): undefined reference to `qproduce'
devcons.o: In function `consinit':
devcons.c:(.text+0x19e0): undefined reference to `randominit'
devcons.c:(.text+0x1a34): undefined reference to `qopen'
devcons.o: In function `consattach':
devcons.c:(.text+0x1a84): undefined reference to `devattach'
devcons.o: In function `conswalk':
devcons.c:(.text+0x1ae0): undefined reference to `devwalk'
devcons.c:(.text+0x1afc): undefined reference to `devgen'
devcons.o: In function `consstat':
devcons.c:(.text+0x1b38): undefined reference to `devstat'
devcons.c:(.text+0x1b50): undefined reference to `devgen'
devcons.o: In function `flushkbdline':
devcons.c:(.text+0x1b8c): undefined reference to `qwrite'
devcons.o: In function `consopen':
devcons.c:(.text+0x1c24): undefined reference to `qlock'
devcons.c:(.text+0x1c40): undefined reference to `qunlock'
devcons.c:(.text+0x1c5c): undefined reference to `qlock'
devcons.c:(.text+0x1c94): undefined reference to `qunlock'
devcons.c:(.text+0x1ca4): undefined reference to `qlock'
devcons.c:(.text+0x1ccc): undefined reference to `qunlock'
devcons.c:(.text+0x1d20): undefined reference to `qopen'
devcons.c:(.text+0x1d34): undefined reference to `qunlock'
devcons.c:(.text+0x1d50): undefined reference to `wlock'
devcons.c:(.text+0x1d68): undefined reference to `wunlock'
devcons.c:(.text+0x1d84): undefined reference to `qopen'
devcons.c:(.text+0x1da8): undefined reference to `wunlock'
devcons.c:(.text+0x1dc4): undefined reference to `qnoblock'
devcons.c:(.text+0x1dcc): undefined reference to `wunlock'
devcons.c:(.text+0x1e00): undefined reference to `devopen'
devcons.c:(.text+0x1e3c): undefined reference to `qiomaxatomic'
devcons.c:(.text+0x1e40): undefined reference to `devgen'
devcons.o: In function `consclose':
devcons.c:(.text+0x1eac): undefined reference to `qlock'
devcons.c:(.text+0x1ee4): undefined reference to `qunlock'
devcons.c:(.text+0x1f00): undefined reference to `qlock'
devcons.c:(.text+0x1f1c): undefined reference to `qunlock'
devcons.c:(.text+0x1f2c): undefined reference to `qlock'
devcons.c:(.text+0x1f4c): undefined reference to `qfree'
devcons.c:(.text+0x1f60): undefined reference to `qunlock'
devcons.c:(.text+0x1f6c): undefined reference to `wlock'
devcons.c:(.text+0x1f7c): undefined reference to `qfree'
devcons.c:(.text+0x1f90): undefined reference to `wunlock'
devcons.o: In function `consread':
devcons.c:(.text+0x2078): undefined reference to `devdirread'
devcons.c:(.text+0x20ac): undefined reference to `qlock'
devcons.c:(.text+0x20ec): undefined reference to `setlabel'
devcons.c:(.text+0x2100): undefined reference to `qunlock'
devcons.c:(.text+0x2134): undefined reference to `qcanread'
devcons.c:(.text+0x2158): undefined reference to `qread'
devcons.c:(.text+0x2178): undefined reference to `qread'
devcons.c:(.text+0x21b8): undefined reference to `qcanread'
devcons.c:(.text+0x2208): undefined reference to `qread'
devcons.c:(.text+0x2360): undefined reference to `qwrite'
devcons.c:(.text+0x237c): undefined reference to `qcanread'
devcons.c:(.text+0x23a0): undefined reference to `qread'
devcons.c:(.text+0x23ac): undefined reference to `qunlock'
devcons.c:(.text+0x240c): undefined reference to `qread'
devcons.c:(.text+0x2590): undefined reference to `genrandom'
devcons.c:(.text+0x25a8): undefined reference to `randomread'
devcons.c:(.text+0x25c4): undefined reference to `poolread'
devcons.c:(.text+0x26b8): undefined reference to `setlabel'
devcons.c:(.text+0x272c): undefined reference to `qread'
devcons.c:(.text+0x273c): undefined reference to `rlock'
devcons.c:(.text+0x277c): undefined reference to `setlabel'
devcons.c:(.text+0x2790): undefined reference to `runlock'
devcons.c:(.text+0x27ac): undefined reference to `qread'
devcons.c:(.text+0x27cc): undefined reference to `runlock'
devcons.c:(.text+0x2814): undefined reference to `devgen'
devcons.c:(.text+0x2840): undefined reference to `cflag'
devcons.o: In function `conswrite':
devcons.c:(.text+0x29e0): undefined reference to `qlock'
devcons.c:(.text+0x2a04): undefined reference to `qunlock'
devcons.c:(.text+0x2a2c): undefined reference to `qlock'
devcons.c:(.text+0x2a4c): undefined reference to `qunlock'
devcons.c:(.text+0x2c9c): undefined reference to `renameproguser'
devcons.c:(.text+0x2cac): undefined reference to `kstrdup'
devcons.c:(.text+0x2ccc): undefined reference to `kstrdup'
devcons.c:(.text+0x2db0): undefined reference to `kstrdup'
devcons.c:(.text+0x2ef4): undefined reference to `kstrdup'
devcons.c:(.text+0x2f1c): undefined reference to `parsecmd'
devcons.c:(.text+0x2f60): undefined reference to `setlabel'
devcons.c:(.text+0x2f88): undefined reference to `lookupcmd'
devcons.c:(.text+0x2fbc): undefined reference to `reboot'
devcons.c:(.text+0x2fc4): undefined reference to `halt'
devcons.c:(.text+0x30c8): undefined reference to `cflag'
devcons.c:(.text+0x30dc): undefined reference to `consoleprint'
devcons.c:(.text+0x30e0): undefined reference to `keepbroken'
devcons.o: In function `seedrand':
devcons.c:(.text+0x30fc): undefined reference to `randomread'
devcons.o: In function `truerand':
devcons.c:(.text+0x3210): undefined reference to `randomread'
devcons.o: In function `_genrandomqlock':
devcons.c:(.text+0x3234): undefined reference to `qlock'
devcons.o: In function `_genrandomqunlock':
devcons.c:(.text+0x3254): undefined reference to `qunlock'
devcons.o:(.data+0x510): undefined reference to `devreset'
devcons.o:(.data+0x518): undefined reference to `devshutdown'
devcons.o:(.data+0x52c): undefined reference to `devcreate'
devcons.o:(.data+0x538): undefined reference to `devbread'
devcons.o:(.data+0x540): undefined reference to `devbwrite'
devcons.o:(.data+0x544): undefined reference to `devremove'
devcons.o:(.data+0x548): undefined reference to `devwstat'

Looks like we should enable some more modules in port section. Undefined references to xalloc mean that we should add xalloc module:

dev

port
  print
  proc
  taslock
  devcons
  xalloc

code

lib
    kern

init
    bootinit

root
  /dev  /

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/xalloc.c
../port/xalloc.c: In function 'xinit':
../port/xalloc.c:64:33: error: 'BY2PG' undeclared (first use in this function)
   xhole(conf.base1, conf.npage1*BY2PG);
                                 ^
../port/xalloc.c:64:33: note: each undeclared identifier is reported only once for each function it appears in
../port/xalloc.c:72:2: warning: implicit declaration of function 'KADDR' [-Wimplicit-function-declaration]
  conf.base0 = (ulong)KADDR(conf.base0);
  ^
../port/xalloc.c: In function 'xspanalloc':
../port/xalloc.c:93:4: warning: implicit declaration of function 'PADDR' [-Wimplicit-function-declaration]
    xhole(PADDR(a), t);
    ^
../port/xalloc.c: In function 'xallocz':
../port/xalloc.c:113:10: error: 'BY2V' undeclared (first use in this function)
  size += BY2V + sizeof(Xhdr);
          ^
../port/xalloc.c:129:6: warning: assignment makes pointer from integer without a cast [enabled by default]
    p = KADDR(p);
      ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Define BY2V, BY2PG macros in mem.h:

diff -r abaabece21b7 os/lpc-e2468-olimex/mem.h
--- a/os/lpc-e2468-olimex/mem.h Sun May 31 02:30:48 2015 +0300
+++ b/os/lpc-e2468-olimex/mem.h Sun May 31 02:36:40 2015 +0300
@@ -7,6 +7,8 @@

 #define KZERO       0xa0008000              /*! kernel address space */
 #define MACHADDR    (KZERO+0x00001000)          /*! Mach structure */
+#define BY2PG       (4*KiB)                 /*! bytes per page */
+#define BY2V        8                       /*! only used in xalloc.c */

 /*
  * PSR

Define PADDR and KADDR in fns.h:

diff -r abaabece21b7 os/lpc-e2468-olimex/fns.h
--- a/os/lpc-e2468-olimex/fns.h Sun May 31 02:30:48 2015 +0300
+++ b/os/lpc-e2468-olimex/fns.h Sun May 31 02:38:21 2015 +0300
@@ -4,6 +4,8 @@
 #define procsave(p)     /* Save the mach part of the current */ 
                         /* process state, no need for one cpu */
 #define    waserror()  (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
+#define KADDR(p)    ((void *)p)
+#define PADDR(p)    ((ulong)p)

 void    (*screenputs)(char*, int);

Rebuild:

main.o: In function `idlehands':
main.c:(.text+0x1b4): undefined reference to `idle'
proc.o: In function `schedinit':
proc.c:(.text+0x18): undefined reference to `setlabel'
proc.o: In function `sched':
proc.c:(.text+0x10c): undefined reference to `setlabel'
proc.c:(.text+0x11c): undefined reference to `spllo'
proc.c:(.text+0x134): undefined reference to `gotolabel'
proc.c:(.text+0x1a4): undefined reference to `gotolabel'
proc.o: In function `ready':
proc.c:(.text+0x2a0): undefined reference to `splx'
proc.o: In function `runproc':
proc.c:(.text+0x43c): undefined reference to `spllo'
proc.o: In function `newproc':
proc.c:(.text+0x8a4): undefined reference to `kstrdup'
proc.c:(.text+0x8dc): undefined reference to `incref'
proc.c:(.text+0x910): undefined reference to `resrcwait'
proc.c:(.text+0x93c): undefined reference to `smalloc'
proc.c:(.text+0x950): undefined reference to `addprog'
proc.o: In function `sleep':
proc.c:(.text+0xb58): undefined reference to `dumpstack'
proc.c:(.text+0xc50): undefined reference to `splx'
proc.c:(.text+0xc74): undefined reference to `splx'
proc.o: In function `tsleep':
proc.c:(.text+0xef0): undefined reference to `setlabel'
proc.c:(.text+0xf68): undefined reference to `talarm'
proc.c:(.text+0xf6c): undefined reference to `talarm'
proc.o: In function `wakeup':
proc.c:(.text+0xfec): undefined reference to `splx'
proc.o: In function `swiproc':
proc.c:(.text+0x10ec): undefined reference to `splx'
proc.o: In function `pexit':
proc.c:(.text+0x1198): undefined reference to `closefgrp'
proc.c:(.text+0x11a8): undefined reference to `closepgrp'
proc.c:(.text+0x11b8): undefined reference to `closeegrp'
proc.c:(.text+0x11c8): undefined reference to `closesigs'
proc.o: In function `kproc':
proc.c:(.text+0x1440): undefined reference to `kstrdup'
proc.c:(.text+0x1470): undefined reference to `incref'
proc.c:(.text+0x14b4): undefined reference to `incref'
proc.c:(.text+0x1500): undefined reference to `incref'
proc.c:(.text+0x1520): undefined reference to `kprocchild'
proc.o: In function `error':
proc.c:(.text+0x15d4): undefined reference to `spllo'
proc.c:(.text+0x162c): undefined reference to `kstrcpy'
proc.c:(.text+0x1640): undefined reference to `setlabel'
proc.o: In function `kerrstr':
proc.c:(.text+0x1694): undefined reference to `kstrcpy'
proc.c:(.text+0x16b4): undefined reference to `kstrcpy'
proc.c:(.text+0x16cc): undefined reference to `kstrcpy'
proc.o: In function `kgerrstr':
proc.c:(.text+0x1714): undefined reference to `kstrcpy'
proc.c:(.text+0x1734): undefined reference to `kstrcpy'
proc.o:proc.c:(.text+0x174c): more undefined references to `kstrcpy' follow
proc.o: In function `nexterror':
proc.c:(.text+0x1880): undefined reference to `gotolabel'
proc.o: In function `renameuser':
proc.c:(.text+0x1a38): undefined reference to `kstrdup'
proc.o: In function `setid':
proc.c:(.text+0x1ad8): undefined reference to `kstrdup'
proc.o: In function `rproc':
proc.c:(.text+0x1cb0): undefined reference to `setlabel'
proc.c:(.text+0x1d2c): undefined reference to `acquire'
proc.c:(.text+0x1d6c): undefined reference to `setlabel'
proc.c:(.text+0x1d7c): undefined reference to `release'
proc.c:(.text+0x1dac): undefined reference to `release'
proc.o: In function `rptproc':
proc.c:(.text+0x1e04): undefined reference to `mallocz'
devcons.o: In function `printinit':
devcons.c:(.text+0x18): undefined reference to `qopen'
devcons.c:(.text+0x50): undefined reference to `qnoblock'
devcons.o: In function `consactive':
devcons.c:(.text+0xf0): undefined reference to `qlen'
devcons.o: In function `putstrn0':
devcons.c:(.text+0x1c0): undefined reference to `canrlock'
devcons.c:(.text+0x21c): undefined reference to `setlabel'
devcons.c:(.text+0x230): undefined reference to `runlock'
devcons.c:(.text+0x258): undefined reference to `qwrite'
devcons.c:(.text+0x274): undefined reference to `qiwrite'
devcons.c:(.text+0x298): undefined reference to `runlock'
devcons.c:(.text+0x3ec): undefined reference to `qwrite'
devcons.c:(.text+0x414): undefined reference to `qiwrite'
devcons.c:(.text+0x45c): undefined reference to `qwrite'
devcons.c:(.text+0x478): undefined reference to `qiwrite'
devcons.c:(.text+0x49c): undefined reference to `consoleprint'
devcons.o: In function `kprint':
devcons.c:(.text+0x714): undefined reference to `qfull'
devcons.c:(.text+0x730): undefined reference to `qflush'
devcons.c:(.text+0x74c): undefined reference to `qproduce'
devcons.o: In function `iprint':
devcons.c:(.text+0x80c): undefined reference to `uartputs'
devcons.c:(.text+0x814): undefined reference to `splx'
devcons.o: In function `panic':
devcons.c:(.text+0x8f0): undefined reference to `spllo'
devcons.c:(.text+0x8f4): undefined reference to `dumpstack'
devcons.o: In function `pprint':
devcons.c:(.text+0xae8): undefined reference to `setlabel'
devcons.o: In function `echo':
devcons.c:(.text+0xc28): undefined reference to `qiwrite'
devcons.c:(.text+0xca8): undefined reference to `qiwrite'
devcons.c:(.text+0xcc8): undefined reference to `consoleprint'
devcons.o: In function `isdbgkey':
devcons.c:(.text+0x10a0): undefined reference to `qproduce'
devcons.o: In function `kbdputc':
devcons.c:(.text+0x13c0): undefined reference to `latin1'
devcons.c:(.text+0x1428): undefined reference to `qproduce'
devcons.c:(.text+0x14b8): undefined reference to `qproduce'
devcons.o: In function `consinit':
devcons.c:(.text+0x19e0): undefined reference to `randominit'
devcons.c:(.text+0x1a34): undefined reference to `qopen'
devcons.o: In function `consattach':
devcons.c:(.text+0x1a84): undefined reference to `devattach'
devcons.o: In function `conswalk':
devcons.c:(.text+0x1ae0): undefined reference to `devwalk'
devcons.c:(.text+0x1afc): undefined reference to `devgen'
devcons.o: In function `consstat':
devcons.c:(.text+0x1b38): undefined reference to `devstat'
devcons.c:(.text+0x1b50): undefined reference to `devgen'
devcons.o: In function `flushkbdline':
devcons.c:(.text+0x1b8c): undefined reference to `qwrite'
devcons.o: In function `consopen':
devcons.c:(.text+0x1c24): undefined reference to `qlock'
devcons.c:(.text+0x1c40): undefined reference to `qunlock'
devcons.c:(.text+0x1c5c): undefined reference to `qlock'
devcons.c:(.text+0x1c94): undefined reference to `qunlock'
devcons.c:(.text+0x1ca4): undefined reference to `qlock'
devcons.c:(.text+0x1ccc): undefined reference to `qunlock'
devcons.c:(.text+0x1d20): undefined reference to `qopen'
devcons.c:(.text+0x1d34): undefined reference to `qunlock'
devcons.c:(.text+0x1d50): undefined reference to `wlock'
devcons.c:(.text+0x1d68): undefined reference to `wunlock'
devcons.c:(.text+0x1d84): undefined reference to `qopen'
devcons.c:(.text+0x1da8): undefined reference to `wunlock'
devcons.c:(.text+0x1dc4): undefined reference to `qnoblock'
devcons.c:(.text+0x1dcc): undefined reference to `wunlock'
devcons.c:(.text+0x1e00): undefined reference to `devopen'
devcons.c:(.text+0x1e3c): undefined reference to `qiomaxatomic'
devcons.c:(.text+0x1e40): undefined reference to `devgen'
devcons.o: In function `consclose':
devcons.c:(.text+0x1eac): undefined reference to `qlock'
devcons.c:(.text+0x1ee4): undefined reference to `qunlock'
devcons.c:(.text+0x1f00): undefined reference to `qlock'
devcons.c:(.text+0x1f1c): undefined reference to `qunlock'
devcons.c:(.text+0x1f2c): undefined reference to `qlock'
devcons.c:(.text+0x1f4c): undefined reference to `qfree'
devcons.c:(.text+0x1f60): undefined reference to `qunlock'
devcons.c:(.text+0x1f6c): undefined reference to `wlock'
devcons.c:(.text+0x1f7c): undefined reference to `qfree'
devcons.c:(.text+0x1f90): undefined reference to `wunlock'
devcons.o: In function `consread':
devcons.c:(.text+0x2078): undefined reference to `devdirread'
devcons.c:(.text+0x20ac): undefined reference to `qlock'
devcons.c:(.text+0x20ec): undefined reference to `setlabel'
devcons.c:(.text+0x2100): undefined reference to `qunlock'
devcons.c:(.text+0x2134): undefined reference to `qcanread'
devcons.c:(.text+0x2158): undefined reference to `qread'
devcons.c:(.text+0x2178): undefined reference to `qread'
devcons.c:(.text+0x21b8): undefined reference to `qcanread'
devcons.c:(.text+0x2208): undefined reference to `qread'
devcons.c:(.text+0x2360): undefined reference to `qwrite'
devcons.c:(.text+0x237c): undefined reference to `qcanread'
devcons.c:(.text+0x23a0): undefined reference to `qread'
devcons.c:(.text+0x23ac): undefined reference to `qunlock'
devcons.c:(.text+0x240c): undefined reference to `qread'
devcons.c:(.text+0x2590): undefined reference to `genrandom'
devcons.c:(.text+0x25a8): undefined reference to `randomread'
devcons.c:(.text+0x25c4): undefined reference to `poolread'
devcons.c:(.text+0x26b8): undefined reference to `setlabel'
devcons.c:(.text+0x272c): undefined reference to `qread'
devcons.c:(.text+0x273c): undefined reference to `rlock'
devcons.c:(.text+0x277c): undefined reference to `setlabel'
devcons.c:(.text+0x2790): undefined reference to `runlock'
devcons.c:(.text+0x27ac): undefined reference to `qread'
devcons.c:(.text+0x27cc): undefined reference to `runlock'
devcons.c:(.text+0x2814): undefined reference to `devgen'
devcons.c:(.text+0x2840): undefined reference to `cflag'
devcons.o: In function `conswrite':
devcons.c:(.text+0x29e0): undefined reference to `qlock'
devcons.c:(.text+0x2a04): undefined reference to `qunlock'
devcons.c:(.text+0x2a2c): undefined reference to `qlock'
devcons.c:(.text+0x2a4c): undefined reference to `qunlock'
devcons.c:(.text+0x2c9c): undefined reference to `renameproguser'
devcons.c:(.text+0x2cac): undefined reference to `kstrdup'
devcons.c:(.text+0x2ccc): undefined reference to `kstrdup'
devcons.c:(.text+0x2db0): undefined reference to `kstrdup'
devcons.c:(.text+0x2ef4): undefined reference to `kstrdup'
devcons.c:(.text+0x2f1c): undefined reference to `parsecmd'
devcons.c:(.text+0x2f60): undefined reference to `setlabel'
devcons.c:(.text+0x2f88): undefined reference to `lookupcmd'
devcons.c:(.text+0x2fbc): undefined reference to `reboot'
devcons.c:(.text+0x2fc4): undefined reference to `halt'
devcons.c:(.text+0x30c8): undefined reference to `cflag'
devcons.c:(.text+0x30dc): undefined reference to `consoleprint'
devcons.c:(.text+0x30e0): undefined reference to `keepbroken'
devcons.o: In function `seedrand':
devcons.c:(.text+0x30fc): undefined reference to `randomread'
devcons.o: In function `truerand':
devcons.c:(.text+0x3210): undefined reference to `randomread'
devcons.o: In function `_genrandomqlock':
devcons.c:(.text+0x3234): undefined reference to `qlock'
devcons.o: In function `_genrandomqunlock':
devcons.c:(.text+0x3254): undefined reference to `qunlock'
devcons.o:(.data+0x510): undefined reference to `devreset'
devcons.o:(.data+0x518): undefined reference to `devshutdown'
devcons.o:(.data+0x52c): undefined reference to `devcreate'
devcons.o:(.data+0x538): undefined reference to `devbread'
devcons.o:(.data+0x540): undefined reference to `devbwrite'
devcons.o:(.data+0x544): undefined reference to `devremove'
devcons.o:(.data+0x548): undefined reference to `devwstat'
xalloc.o: In function `ixprt':

Better, but still alot of undefined entries.

Add qlock and random modules to lpc-e2468:

dev

port
  print
  proc
  taslock
  devcons
  qlock
    random
  xalloc

code

lib
    kern

init
    bootinit

root
  /dev  /

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/qlock.c
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/random.c
../port/random.c: In function 'rbnotfull':
../port/random.c:27:1: error: parameter name omitted
 rbnotfull(void*)
 ^
../port/random.c: In function 'rbnotempty':
../port/random.c:38:1: error: parameter name omitted
 rbnotempty(void*)
 ^
../port/random.c: In function 'genrandom':
../port/random.c:44:1: error: parameter name omitted
 genrandom(void*)
 ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Fix rbnotfull, rbnotempty, getrandom in port/random.c:

diff -r abaabece21b7 os/port/random.c
--- a/os/port/random.c  Sun May 31 02:30:48 2015 +0300
+++ b/os/port/random.c  Sun May 31 02:42:36 2015 +0300
@@ -24,7 +24,7 @@
 } rb;

 static int
-rbnotfull(void*)
+rbnotfull(void* v)
 {
    int i;

@@ -35,13 +35,13 @@
 }

 static int
-rbnotempty(void*)
+rbnotempty(void* v)
 {
    return rb.wp != rb.rp;
 }

 static void
-genrandom(void*)
+genrandom(void* v)
 {
    setpri(PriBackground);

Rebuild. Still alot to do. Lets add qio, allocb, dev modules to lpc-e2468:

dev

port
  allocb
  dev
  devcons
  print
  proc
  taslock
  qio
  qlock
    random
  xalloc

code

lib
    kern

init
    bootinit

root
  /dev  /

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/dev.c
../port/dev.c: In function 'devgen':
../port/dev.c:56:1: error: parameter name omitted
 devgen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp)
 ^
../port/dev.c: In function 'devcreate':
../port/dev.c:348:1: error: parameter name omitted
 devcreate(Chan*, char*, int, ulong)
 ^
../port/dev.c:348:1: error: parameter name omitted
../port/dev.c:348:1: error: parameter name omitted
../port/dev.c:348:1: error: parameter name omitted
../port/dev.c: In function 'devremove':
../port/dev.c:387:1: error: parameter name omitted
 devremove(Chan*)
 ^
../port/dev.c: In function 'devwstat':
../port/dev.c:393:1: error: parameter name omitted
 devwstat(Chan*, uchar*, int)
 ^
../port/dev.c:393:1: error: parameter name omitted
../port/dev.c:393:1: error: parameter name omitted
../port/dev.c: In function 'devpower':
../port/dev.c:400:1: error: parameter name omitted
 devpower(int)
 ^
../port/dev.c: In function 'devconfig':
../port/dev.c:406:1: error: parameter name omitted
 devconfig(int, char *, DevConf *)
 ^
../port/dev.c:406:1: error: parameter name omitted
../port/dev.c:406:1: error: parameter name omitted
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Fix these guys:

diff -r abaabece21b7 os/port/dev.c
--- a/os/port/dev.c Sun May 31 02:30:48 2015 +0300
+++ b/os/port/dev.c Sun May 31 02:54:32 2015 +0300
@@ -53,7 +53,7 @@
  * the zeroth element of the table MUST be the directory itself for ..
 */
 int
-devgen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp)
+devgen(Chan *c, char* ch, Dirtab *tab, int ntab, int i, Dir *dp)
 {
    if(tab == 0)
        return -1;
@@ -345,7 +345,7 @@
 }

 void
-devcreate(Chan*, char*, int, ulong)
+devcreate(Chan* c, char* ch, int i, ulong u)
 {
    error(Eperm);
 }
@@ -384,26 +384,26 @@
 }

 void
-devremove(Chan*)
+devremove(Chan* c)
 {
    error(Eperm);
 }

 int
-devwstat(Chan*, uchar*, int)
+devwstat(Chan* c, uchar* u, int i)
 {
    error(Eperm);
    return 0;
 }

 void
-devpower(int)
+devpower(int i)
 {
    error(Eperm);
 }

 int
-devconfig(int, char *, DevConf *)
+devconfig(int i, char *c, DevConf *dc)
 {
    error(Eperm);
    return 0;

Rebuilding shows some more undefined procedures. Add alloc, chan, pgrp, parse, sysfile, dis modules to lpc-e2468:

dev

port
  alloc
  allocb
  chan
  dev
  devcons
  dis
  parse
  pgrp
  print
  proc
  qio
  qlock
    random
  sysfile
  taslock
  xalloc

code

lib
    kern

init
    bootinit

root
  /dev  /

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/dis.c
../port/dis.c: In function 'tready':
../port/dis.c:59:2: warning: useless type name in empty declaration [enabled by default]
  USED(a);
  ^
../port/dis.c: In function 'delprog':
../port/dis.c:257:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]
  p->state = 0xdeadbeef;
  ^
../port/dis.c: In function 'disfault':
../port/dis.c:989:2: warning: useless type name in empty declaration [enabled by default]
  USED(reg);
  ^
../port/dis.c: In function 'vmachine':
../port/dis.c:1012:1: error: parameter name omitted
 vmachine(void*)
 ^
../port/dis.c: In function 'disinit':
../port/dis.c:1092:2: warning: implicit declaration of function 'fpinit' [-Wimplicit-function-declaration]
  FPinit();
  ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Fix it:

diff -r abaabece21b7 os/port/dis.c
--- a/os/port/dis.c Sun May 31 02:30:48 2015 +0300
+++ b/os/port/dis.c Sun May 31 03:02:31 2015 +0300
@@ -254,7 +254,7 @@
        if(p->link == nil)
            isched.runtl = nil;
    }
-   p->state = 0xdeadbeef;
+   p->state = 0xdeadbeefUL;
    free(o->user);
    free(p->killstr);
    free(p->exstr);
@@ -1009,7 +1009,7 @@
 }

 void
-vmachine(void*)
+vmachine(void* v)
 {
    Prog *r;
    Osenv *o;

After rebuild we still have alot of undefined entries, but some of these are port-specific. This is the list:

  • setlabel
  • gotolabel
  • splx
  • spllo
  • consoleprint
  • reboot
  • halt

  • Define setlabel in main.c:

int
setlabel(Label* l) {
  __asm__ __volatile__ (
    "mov %[dstsp], sp\n"
    "mov %[dstpc], lr\n"
    : [dstsp] "=&r" (l->sp), [dstpc] "=&r" (l->pc)
    );

  return 0;
}
  1. Define gotolabel in main.c:
void
gotolabel(Label* l) {
  __asm__ __volatile__ (
    "mov sp, %[srcsp]\n"
    "mov lr, %[srcpc]\n"
    "bx lr"
    :
    : [srcsp] "r" (l->sp), [srcpc] "r" (l->pc)
    );
}
  1. Define splx:
void
splx(int i)
{
  __asm__ __volatile__ (
    "mov %[dst], lr\n"
    : [dst] "=&r" (m->splpc)
    );
}
  1. Define spllo
int
spllo(void) {
  register uint32_t ret, tmp;
  uint32_t val = PsrDirq | PsrDfiq;

  __asm__ __volatile__
  (
    "mrs %[r0], CPSR\n\t"
    "bic %[r1], %[r0], %[val]\n\t"
    "msr CPSR_c, %[r1]\n\t"
    : [r0] "=r"(ret), [r1] "=r"(tmp)
    : [val] "r" (val)
  );

  return ret;
}
  1. Enable consoleprint in lpc-e2468:
dev

port
  alloc
  allocb
  chan
  dev
  devcons
  dis
  parse
  pgrp
  print
  proc
  qio
  qlock
    random
  sysfile
  taslock
  xalloc

code
    int consoleprint = 1;

lib
    kern

init
    bootinit

root
  /dev  /
  1. Define reboot and halt in main.c:
void
reboot(void) {
  uart0_puts("reboot\r\n");
  return;
  }

void
halt(void) {
  uart0_puts("halt\r\n");
  return;
}

Rebuild:

main.o: In function `idlehands':
main.c:(.text+0x220): undefined reference to `idle'
alloc.o: In function `poolmutable':
alloc.c:(.text+0x1d8): undefined reference to `mutator'
alloc.o: In function `poolfree':
alloc.c:(.text+0x10d4): undefined reference to `ptr'
allocb.o: In function `_allocb':
allocb.c:(.text+0x84): undefined reference to `ROUND'
chan.o: In function `chanfree':
chan.c:(.text+0xa7c): undefined reference to `muxclose'
devcons.o: In function `putstrn0':
devcons.c:(.text+0x49c): undefined reference to `consoleprint'
devcons.o: In function `iprint':
devcons.c:(.text+0x80c): undefined reference to `uartputs'
devcons.o: In function `panic':
devcons.c:(.text+0x8f4): undefined reference to `dumpstack'
devcons.o: In function `echo':
devcons.c:(.text+0xcc8): undefined reference to `consoleprint'
devcons.o: In function `kbdputc':
devcons.c:(.text+0x13c0): undefined reference to `latin1'
devcons.o: In function `consread':
devcons.c:(.text+0x2590): undefined reference to `genrandom'
devcons.o: In function `conswrite':
devcons.c:(.text+0x30dc): undefined reference to `consoleprint'
dis.o: In function `execatidle':
dis.c:(.text+0x2e4): undefined reference to `rungc'
dis.c:(.text+0x374): undefined reference to `gccolor'
dis.c:(.text+0x384): undefined reference to `gchalt'
dis.o: In function `newprog':
dis.c:(.text+0x7c0): undefined reference to `exNomem'
dis.c:(.text+0x7d4): undefined reference to `xec'
dis.c:(.text+0x7d8): undefined reference to `mutator'
dis.c:(.text+0x7dc): undefined reference to `nprop'
dis.o: In function `delprog':
dis.c:(.text+0x83c): undefined reference to `closeegrp'
dis.o: In function `exprog':
dis.c:(.text+0xcb0): undefined reference to `altdone'
dis.c:(.text+0xccc): undefined reference to `cqdelp'
dis.c:(.text+0xce8): undefined reference to `cqdelp'
dis.o: In function `killprog':
dis.c:(.text+0xff4): undefined reference to `altdone'
dis.c:(.text+0x1010): undefined reference to `cqdelp'
dis.c:(.text+0x102c): undefined reference to `cqdelp'
dis.c:(.text+0x1124): undefined reference to `dbgexit'
dis.c:(.text+0x119c): undefined reference to `destroystack'
dis.c:(.text+0x11ec): undefined reference to `gchalt'
dis.o: In function `killcomm':
dis.c:(.text+0x19e4): undefined reference to `altgone'
dis.o: In function `schedmod':
dis.c:(.text+0x1ef8): undefined reference to `mklinkmod'
dis.c:(.text+0x1f3c): undefined reference to `nheap'
dis.c:(.text+0x1f90): undefined reference to `newmp'
dis.c:(.text+0x1ff8): undefined reference to `newstack'
dis.c:(.text+0x2014): undefined reference to `initmem'
dis.c:(.text+0x202c): undefined reference to `R'
dis.o: In function `acquire':
dis.c:(.text+0x2158): undefined reference to `irestore'
dis.o: In function `release':
dis.c:(.text+0x2210): undefined reference to `isave'
dis.o: In function `progexit':
dis.c:(.text+0x26bc): undefined reference to `dbgexit'
dis.c:(.text+0x2738): undefined reference to `isave'
dis.c:(.text+0x2768): undefined reference to `destroystack'
dis.c:(.text+0x27ac): undefined reference to `R'
dis.c:(.text+0x27c0): undefined reference to `gchalt'
dis.o: In function `vmachine':
dis.c:(.text+0x2910): undefined reference to `handler'
dis.c:(.text+0x2a60): undefined reference to `FPrestore'
dis.c:(.text+0x2a84): undefined reference to `FPsave'
dis.c:(.text+0x2b68): undefined reference to `rungc'
dis.o: In function `disinit':
dis.c:(.text+0x2c58): undefined reference to `addclock0link'
dis.c:(.text+0x2c5c): undefined reference to `fpinit'
dis.c:(.text+0x2c74): undefined reference to `FPsave'
dis.c:(.text+0x2c78): undefined reference to `opinit'
dis.c:(.text+0x2c80): undefined reference to `excinit'
dis.c:(.text+0x2c88): undefined reference to `load'
dis.c:(.text+0x2e38): undefined reference to `Dconv'
proc.o: In function `sleep':
proc.c:(.text+0xb58): undefined reference to `dumpstack'
proc.o: In function `tsleep':
proc.c:(.text+0xf68): undefined reference to `talarm'
proc.c:(.text+0xf6c): undefined reference to `talarm'
proc.o: In function `pexit':
proc.c:(.text+0x11b8): undefined reference to `closeegrp'
proc.o: In function `kproc':
proc.c:(.text+0x1520): undefined reference to `kprocchild'
random.o: In function `randominit':
random.c:(.text+0x2d4): undefined reference to `addclock0link'
sysfile.o: In function `kfauth':
sysfile.c:(.text+0x1018): undefined reference to `mntauth'
sysfile.o: In function `kfversion':
sysfile.c:(.text+0x1230): undefined reference to `mntversion'

Lets fix these issues one-by one:

  1. idle

Add definition to fns.h:

#include "../port/portfns.h"

#define coherence()     /* nothing needed for uniprocessor */
#define procsave(p)     /* Save the mach part of the current */ 
                        /* process state, no need for one cpu */
#define waserror()  (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
#define KADDR(p)    ((void *)p)
#define PADDR(p)    ((ulong)p)

void    (*screenputs)(char*, int);
void    (*idle)(void);

void archreset(void);
void dmareset(void);
void idlehands(void);
  1. mutator

Grep shows taht mutator is a variable defined in libinterp. Lets add this lib to lib section in lpc-e2468:

dev

port
  alloc
  allocb
  chan
  dev
  devcons
  dis
  parse
  pgrp
  print
  proc
  qio
  qlock
    random
  sysfile
  taslock
  xalloc

code
    int consoleprint = 1;

lib
  interp
    kern

init
    bootinit

root
  /dev  /

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/proc.c
../port/proc.c: In function 'errorf':
../port/proc.c:570:2: warning: useless type name in empty declaration [enabled by default]
  va_end(arg);
  ^
../port/proc.c: In function 'kwerrstr':
../port/proc.c:622:2: warning: useless type name in empty declaration [enabled by default]
  va_end(arg);
  ^
../port/proc.c: In function 'werrstr':
../port/proc.c:634:2: warning: useless type name in empty declaration [enabled by default]
  va_end(arg);
  ^
arm-none-eabi-gcc -c -x assembler-with-cpp -mcpu=arm7tdmi-s -c lpc-e2468.root.s
(cd /home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp ; mk SHELLTYPE=sh SYSTARG=Inferno OBJTYPE=arm-gcc install)
mk: no recipe to make 'comp-arm-gcc.o'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a doesn't exist: assuming it will be an archive
mk:  echo "(cd ...  : exit status=exit(1)

This fails because libinterp has some architecture-specific parts and the name of the arch-specific file is based on OBJTYPE variable we set in mkfile. We know that we have ARM architecture, lets just create link comp-arm-gcc.c -> comp-arm.c in libinterp directory.

After that we can rebuild:

dlm-Inferno.c:43:2: warning: implicit declaration of function 'signof' [-Wimplicit-function-declaration]
  v = addr("XXX", "module", o, signof(char*));
  ^
dlm-Inferno.c:43:38: error: expected expression before 'char'
  v = addr("XXX", "module", o, signof(char*));
                                      ^
dlm-Inferno.c:48:37: error: expected expression before 'Runtab'
  r = addr(name, "modtab", o, signof(Runtab[]));
                                     ^
mk:  echo "(cd ...  : exit status=exit(1)

signof turns out to be some built-in procedure in Inferno C compiler, which we just dont have in gcc.

If we check how addr works, it becomes obvious that we dont need sig argument actually, so we can replace signof with any other macro taking type as an argument. Lets replace it with sizeof by defining this macro:

-D'signof(type_t)=sizeof(type_t)'

Put it in mkfiles/mkfile-Inferno-arm-gcc:

TARGMODEL=  Inferno
TARGSHTYPE= rc
CPUS=       arm

O=      o
OS=     o

AR=     arm-none-eabi-ar
ARFLAGS= ruvs

AS=arm-none-eabi-gcc -c
ASFLAGS= -x assembler-with-cpp -mcpu=arm7tdmi-s -c

CC=arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c
CFLAGS= -O\
        -Wuninitialized -Wno-unused -Wreturn-type -Wimplicit\
        -I$ROOT/Inferno/arm/include\
        -I$ROOT/include\
        -I$ROOT/os/lpc-e2468\
        -DLINUX_ARM\
        -D'signof(type_t)=sizeof(type_t)'\

ANSICPP= -p

LD=arm-none-eabi-gcc
LDFLAGS=-nostartfiles 

SYSLIBS=

YACC=       yacc
YFLAGS=     -d

Rebuild:

inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a doesn't exist: assuming it will be an archive
arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -O -Wuninitialized -Wno-unused -Wreturn-type -Wimplicit -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/os/lpc-e2468 -DLINUX_ARM -Dsignof(type_t)=sizeof(type_t) dlm-Inferno.c
mk: no recipe to make 'das-arm-gcc.o'
dlm-Inferno.c: In function 'newdyncode':
dlm-Inferno.c:48:37: error: invalid application of 'sizeof' to incomplete type 'struct Runtab[]'
  r = addr(name, "modtab", o, signof(Runtab[]));
                                     ^
<command-line>:0:23: note: in definition of macro 'signof'
mk:  echo "(cd ...  : exit status=exit(1)

Somehow gcc doesn't like Runtab arary, but likes Runtab pointer. Why ? I dont know. Here is the diff:

diff -r abaabece21b7 libinterp/dlm-Inferno.c
--- a/libinterp/dlm-Inferno.c   Sun May 31 02:30:48 2015 +0300
+++ b/libinterp/dlm-Inferno.c   Sun May 31 04:01:28 2015 +0300
@@ -45,7 +45,7 @@
        goto Error;
    name = *(char**)v;
    DBG("module name is %s\n", name);
-   r = addr(name, "modtab", o, signof(Runtab[]));
+   r = addr(name, "modtab", o, signof(Runtab*));
    if(r == nil)
        goto Error;
    m = builtinmod(name, r, 0);

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
arm-none-eabi-gcc -c -x assembler-with-cpp -mcpu=arm7tdmi-s -c lpc-e2468.root.s
(cd /home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp ; mk SHELLTYPE=sh SYSTARG=Inferno OBJTYPE=arm-gcc install)
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a doesn't exist: assuming it will be an archive
arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -O -Wuninitialized -Wno-unused -Wreturn-type -Wimplicit -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/os/lpc-e2468 -DLINUX_ARM -Dsignof(type_t)=sizeof(type_t) comp-arm-gcc.c
mk: no recipe to make 'das-arm-gcc.o'
comp-arm-gcc.c: In function 'urk':
comp-arm-gcc.c:352:2: warning: useless type name in empty declaration [enabled by default]
  USED(s);
  ^
mk:  echo "(cd ...  : exit status=exit(1)

Lets link das-arm-gcc.c to das-arm.c and rebuild:

In file included from conv.c:4:0:
/home/snegovick/dev/inferno/inferno-os-lpc2468/include/mathi.h:34:15: error: conflicting types for 'strtod'
 extern double strtod(const char *, char **);
               ^
In file included from /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm/include/lib9.h:2:0,
                 from conv.c:1:
/home/snegovick/dev/inferno/inferno-os-lpc2468/include/kern.h:366:15: note: previous declaration of 'strtod' was here
 extern double strtod(char*, char**);
               ^
mk: arm-none-eabi-gcc -O0 -std=c1x ...  : exit status=exit(1)
mk:  echo "(cd ...  : exit status=exit(1)

Check what it should look like:

man strtod

STRTOD(3)                                   Linux Programmer's Manual                                   STRTOD(3)

NAME
       strtod, strtof, strtold - convert ASCII string to floating-point number

SYNOPSIS
       #include <stdlib.h>

       double strtod(const char *nptr, char **endptr);
       float strtof(const char *nptr, char **endptr);
       long double strtold(const char *nptr, char **endptr);

Fix kern.h accordingly:

diff -r abaabece21b7 include/kern.h
--- a/include/kern.h    Sun May 31 02:30:48 2015 +0300
+++ b/include/kern.h    Sun May 31 04:08:55 2015 +0300
@@ -363,7 +363,7 @@
 extern int putenv(char*, char*);
 extern void    qsort(void*, long, long, int (*)(void*, void*));
 /*extern   int setjmp(jmp_buf);*/
-extern double  strtod(char*, char**);
+extern double  strtod(const char*, char**);
 extern long    strtol(char*, char**, int);
 extern ulong   strtoul(char*, char**, int);
 extern vlong   strtoll(const char*, char**, int);

Rebuild:

gcc -lm -o ilpc-e2468.elf
   arm-none-eabi-objcopy -O binary ilpc-e2468.elf ilpc-e2468.bin
   arm-none-eabi-size ./ilpc-e2468.elf
allocb.o: In function `_allocb':
allocb.c:(.text+0x84): undefined reference to `ROUND'
chan.o: In function `chanfree':
chan.c:(.text+0xa7c): undefined reference to `muxclose'
devcons.o: In function `putstrn0':
devcons.c:(.text+0x49c): undefined reference to `consoleprint'
devcons.o: In function `iprint':
devcons.c:(.text+0x80c): undefined reference to `uartputs'
devcons.o: In function `panic':
devcons.c:(.text+0x8f4): undefined reference to `dumpstack'
devcons.o: In function `echo':
devcons.c:(.text+0xcc8): undefined reference to `consoleprint'
devcons.o: In function `kbdputc':
devcons.c:(.text+0x13c0): undefined reference to `latin1'
devcons.o: In function `consread':
devcons.c:(.text+0x2590): undefined reference to `genrandom'
devcons.o: In function `conswrite':
devcons.c:(.text+0x30dc): undefined reference to `consoleprint'
dis.o: In function `delprog':
dis.c:(.text+0x83c): undefined reference to `closeegrp'
dis.o: In function `killprog':
dis.c:(.text+0x1124): undefined reference to `dbgexit'
dis.o: In function `progexit':
dis.c:(.text+0x26bc): undefined reference to `dbgexit'
dis.o: In function `vmachine':
dis.c:(.text+0x2910): undefined reference to `handler'
dis.c:(.text+0x2a60): undefined reference to `FPrestore'
dis.c:(.text+0x2a84): undefined reference to `FPsave'
dis.o: In function `disinit':
dis.c:(.text+0x2c58): undefined reference to `addclock0link'
dis.c:(.text+0x2c5c): undefined reference to `fpinit'
dis.c:(.text+0x2c74): undefined reference to `FPsave'
dis.c:(.text+0x2c80): undefined reference to `excinit'
proc.o: In function `sleep':
proc.c:(.text+0xb58): undefined reference to `dumpstack'
proc.o: In function `tsleep':
proc.c:(.text+0xf68): undefined reference to `talarm'
proc.c:(.text+0xf6c): undefined reference to `talarm'
proc.o: In function `pexit':
proc.c:(.text+0x11b8): undefined reference to `closeegrp'
proc.o: In function `kproc':
proc.c:(.text+0x1520): undefined reference to `kprocchild'
random.o: In function `randominit':
random.c:(.text+0x2d4): undefined reference to `addclock0link'
sysfile.o: In function `kfauth':
sysfile.c:(.text+0x1018): undefined reference to `mntauth'
sysfile.o: In function `kfversion':
sysfile.c:(.text+0x1230): undefined reference to `mntversion'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(readmod.o): In function `readmod':
readmod.c:(.text+0x118): undefined reference to `dynldable'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(comp-arm-gcc.o): In function `typecom':
comp-arm-gcc.c:(.text+0x442c): undefined reference to `segflush'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(comp-arm-gcc.o): In function `compile':
comp-arm-gcc.c:(.text+0x45b0): undefined reference to `segflush'
comp-arm-gcc.c:(.text+0x4ac8): undefined reference to `segflush'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(dlm-Inferno.o): In function `addr':
dlm-Inferno.c:(.text+0x60): undefined reference to `dynimport'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(dlm-Inferno.o): In function `newdyncode':
dlm-Inferno.c:(.text+0xd4): undefined reference to `dynld'
dlm-Inferno.c:(.text+0x1cc): undefined reference to `dynobjfree'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(dlm-Inferno.o): In function `freedyncode':
dlm-Inferno.c:(.text+0x208): undefined reference to `dynobjfree'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o): In function `xprint':
runt.c:(.text+0x984): undefined reference to `syserr'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o): In function `sysmodinit':
runt.c:(.text+0xb98): undefined reference to `sysinit'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x8): undefined reference to `Sys_announce'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x50): undefined reference to `Sys_bind'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0xbc): undefined reference to `Sys_chdir'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0xe0): undefined reference to `Sys_create'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x104): undefined reference to `Sys_dial'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x128): undefined reference to `Sys_dirread'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x14c): undefined reference to `Sys_dup'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x170): undefined reference to `Sys_export'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x194): undefined reference to `Sys_fauth'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x1b8): undefined reference to `Sys_fd2path'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x1dc): undefined reference to `Sys_fildes'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x200): undefined reference to `Sys_file2chan'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x224): undefined reference to `Sys_fprint'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x248): undefined reference to `Sys_fstat'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x26c): undefined reference to `Sys_fversion'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x290): undefined reference to `Sys_fwstat'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x2b4): undefined reference to `Sys_iounit'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x2d8): undefined reference to `Sys_listen'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x2fc): undefined reference to `Sys_millisec'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x320): undefined reference to `Sys_mount'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x344): undefined reference to `Sys_open'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x368): undefined reference to `Sys_pctl'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x38c): undefined reference to `Sys_pipe'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x3b0): undefined reference to `Sys_pread'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x3d4): undefined reference to `Sys_print'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x3f8): undefined reference to `Sys_pwrite'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x41c): undefined reference to `Sys_read'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x440): undefined reference to `Sys_readn'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x464): undefined reference to `Sys_remove'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x488): undefined reference to `Sys_seek'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x4ac): undefined reference to `Sys_sleep'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x4f4): undefined reference to `Sys_stat'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x518): undefined reference to `Sys_stream'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x560): undefined reference to `Sys_unmount'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x5a8): undefined reference to `Sys_werrstr'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x5cc): undefined reference to `Sys_write'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a(runt.o):(.data+0x5f0): undefined reference to `Sys_wstat'
/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libkern.a(charstod.o): In function `charstod':
charstod.c:(.text+0x78): undefined reference to `NaN'
charstod.c:(.text+0xe4): undefined reference to `NaN'
charstod.c:(.text+0x134): undefined reference to `NaN'
charstod.c:(.text+0x1a0): undefined reference to `NaN'
charstod.c:(.text+0x1f8): undefined reference to `NaN'

Fix undefined ROUND in mem.h:

#define KiB     1024u       /*! Kibi 0x0000000000000400 */
#define MiB     1048576u    /*! Mebi 0x0000000000100000 */
#define GiB     1073741824u /*! Gibi 000000000040000000 */

#define KSTKSIZE    (8*KiB*2)
#define KSTACK      KSTKSIZE

#define KZERO       0xa0008000              /*! kernel address space */
#define MACHADDR    (KZERO+0x00001000)          /*! Mach structure */
#define BY2PG       (4*KiB)                 /*! bytes per page */
#define BY2V        8                       /*! only used in xalloc.c */
#define ROUND(s,sz) (((s)+(sz-1))&~(sz-1))
#define PGROUND(s)  ROUND(s, BY2PG)

/*
 * PSR
 */
#define PsrMusr     0x10    /* mode */
#define PsrMfiq     0x11 
#define PsrMirq     0x12
#define PsrMsvc     0x13
#define PsrMabt     0x17
#define PsrMund     0x1B
#define PsrMsys     0x1F
#define PsrMask     0x1F

#define PsrDfiq     0x00000040  /* disable FIQ interrupts */
#define PsrDirq     0x00000080  /* disable IRQ interrupts */

#define PsrV        0x10000000  /* overflow */
#define PsrC        0x20000000  /* carry/borrow/extend */
#define PsrZ        0x40000000  /* zero */
#define PsrN        0x80000000  /* negative/less than */

Fix undefined muxclose by adding mnt to dev section in lpc-e2468:

dev
  mnt

port
  alloc
  allocb
  chan
  dev
  devcons
  dis
  parse
  pgrp
  print
  proc
  qio
  qlock
    random
  sysfile
  taslock
  xalloc

code
    int consoleprint = 1;

lib
  interp
    kern

init
    bootinit

root
  /dev  /

Fix cinit, cread, copen, cwrite etc. by adding nocache module to port section in lpc-e2468:

dev
  mnt

port
  alloc
  allocb
  chan
  dev
  devcons
  dis
  nocache
  parse
  pgrp
  print
  proc
  qio
  qlock
  random
  sysfile
  taslock
  xalloc

code
    int consoleprint = 1;

lib
  interp
    kern

init
    bootinit

root
  /dev  /

Add latin1 module to port section in lpc-e2468 to fix undefine latin1:

dev
  mnt

port
  alloc
  allocb
  chan
  dev
  devcons
  dis
  latin1
  nocache
  parse
  pgrp
  print
  proc
  qio
  qlock
  random
  sysfile
  taslock
  xalloc

code
    int consoleprint = 1;

lib
  interp
    kern

init
    bootinit

root
  /dev  /

Remove devcons from port section and add cons and env to dev section:

dev
  env
  mnt
  cons

port
  alloc
  allocb
  chan
  dev
  dis
  latin1
  nocache
  parse
  pgrp
  print
  proc
  qio
  qlock
    random
  sysfile
  taslock
  xalloc

code
    int consoleprint = 1;

lib
  interp
    kern

init
    bootinit

root
  /dev  /

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/devenv.c
../port/devenv.c: In function 'envgen':
../port/devenv.c:19:1: error: parameter name omitted
 envgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
 ^
../port/devenv.c:19:1: error: parameter name omitted
../port/devenv.c:19:1: error: parameter name omitted
../port/devenv.c: In function 'envcreate':
../port/devenv.c:102:1: error: parameter name omitted
 envcreate(Chan *c, char *name, int mode, ulong)
 ^
../port/devenv.c: In function 'ksetenv':
../port/devenv.c:320:1: error: parameter name omitted
 ksetenv(char *var, char *val, int)
 ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Fix these:

diff -r abaabece21b7 os/port/devenv.c
--- a/os/port/devenv.c  Sun May 31 02:30:48 2015 +0300
+++ b/os/port/devenv.c  Sun May 31 04:25:05 2015 +0300
@@ -16,7 +16,7 @@
 };

 static int
-envgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
+envgen(Chan *c, char* ch, Dirtab* d, int i, int s, Dir *dp)
 {
    Egrp *eg;
    Evalue *e;
@@ -99,7 +99,7 @@
 }

 static void
-envcreate(Chan *c, char *name, int mode, ulong)
+envcreate(Chan *c, char *name, int mode, ulong u)
 {
    Egrp *eg;
    Evalue *e, **le;
@@ -317,7 +317,7 @@
 }

 void
-ksetenv(char *var, char *val, int)
+ksetenv(char *var, char *val, int i)
 {
    Chan *c;
    char buf[2*KNAMELEN];

To fix multiple Sys* entries, add inferno module to port section:

dev
  env
  mnt
  cons

port
  alloc
  allocb
  chan
  dev
  dis
  inferno
  latin1
  nocache
  parse
  pgrp
  print
  proc
  qio
  qlock
    random
  sysfile
  taslock
  xalloc

code
    int consoleprint = 1;

lib
  interp
    kern

init
    bootinit

root
  /dev  /

Dyn-related stuff is fixed by adding nodynld to port section.

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/nodynld.c
../port/nodynld.c: In function 'dynimport':
../port/nodynld.c:15:1: error: parameter name omitted
 dynimport(Dynobj*, char*, ulong)
 ^
../port/nodynld.c:15:1: error: parameter name omitted
../port/nodynld.c:15:1: error: parameter name omitted
../port/nodynld.c: In function 'dynobjfree':
../port/nodynld.c:21:1: error: parameter name omitted
 dynobjfree(Dynobj*)
 ^
../port/nodynld.c: In function 'kdynloadfd':
../port/nodynld.c:28:2: warning: useless type name in empty declaration [enabled by default]
  USED(fd, tab, ntab);
  ^
../port/nodynld.c: In function 'kdynloadable':
../port/nodynld.c:33:1: error: parameter name omitted
 kdynloadable(int)
 ^
../port/nodynld.c: In function 'dynld':
../port/nodynld.c:39:1: error: parameter name omitted
 dynld(int)
 ^
../port/nodynld.c: In function 'dynldable':
../port/nodynld.c:45:1: error: parameter name omitted
 dynldable(int)
 ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Fix port/nodynld.c:

diff -r abaabece21b7 os/port/nodynld.c
--- a/os/port/nodynld.c Sun May 31 02:30:48 2015 +0300
+++ b/os/port/nodynld.c Sun May 31 04:30:09 2015 +0300
@@ -12,13 +12,13 @@
  */

 void*
-dynimport(Dynobj*, char*, ulong)
+dynimport(Dynobj* d, char* c, ulong u)
 {
    return nil;
 }

 void
-dynobjfree(Dynobj*)
+dynobjfree(Dynobj* d)
 {
 }

@@ -30,19 +30,19 @@
 }

 int
-kdynloadable(int)
+kdynloadable(int i)
 {
    return 0;
 }

 Dynobj*
-dynld(int)
+dynld(int i)
 {
    return nil;
 }

 int
-dynldable(int)
+dynldable(int i)
 {
    return 0;
 }

klisten, kannounce, kdial etc. are fixed by adding dial to port section.

dbgexit is defined in devprog, so add prog to dev section in lpc-e2468 and rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/devprog.c
../port/devprog.c: In function 'proggen':
../port/devprog.c:157:1: error: parameter name omitted
 proggen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp)
 ^
../port/devprog.c: In function 'progwrite':
../port/devprog.c:1032:2: warning: useless type name in empty declaration [enabled by default]
  USED(offset);
  ^
../port/devprog.c:1033:2: warning: useless type name in empty declaration [enabled by default]
  USED(va);
  ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Fix port/devprog.c:

diff -r abaabece21b7 os/port/devprog.c
--- a/os/port/devprog.c Sun May 31 02:30:48 2015 +0300
+++ b/os/port/devprog.c Sun May 31 04:34:12 2015 +0300
@@ -154,7 +154,7 @@
 static  char   Emisalign[] = "misaligned address";

 static int
-proggen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp)
+proggen(Chan *c, char *name, Dirtab *tab, int i, int s, Dir *dp)
 {
    Qid qid;
    Prog *p;

Define segflush in main.c:

int
segflush(void* v, ulong u) {
  return 1;
}

Add srv to dev section to define srvf2c. Add alarm to port section to define talarm.

To get rid of NaN undefs, add math to lib section. excinit is defined by adding exception to port section. To define export, add exportfs to port section.

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/exportfs.c
../port/exportfs.c: In function 'exwork':
../port/exportfs.c:503:1: error: parameter name omitted
 exwork(void*)
 ^
../port/exportfs.c: In function 'exslave':
../port/exportfs.c:509:1: error: parameter name omitted
 exslave(void*)
 ^

Fix port/exportfs.c:

diff -r abaabece21b7 os/port/exportfs.c
--- a/os/port/exportfs.c    Sun May 31 02:30:48 2015 +0300
+++ b/os/port/exportfs.c    Sun May 31 04:47:51 2015 +0300
@@ -500,13 +500,13 @@
 }

 static int
-exwork(void*)
+exwork(void* v)
 {
    return exq.head != nil;
 }

 static void
-exslave(void*)
+exslave(void* v)
 {
    Export *fs;
    Exq *q, *t, *fq, **last;

Lets fix fp-related things by adding these lines to main.c:

void
fpinit(void) {
}

void
FPsave(void* v) {
}

void
FPrestore(void* v) {
}

Add uart to dev section and rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
    arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -I. ../port/devuart.c
../port/devuart.c: In function 'uartwrite':
../port/devuart.c:482:1: error: parameter name omitted
 uartwrite(Chan *c, void *buf, long n, vlong)
 ^
mk:  arm-none-eabi-gcc -O0 ...  : exit status=exit(1)

Fix port/devuart.c:

diff -r abaabece21b7 os/port/devuart.c
--- a/os/port/devuart.c Sun May 31 02:30:48 2015 +0300
+++ b/os/port/devuart.c Sun May 31 04:56:26 2015 +0300
@@ -479,7 +479,7 @@
 }

 static long
-uartwrite(Chan *c, void *buf, long n, vlong)
+uartwrite(Chan *c, void *buf, long n, vlong v)
 {
    Uart *p;
    char *cmd;

Fix undefined physuart by adding this to main.c:

#include "../port/uart.h"
PhysUart* physuart[1];

Define kprocchild in main.c:

static void
linkproc(void) {
    spllo();
    if (waserror())
        print("error() underflow: %r\n");
    else
        (*up->kpfun)(up->arg);
    pexit("end proc", 1);
}

void
kprocchild(Proc *p, void (*func)(void*), void *arg) {
    p->sched.pc = (ulong)linkproc;
    p->sched.sp = (ulong)p->kstack+KSTACK-8;

    p->kpfun = func;
    p->arg = arg;
}

Now we are left with a few undefs:

  • dumpstack
  • addclock0link
  • genrandom
  • consoleprint

  • dumpstack : add file os/lpc-e2468-olimex/dump.c:

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "ureg.h"
#include <stdbool.h>

#define isvalid_va(v) true
#define isvalid_wa(v) true

void
dumplongs(char *msg, ulong *v, int n)
{
    int i, l;

    l = 0;
    iprint("%s at %.8p: ", msg, v);
    for(i=0; i<n; i++){
        if(l >= 4){
            iprint("\n    %.8p: ", v);
            l = 0;
        }
        if(isvalid_va(v)){
            iprint(" %.8lux", *v++);
            l++;
        }else{
            iprint(" invalid");
            break;
        }
    }
    iprint("\n");
}

static void
_dumpstack(Ureg *ureg)
{
    ulong *v, *l;
    ulong inst;
    ulong *estack;
    int i;

    l = (ulong*)(ureg+1);
    if(!isvalid_wa(l)){
        iprint("invalid ureg/stack: %.8p\n", l);
        return;
    }
    print("ktrace /kernel/path %.8ux %.8ux %.8ux\n" 
        ,ureg->pc, ureg->sp, ureg->r14);
    if(up != nil && l >= (ulong*)up->kstack 
        && l <= (ulong*)(up->kstack+KSTACK-4))
        estack = (ulong*)(up->kstack+KSTACK);
    else if(l >= (ulong*)m->stack && l <= (ulong*)((ulong)m+BY2PG-4))
        estack = (ulong*)((ulong)m+BY2PG-4);
    else{
        iprint("unknown stack\n");
        return;
    }
    i = 0;
    for(; l<estack; l++) {
        if(!isvalid_wa(l)) {
            iprint("invalid(%8.8p)", l);
            break;
        }
        v = (ulong*)*l;
        if(isvalid_wa(v)) {
            inst = v[-1];
            if((inst & 0x0ff0f000) == 0x0280f000 &&
                 (*(v-2) & 0x0ffff000) == 0x028fe000    ||
                (inst & 0x0f000000) == 0x0b000000) {
                iprint("%8.8p=%8.8lux ", l, v);
                i++;
            }
        }
        if(i == 4){
            iprint("\n");
            i = 0;
        }
    }
    if(i)
        print("\n");
}

/*
 * Fill in enough of Ureg to get a stack trace, and call a function.
 * Used by debugging interface rdb.
 */
void
callwithureg(void (*fn)(Ureg*))
{
    Ureg ureg;
    ureg.pc = getcallerpc(&fn);
    ureg.sp = (ulong)&fn;
    ureg.r14 = 0;
    fn(&ureg);
}

void
dumpstack(void)
{
    callwithureg(_dumpstack);
}

void
dumparound(uint addr)
{
    uint addr0 = (addr/16)*16;
    int a_row, a_col;
    uchar ch, *cha;
    uint c;
    /* +-32 bytes to print */
    print("%8.8uX:\n", addr0 +(-2)*16);
    for (a_col = 0; a_col<16; ++a_col) {
        print(" %.2uX", a_col);
    }
    print("\n");

    for (a_row = -2; a_row < 3; ++a_row) {
        for (a_col = 0; a_col<16; ++a_col) {
            cha = (uchar *)(addr0 +a_row*16+a_col);
            ch = *cha;
            c = ch;
            if (cha == (uchar *)addr)
                print(">%2.2uX", c);
            else print(" %2.2uX", c);
        }
        print("\n");
    }
    print("\n");
}

void
dumpregs(Ureg* ureg)
{
    print("\n");
    print("PSR %8.8uX type %2.2uX PC %8.8uX LINK %8.8uX\n",
        ureg->psr, ureg->type, ureg->pc, ureg->link);
    print("R14 %8.8uX R13 %8.8uX R12 %8.8uX R11 %8.8uX R10 %8.8uX\n",
        ureg->r14, ureg->r13, ureg->r12, ureg->r11, ureg->r10);
    print("R9  %8.8uX R8  %8.8uX R7  %8.8uX R6  %8.8uX R5  %8.8uX\n",
        ureg->r9, ureg->r8, ureg->r7, ureg->r6, ureg->r5);
    print("R4  %8.8uX R3  %8.8uX R2  %8.8uX R1  %8.8uX R0  %8.8uX\n",
        ureg->r4, ureg->r3, ureg->r2, ureg->r1, ureg->r0);
    print("Stack is at: %8.8luX\n", ureg);
    print("PC %8.8lux LINK %8.8lux\n", (ulong)ureg->pc, (ulong)ureg->link);

    if(up)
        print("Process stack:  %8.8lux-%8.8lux\n",
            up->kstack, up->kstack+KSTACK-4);
    else
        print("System stack: %8.8lux-%8.8lux\n",
            (ulong)(m+1), (ulong)m+BY2PG-4);
    dumplongs("stack", (ulong *)(ureg + 1), 16);
    _dumpstack(ureg);
    dumparound(ureg->pc);
}

Don't forget to add this file to mkfile.

Add file os/lpc-e2468-olimex/clock.c:

#include "bsp_timer.h"
#include "trap.h"

static ulong timer_incr[4] = { 0, 0, 0, -1 };

typedef struct Clock0link Clock0link;
typedef struct Clock0link {
    void        (*clock)(void);
    Clock0link* link;
} Clock0link;

static Clock0link *clock0link;
static Lock clock0lock;
static void (*prof_fcn)(Ureg *, int);

Timer*
addclock0link(void (*clock)(void), int i)
{
    Clock0link *lp;

    if((lp = malloc(sizeof(Clock0link))) == 0){
        print("addclock0link: too many links\n");
        return nil;
    }
    ilock(&clock0lock);
    lp->clock = clock;
    lp->link = clock0link;
    clock0link = lp;
    iunlock(&clock0lock);
    return nil;
}

static void
profintr(Ureg *ur, void* v)
{
    /* OstmrReg *ost = OSTMRREG; */
    /* int t; */

    /* if((ost->osmr[3] - ost->oscr) < 2*CLOCKFREQ) { */
    /*  /\* less than 2 seconds before reset, say something *\/ */
    /*  setpanic(); */
    /*  clockpoll(); */
    /*  dumpregs(ur); */
    /*  panic("Watchdog timer will expire"); */
    /* } */

    /* /\* advance the profile clock tick *\/ */
    /* ost->osmr[2] += timer_incr[2]; */
    /* ost->ossr = (1 << 2);            /\* Clear the SR *\/ */
    /* t = 1; */
    /* while((ost->osmr[2] - ost->oscr) > 0x80000000) { */
    /*  ost->osmr[2] += timer_incr[2]; */
    /*  t++; */
    /* } */
    /* if(prof_fcn) */
    /*  prof_fcn(ur, t); */
}

static void
clockintr(Ureg* u, void* v)
{
    Clock0link *lp;

    m->ticks++;

    checkalarms();

    if(canlock(&clock0lock)){
        for(lp = clock0link; lp; lp = lp->link)
            if(lp->clock)
                lp->clock();
        unlock(&clock0lock);
    }

    /* round robin time slice is done by trap.c and proc.c */
}

void
timerenable( int timer, int Hz, void (*f)(Ureg *, void*), void* a)
{
    char name[KNAMELEN];

    if(timer < 0 || timer > 3)
        return;
    timer_incr[timer] = CLOCKFREQ/Hz;       /* set up freq */
    snprint(name, sizeof(name), "timer%d", timer);
  timer_enable(timer, Hz);
    intrenable(Timerbit(timer), f, a, BusCPU, name);
}

void
timerdisable( int timer )
{
    if(timer < 0 || timer > 3)
        return;
  timer_disable(timer);
}

void
installprof(void (*pf)(Ureg *, int))
{
//  int s;

    /* s = splfhi(); */
    /* prof_fcn = pf; */
    /* timerenable( 2, HZ+1, profintr, 0); */
    /* timer_incr[2] = timer_incr[0]+63;    /\* fine tuning *\/ */
    /* splx(s); */
}

void
clockinit(void)
{
    m->ticks = 0;
    timerenable( 0, HZ, clockintr, 0);
//  timer_incr[3] = CLOCKFREQ*10;   /* 10 second watchdog */
//  timer_setwatchdog(timer_incr[3]);
//  timerenable( 2, 1, profintr, 0);    /* watch the watchdog */
}

void
clockpoll(void)
{
}

void
clockcheck(void)
{
}

// macros for fixed-point math

ulong _mularsv(ulong m0, ulong m1, ulong a, ulong s) {
  uint64_t m = m0*m1;
  m = m/a;
  m>>=s;
  return (uint32_t)m;
}

/* truncated: */
#define FXDPTDIV(a,b,n) ((ulong)(((uvlong)(a) << (n)) / (b)))
#define MAXMUL(a,n)     ((ulong)((((uvlong)1<<(n))-1)/(a)))
#define MULDIV(x,a,b,n) (((x)*FXDPTDIV(a,b,n)) >> (n)) 
#define MULDIV64(x,a,b,n) ((ulong)_mularsv(x, FXDPTDIV(a,b,n), 0, (n)))

/* rounded: */
#define FXDPTDIVR(a,b,n) ((ulong)((((uvlong)(a) << (n))+((b)/2)) / (b)))
#define MAXMULR(a,n)     ((ulong)((((uvlong)1<<(n))-1)/(a)))
#define MULDIVR(x,a,b,n) (((x)*FXDPTDIVR(a,b,n)+(1<<((n)-1))) >> (n)) 
#define MULDIVR64(x,a,b,n) ((ulong)_mularsv(x, FXDPTDIVR(a,b,n), 1<<((n)-1), (n)))


// these routines are all limited to a maximum of 1165 seconds,
// due to the wrap-around of the OSTIMER

ulong
timer_start(void)
{
    return timer_get_tc(0);
}

ulong
timer_ticks(ulong t0)
{
    return timer_get_tc(0) - t0;
}

int
timer_devwait(ulong *adr, ulong mask, ulong val, int ost)
{
    int i;
    ulong t0 = timer_start();
    while((*adr & mask) != val) 
        if(timer_ticks(t0) > ost)
            return ((*adr & mask) == val) ? 0 : -1;
        else
            for(i = 0; i < 10; i++);    /* don't pound OSCR too hard! (why not?) */
    return 0;
}

void
timer_setwatchdog(int t)
{
}

void
timer_delay(int t)
{   
    ulong t0 = timer_start();
    while(timer_ticks(t0) < t)
        ;
}


ulong
us2tmr(int us)
{
    return MULDIV64(us, CLOCKFREQ, 1000000, 24);
}

int
tmr2us(ulong t)
{
    return MULDIV64(t, 1000000, CLOCKFREQ, 24);
}

void
microdelay(int us)
{
    ulong t0 = timer_start();
    ulong t = us2tmr(us);
    while(timer_ticks(t0) <= t)
        ;
}

ulong
ms2tmr(int ms)
{
    return MULDIV64(ms, CLOCKFREQ, 1000, 20);
}

int
tmr2ms(ulong t)
{
    return MULDIV64(t, 1000, CLOCKFREQ, 32);
}

void
delay(int ms)
{
    ulong t0 = timer_start();
    ulong t = ms2tmr(ms);
    while(timer_ticks(t0) <= t)
        clockpoll();
}

uvlong
fastticks(uvlong *hz)
{
    if(hz)
        *hz = HZ;
    return m->ticks;
}

Add file os/lpc-e2468-olimex/timer.c:

#include "timer.h"
#include "lpc24xx_irq.h"

#include "trap.h"

#define PCONP_TIM0  (1<<1)

#define PCLK_SEL0_SET_TIM0_01 {PCLKSEL0 |= (1<<2); PCLKSEL0 &= ~(1<<3);}
#define TXIR_MR0 (1)
#define TXTCR_CR (1<<1)
#define TXTCR_CE (1)
#define TXMCR_MR0I (1)

static void timer0_irq_wrapper(void) {
  Handler h;
  if (trp_get_irqvec(Timerbit(0)))
    h.r(0, h.a);
  T0IR |= TXIR_MR0;
}

void timer_enable(unsigned int timer, unsigned int freq) {
  uint32_t mr = CLOCKFREQ/(freq-1);
  switch (timer) {
  case 0:
    PCONP |= PCONP_TIM0;
    PCLK_SEL0_SET_TIM0_01;
    T0TCR &= ~TXTCR_CR;
    //BSP_T0MCR |= TXMCR_MR0I | TXMCR_MR0S;
    T0MCR |= TXMCR_MR0I;
    T0MR0 = mr;
    T0IR |= TXIR_MR0;
    T0PR = 0;
    install_irq( TIMER0_INT, (void *)timer0_irq_wrapper, 1 );
    T0TCR = TXTCR_CE;
    break;
  case 1:
    break;
  case 2:
    break;
  case 3:
    break;
  default:
    return;
  }
  return;
}

void timer_disable(unsigned int timer) {
  T0TCR &= ~TXTCR_CE;
  T0TCR |= TXTCR_CR;
}

uint32_t timer_get_tc(unsigned int timer) {
  uint32_t t;
  switch (timer) {
  case 0:
    t = T0TC;
    break;
  case 1:
    t = T1TC;
    break;
  case 2:
    t = T2TC;
    break;
  case 3:
    t = T3TC;
    break;
  default:
    return 0;
  }
  return t;
}

Add file os/lpc-e2468-olimex/timer.h:

#ifndef __TIMER_H__
#define __TIMER_H__

#include <stdint.h>

#define CLOCKFREQ 57600000

void timer_enable(unsigned int timer, unsigned int freq);
void timer_disable(unsigned int timer);
uint32_t timer_get_tc(unsigned int timer);

#endif/*__TIMER_H__*/

Add file os/lpc-e2468-olimex/lpc24xx_irq.c:

/*****************************************************************************
 *   irq.c: Interrupt handler C file for NXP LPC23xx/24xx Family Microprocessors
 *
 *   Copyright(C) 2006, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2006.07.13  ver 1.00    Prelimnary version, first Release
 *
******************************************************************************/
#include "LPC24xx.h"            /* LPC23XX/24xx Peripheral Registers */
#include "lpc24xx_irq.h"

/* Initialize the interrupt controller */
/******************************************************************************
** Function name:       init_VIC
**
** Descriptions:        Initialize VIC interrupt controller.
** parameters:          None
** Returned value:      None
** 
******************************************************************************/
void init_VIC(void) 
{
    uint32_t i = 0;
    uint32_t *vect_addr, *vect_prio;

    /* initialize VIC*/
    VICIntEnClr = 0xffffffff;
    VICVectAddr = 0;
    VICIntSelect = 0;

    /* set all the vector and vector control register to 0 */
    for ( i = 0; i < VIC_SIZE; i++ )
    {
        vect_addr = (uint32_t *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + i*4);
        vect_prio = (uint32_t *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + i*4);
        *vect_addr = 0x0;   
        *vect_prio = 0xF;
    }
    return;
}

/******************************************************************************
** Function name:       install_irq
**
** Descriptions:        Install interrupt handler
** parameters:          Interrupt number, interrupt handler address, 
**                      interrupt priority
** Returned value:      true or false, return false if IntNum is out of range
** 
******************************************************************************/
uint32_t install_irq( uint32_t IntNumber, void *HandlerAddr, uint32_t Priority )
{
    uint32_t *vect_addr;
    uint32_t *vect_prio;

    VICIntEnClr = 1 << IntNumber;   /* Disable Interrupt */
    if ( IntNumber >= VIC_SIZE )
    {
        return ( 0 );
    }
    else
    {
        /* find first un-assigned VIC address for the handler */
        vect_addr = (uint32_t *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4);
        vect_prio = (uint32_t *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + IntNumber*4);
        *vect_addr = (uint32_t)HandlerAddr; /* set interrupt vector */
        *vect_prio = Priority;
        VICIntEnable = 1 << IntNumber;  /* Enable Interrupt */
        return( 1 );
    }
}

/******************************************************************************
**                            End Of File
******************************************************************************/

And os/lpc-e2468-olimex/lpc24xx_irq.h:

/******************************************************************************
 *   irq.h:  Interrupt related Header file for NXP LPC23xx/24xx Family 
 *   Microprocessors
 *
 *   Copyright(C) 2006, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2006.09.01  ver 1.00    Prelimnary version, first Release
 *
******************************************************************************/
#ifndef __IRQ_H 
#define __IRQ_H

#include "LPC24xx.h"
#include <stdint.h>

#define I_Bit           0x80
#define F_Bit           0x40

#define SYS32Mode       0x1F
#define IRQ32Mode       0x12
#define FIQ32Mode       0x11

#define HIGHEST_PRIORITY    0x01
#define LOWEST_PRIORITY     0x0F

#define WDT_INT         0
#define SWI_INT         1
#define ARM_CORE0_INT   2
#define ARM_CORE1_INT   3
#define TIMER0_INT      4
#define TIMER1_INT      5
#define UART0_INT       6
#define UART1_INT       7
#define PWM0_1_INT      8
#define I2C0_INT        9
#define SPI0_INT        10          /* SPI and SSP0 share VIC slot */
#define SSP0_INT        10
#define SSP1_INT        11
#define PLL_INT         12
#define RTC_INT         13
#define EINT0_INT       14
#define EINT1_INT       15
#define EINT2_INT       16
#define EINT3_INT       17
#define ADC0_INT        18
#define I2C1_INT        19
#define BOD_INT         20
#define EMAC_INT        21
#define USB_INT         22
#define CAN_INT         23
#define MCI_INT         24
#define GPDMA_INT       25
#define TIMER2_INT      26
#define TIMER3_INT      27
#define UART2_INT       28
#define UART3_INT       29
#define I2C2_INT        30
#define I2S_INT         31

#define VIC_SIZE        32

#define VECT_ADDR_INDEX 0x100
#define VECT_PRIO_INDEX 0x200

/* Be aware that, from compiler to compiler, nested interrupt will have to
be handled differently. More details can be found in Philips LPC2000
family app-note AN10381 */

/* unlike Keil CARM Compiler, in ARM's RealView compiler, don't save and 
restore registers into the stack in RVD as the compiler does that for you. 
See RVD ARM compiler Inline and embedded assemblers, "Rules for 
using __asm and asm keywords. */
static uint32_t sysreg;     /* used as LR register */
#define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode }
#define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg }

void init_VIC( void );
uint32_t install_irq( uint32_t IntNumber, void *HandlerAddr, uint32_t Priority );

#endif /* end __IRQ_H */

/******************************************************************************
**                            End Of File
******************************************************************************/

Add os/lpc-e2468-olimex/trap.c:

#include "trap.h"
#include <stdbool.h>

//enum {
//  MinGpioIRQbit = 11,
//  NumGpioIRQbits = MaxGPIObit-MinGpioIRQbit+1,
//  GpioIRQmask = ((1<<NumGpioIRQbits)-1)<<MinGpioIRQbit,
//};

static Handler irqvec[MaxIRQbit+1];
//static Handler gpiovec[NumGpioIRQbits];
static Lock veclock;

bool trp_get_irqvec(int n, Handler *h) {
  if (n>=MaxIRQbit) {
    return false;
  }
  h = &irqvec[n];
  return true;
}

void
intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
{
    int x;
    Handler *ie;

    ilock(&veclock);
    switch(tbdf) {
    case BUSUNKNOWN:
    case BusCPU:
        if(v < 0 || v > MaxIRQbit)
            panic("intrenable: irq source %d out of range", v);
        ie = &irqvec[v];
        if(ie->r != nil)
            iprint("duplicate irq: %d (%s)\n", v, ie->name);
        ie->r = f;
        ie->a = a;
        strncpy(ie->name, name, KNAMELEN-1);
        ie->name[KNAMELEN-1] = 0;

        //x = splfhi();
        /* Enable the interrupt by setting the mask bit */
        //splx(x);
        break;
    default:
        panic("intrenable: unknown irq bus %d", tbdf);
    }
    iunlock(&veclock);
}

void
trap(Ureg* ureg)
{
  uart0_puts("bsp:: trap\r\n");
}

Add file os/lpc-e2468-olimex/trap.h:

#ifndef __TRAP_H__
#define __TRAP_H__

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"

#include "ureg.h"

#define MaxIRQbit 31

#define Timerbit(x) ((x)<=1 ? 4+(x) : 26+(x))

enum {
    BusCPU= 1,
    BusGPIOfalling= 2,  /* falling edge */
    BusGPIOrising = 3,  /* rising edge */
    BusGPIOboth = 4,    /* both edges */
    BusMAX= 4,
    BUSUNKNOWN= -1,
};

typedef struct Handler Handler;

struct Handler {
    void    (*r)(Ureg*, void*);
    void    *a;
    int v;
    char    name[KNAMELEN];
    Handler *next;
};


#endif/*__TRAP_H__*/

Add these files to mkfile:

<../../mkconfig

CONF=lpc-e2468
CONFLIST=lpc-e2468

SYSTARG=Inferno
OBJTYPE=arm-gcc
INSTALLDIR=$ROOT/Inferno/$OBJTYPE/bin

<$ROOT/mkfiles/mkfile-$SYSTARG-$OBJTYPE

<| $SHELLNAME ../port/mkdevlist $CONF

OBJ=\
    load.$O\
    main.$O\
    uart.$O\
    archlpc2468.$O\
    port.$O\
    dump.$O\
    timer.$O\
    clock.$O\
    lpc24xx_irq.$O\
    trap.$O\
    $IP\
    $DEVS\
    $ETHERS\
    $LINKS\
    $PORT\
    $MISC\
    $OTHERS\
    $CONF.root.$O\

LIBNAMES=${LIBS:%=lib%.a}
LIBDIRS=$LIBS
CP=arm-none-eabi-objcopy

CFLAGS= -mcpu=arm7tdmi-s -I$ROOT/Inferno/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp -I./ -DLINUX_ARM
KERNDATE=`{$NDATE}

HFILES=\
    uart.h\
    timer.h
    dat.h\
    mem.h\
    io.h\
    fns.h\
    LPC24xx.h

default:V: i$CONF

i$CONF: $OBJ $CONF.c $CONF.root.h $LIBNAMES
    $CC $CFLAGS -DKERNDATE=$KERNDATE $CONF.c
    $LD -mcpu=arm7tdmi-s  -nostartfiles -Wl,-Map=main.map,--cref,--gc-sections -Tlpc_e2468.ld $OBJ $CONF.$O $LIBFILES -lgcc -lm -o ilpc-e2468.elf
    $CP -O binary ilpc-e2468.elf ilpc-e2468.bin
    arm-none-eabi-size ./ilpc-e2468.elf

<../port/portmkfile

Remove clockcheck from main.c.

Rebuild:

devcons.o: In function `putstrn0':
devcons.c:(.text+0x49c): undefined reference to `consoleprint'
devcons.o: In function `echo':
devcons.c:(.text+0xcc8): undefined reference to `consoleprint'
devcons.o: In function `consread':
devcons.c:(.text+0x2590): undefined reference to `genrandom'
devcons.o: In function `conswrite':
devcons.c:(.text+0x30dc): undefined reference to `consoleprint'

In my case it turned out that the line

    int consoleprint = 1;

in lpc-e2468 was indented with spaces, not a tab is it should be. After fixing indentation, this line made it to the generated lpc-e2468.c file and consoleprint was no longer a problem.

To solve genrandom we will have to add sec to lib section and rebuild:

/usr/lib/gcc/arm-none-eabi/4.8/../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
/build/buildd/newlib-2.1.0+git20140818.1a8323b/build/arm-none-eabi/newlib/libc/stdlib/../../../../../newlib/libc/stdlib/exit.c:70: undefined reference to `_exit'
collect2: error: ld returned 1 exit status
mk:    ...  : exit status=exit(1)

To fix it, add this code to main.c:

void
exit(int status) {
}

So, main.c looks like this now:

#include <stdbool.h>

#include "u.h"
#include "../port/lib.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "mem.h"

#include "uart.h"
#include "../port/uart.h"

PhysUart* physuart[1];

Mach *m = (Mach*)MACHADDR;
Conf conf;
Proc *up = 0;

int main(void) {
  memset(m, 0, sizeof(Mach));   /* clear the mach struct */
  conf.nmach = 1;
  uart0_puts("memset Mach\r\n");
  archreset();
  uart0_puts("archreset\r\n");
  quotefmtinstall();
  uart0_puts("quotefmtinstall\r\n");

  while(true) {

  }
  return 0;
}

void
setpanic(void) {
  uart0_puts("Infernal panic\r\n");
  while (1);
}

uint32_t
__swp(uint32_t x, volatile uint32_t *p) {
  uint32_t ret;
  __asm__ __volatile__ (
    "swp %[ret], %[x], [%[m]]\n"
    : [ret] "=&r" (ret)
    : [m] "r" (p), [x] "r" (x)
    );
  return ret;
}

ulong
_tas(ulong* u) {
  return __swp(0xDEADDEAD, u);
}

int
islo(void) {
  register uint32_t ret;
  uint32_t val = PsrDirq;

  __asm__ __volatile__
  (
    "mrs %[r0], CPSR\n\t"
    "and %[r0], %[val]\n\t"
    "eor %[r0], %[val]\n\t"
    : [r0] "=r"(ret)
    : [val] "r" (val)
  );

  return ret;
}

int
splhi(void) { 
  register uint32_t ret, tmp;

  __asm__ __volatile__
  (
    "mrs %[r0], CPSR" "\n\t"
    "orr %[r1], %[r0], #0x80" "\n\t"
    "msr CPSR_c, %[r1]" "\n\t"
    "mov %[dst], lr\n"
    : [dst] "=&r" (m->splpc), [r0] "=r"(ret), [r1] "=r"(tmp)
  );

  return ret;
}

void
splxpc(int i) {
  register uint32_t ret;

  __asm__ __volatile__
  (
    "mrs %[r0], CPSR" "\n\t"
    "msr CPSR_c, %[r1]" "\n\t"
    : [r0] "=r"(ret)
    : [r1] "r"(i)
  );

  return;
}

void
splx(int i)
{
  __asm__ __volatile__ (
    "mov %[dst], lr\n"
    : [dst] "=&r" (m->splpc)
    );
}

int
spllo(void) {
  register uint32_t ret, tmp;
  uint32_t val = PsrDirq | PsrDfiq;

  __asm__ __volatile__
  (
    "mrs %[r0], CPSR\n\t"
    "bic %[r1], %[r0], %[val]\n\t"
    "msr CPSR_c, %[r1]\n\t"
    : [r0] "=r"(ret), [r1] "=r"(tmp)
    : [val] "r" (val)
  );

  return ret;
}

void
idlehands(void) {
  uart0_puts("bsp::idlehands\r\n");
    idle();
}

int
setlabel(Label* l) {
  __asm__ __volatile__ (
    "mov %[dstsp], sp\n"
    "mov %[dstpc], lr\n"
    : [dstsp] "=&r" (l->sp), [dstpc] "=&r" (l->pc)
    );

  return 0;
}

void
gotolabel(Label* l) {
  __asm__ __volatile__ (
    "mov sp, %[srcsp]\n"
    "mov lr, %[srcpc]\n"
    "bx lr"
    :
    : [srcsp] "r" (l->sp), [srcpc] "r" (l->pc)
    );
}

void
reboot(void) {
  uart0_puts("reboot\r\n");
  return;
  }

void
halt(void) {
  uart0_puts("halt\r\n");
  return;
}

int
segflush(void* v, ulong u) {
  return 1;
}

void
fpinit(void) {
}

void
FPsave(void* v) {
}

void
FPrestore(void* v) {
}

static void
linkproc(void) {
    spllo();
    if (waserror())
        print("error() underflow: %r\n");
    else
        (*up->kpfun)(up->arg);
    pexit("end proc", 1);
}

void
kprocchild(Proc *p, void (*func)(void*), void *arg) {
    p->sched.pc = (ulong)linkproc;
    p->sched.sp = (ulong)p->kstack+KSTACK-8;

    p->kpfun = func;
    p->arg = arg;
}

void
exit(int status) {
}

Rebuild:

inferno-os-lpc2468/os/lpc-e2468-olimex$ mk
arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM main.c
/bin/sh ../port/mkroot lpc-e2468
(cd /home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp ; mk SHELLTYPE=sh SYSTARG=Inferno OBJTYPE=arm-gcc install)
arm-none-eabi-ar ruvs /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a xec.o das-arm-gcc.o keyring.o string.o
(cd /home/snegovick/dev/inferno/inferno-os-lpc2468/libmath ; mk SHELLTYPE=sh SYSTARG=Inferno OBJTYPE=arm-gcc install)
arm-none-eabi-ar ruvs /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libmath.a s_log1p.o s_nextafter.o s_rint.o s_scalbn.o s_sin.o s_tan.o s_tanh.o
(cd /home/snegovick/dev/inferno/inferno-os-lpc2468/libkern ; mk SHELLTYPE=sh SYSTARG=Inferno OBJTYPE=arm-gcc install)
warning: skipping missing include file: mkfile-arm-gcc: No such file or directory
arm-none-eabi-ar ruvs /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libkern.a fmtstr.o fmtvprint.o getfields.o log.o memccpy.o memchr.o memcmp.o pow.o pow10.o qsort.o rune.o runestrlen.o sin.o seprint.o smprint.o snprint.o sqrt.o strcat.o strcmp.o strcpy.o strdup.o strecpy.o strlen.o strncmp.o strncpy.o strrchr.o strstr.o strtod.o strtol.o strtoll.o strtoul.o strtoull.o tokenize.o toupper.o u16.o u32.o u64.o utfecpy.o utflen.o utfnlen.o utfrrune.o utfrune.o vseprint.o vsmprint.o vsnprint.o
(cd /home/snegovick/dev/inferno/inferno-os-lpc2468/libsec ; mk SHELLTYPE=sh SYSTARG=Inferno OBJTYPE=arm-gcc install)
(cd port; mk  SYSTARG=Inferno OBJTYPE=arm-gcc install)
arm-none-eabi-ar ruvs /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libsec.a prng.o fastrand.o nfastrand.o probably_prime.o smallprimetest.o genprime.o dsaprimes.o gensafeprime.o genstrongprime.o rsagen.o rsafill.o rsaencrypt.o rsadecrypt.o rsaalloc.o rsaprivtopub.o eggen.o egencrypt.o egdecrypt.o egalloc.o egprivtopub.o egsign.o egverify.o dsagen.o dsaalloc.o dsaprivtopub.o dsasign.o dsaverify.o
arm-none-eabi-gcc -c -x assembler-with-cpp -mcpu=arm7tdmi-s -c lpc-e2468.root.s
   arm-none-eabi-gcc -O0 -std=c1x -fno-builtin -fplan9-extensions -fms-extensions -DUSED(...)=void -DSET(...) -c -mcpu=arm7tdmi-s -I/home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/include -I/home/snegovick/dev/inferno/inferno-os-lpc2468/libinterp -I./ -DLINUX_ARM -DKERNDATE=1433040606 lpc-e2468.c
   arm-none-eabi-gcc -mcpu=arm7tdmi-s  -nostartfiles -Wl,-Map=main.map,--cref,--gc-sections -Tlpc_e2468.ld load.o main.o uart.o archlpc2468.o port.o dump.o timer.o clock.o lpc24xx_irq.o trap.o devcons.o devenv.o devmnt.o devprog.o devsrv.o devuart.o alarm.o alloc.o allocb.o chan.o dev.o dial.o dis.o exception.o exportfs.o inferno.o latin1.o nocache.o nodynld.o parse.o pgrp.o print.o proc.o qio.o qlock.o random.o sysfile.o taslock.o xalloc.o lpc-e2468.root.o lpc-e2468.o /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libinterp.a /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libmath.a /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libkern.a /home/snegovick/dev/inferno/inferno-os-lpc2468/Inferno/arm-gcc/lib/libsec.a -lgcc -lm -o ilpc-e2468.elf
   arm-none-eabi-objcopy -O binary ilpc-e2468.elf ilpc-e2468.bin
   arm-none-eabi-size ./ilpc-e2468.elf
   text    data     bss     dec     hex filename
 335192   16644   31380  383216   5d8f0 ./ilpc-e2468.elf

Woohoo! :)

Lets flash it:

TFTP from server 10.218.35.27; our IP address is 10.218.35.61
Filename 'iarmtest'.
Load address: 0xa0008000
Loading: ########################
done
Bytes transferred = 351836 (55e5c hex)
## Starting application at 0xA0008000 ...
memset Mach
Inferno OS compiled by GCC
archreset
quotefmtinstall