Zeus WPI recently got some old IP cameras: we got 8 AXIS 210A network camera’s. These can be used to monitor things, but in this blog post we will be using them as a “computer” to run arbitrary programs on instead of only the application made by the vendor.
The camera has a web interface where you can edit files. The file
/etc/inittab contains a line that is by default commented out that starts a telnet server at boot. After enabling this service, some Linux commands can be executed on the camera. Unfortunately, the camera only has a limited set of commands (most of them included in a busybox multi-call binary). The camera also runs an ftp server.
/proc/cpuinfo contains information about the processor: in this case it was rather non-standard: ETRAX 100LX running the CRIS instruction set.
$ cat /proc/cpuinfo processor : 0 cpu : CRIS cpu revision : 11 cpu model : ETRAX 100LX v2 cache size : 8 kB fpu : no mmu : yes mmu DMA bug : no ethernet : 10/100 Mbps token ring : no scsi : yes ata : yes usb : yes bogomips : 99.32 $ uname -a Linux axis-00408c7eee9f 2.6.17 #1 Mon Jan 22 11:35:26 CET 2007 cris unknown
After some research, a toolchain was found on the vendors ftp server. Unfortunately, the toolchain itself didn’t compile on my system. This was not unexpected, since the last time the files on the server were updated was in 2007. Luckily, there were also prebuilt packages of the compiler for Debian (32-bits Debian, that is). These were installed on a virtual machine downloaded from osboxes.org.
After installing the
.deb file, there are now some binaries having a
cris- prefix in
/usr/local/cris/bin/. This includes a compiler
cris-gcc, but it doesn’t work in the default configuration: the camera uses
libuClibc-0.9.27.so as its libc, but the compiler uses
glibc. This could not be fixed by just linking against the
libuClibc-0.9.27.so from the device, because the linker would give errors like:
error adding symbols: File in wrong format. This was a dead end, and was not solved.
Writing our own syscalls
An approach of writing C without libc was then tried: this can be done with the following GCC flags:
cris-gcc -g -mcpu=v10 -mno-side-effects -mcc-init -static -nostdlib main.c -Wl,--entry=_main -o /tmp/compiled
This in itself is of course useless without a way provide input to the program and have the program provide output. To combat this, some of the Linux kernel headers were copied, modified and compiled with the binary. Specifically, the file
asm/unistd.h was included since it had some Linux system call assembly macro’s.
Adding the syscalls enabled the program to perform IO, and enabled the porting of RCPU (RCPU is a fantasy CPU emulator) to the CRIS architecture. There was already a brainfuck interpreter for RCPU, so now there’s indirectly a brainfuck interpreter for CRIS.
The code and some scripts to make deploying easier can be found on this GitHub repository.
The toolchain can be downloaded from the site, or if it goes down, from the Internet archive