What is this?

IndigoVision's Standalone NVR is a small motherboard with Ethernet networking, two discs, and built-in power supply. Although it's sold as a video recorder (a digital one, mind you), it's essentially just a PC without screen or keyboard. The obvious use for this is to install a full operating system on it, and use it as a file server (or more -- it's quite powerful enough to run a Web site, and, being ARM-based, will fool most x86-based attacks: think Darwin and bio-diversity!).

This page thus presents how I installed Debian GNU/Linux, my operating system of choice, on a Standalone NVR.

NOTE: I have since left IndigoVision, and I noticed the original Standalone NVR got a little brother with one hot-swappable disc. Although I'm not too sure it'd be useful to install Debian on such a system, I imagine one might try it. These notes may or may not apply: I expect the motherboard of the new NVR is heavily based on the vp850 (that of the original NVR) if it's not just the same, and it's ARM-based for sure.

What's new?

24 Nov 2004

Ok, the links are updated to new images using the new ethernet driver. The kernel's command line now defaults to starting in rescue mode as well, which means you can interrupt the boot process at the Blob prompt, just 'b'oot, and you'll end up in the busybox, flash-based system before any driver has been loaded.

Also, here is a tarball [37M] of all the source I used to build the images. Pfew, the FSF police can't arrest me anymore.

16 Nov 2004
We tried a new ethernet driver from Intel this afternoon, and it seem much, much, much better: faster and more reliable. I'll build new images later on.

Foreplay

I built a root file system to put in flash, which contains all the tools you need to download Debian directly. We'll also need to change the kernel (esoteric considerations of what root to use: stock Indigo kernels boot on a ramdisk, whereas we want to boot with a temporary initrd root which will be moved to the disk later on. See linux/Documentation/initrd.txt for more details)

You'll need a serial console using 115200 8N1.

The adventurous, and the insane, can re-build it all from the source tarball. There are some hints in the HOWTO file included, although that needs to be more documented. I have built the images using a x86-based cross-compiler. In theory you could get a system running and then do native builds, but it seems the native builds I did have had problems so far (i.e. the kernel would oops after a day or two, apparently choking on memory allocation). This is all yet to investigate...

Getting into it

Start by booting into blob (pressing a key at the prompt, just after powering up). Upload and install the root file system:

blob> xd ramdisk
['send file' using X-Modem protocol, send rfs.jffs2]
blob> erase ramdisk
blob> flash ramdisk
Then reprogram the kernel
blob> unlock kernel
blob> xd kernel
['send file' using X-Modem protocol, send zImage]
blob> flash kernel
You will also need to program blob to use a different kernel command line which will boot on the ramdisk properly:
blob> unlock param
blob> cmd mem=64M console=115200,ttyS0 rootfstype=jffs2 root=/dev/mtdblock2 init=/bin/sh

Reboot (and let Blob's prompt expire -- The kernel doesn't have a command line that lets it boot from blob's 'boot' command.) The kernel should boot, and end up at a shell prompt. If it doesn't, complain to your vendor. At the prompt:

# export PATH=/sbin:/usr/sbin:$PATH
# ./startup

This loads the drivers, sets up the RAID arrays and mounts /dev/md1 on /mnt. The 'startup' script will later boot the entire sytem, so the last few commands will fail at this point: it's safe to ignore the two error messages on pivot_root and chroot.

(Note: We use Indigo's partitionning scheme in the following way:

/dev/md0        /dev/hda1+/dev/hdc1      2Gb    swap
/dev/md1        /dev/hda2+/dev/hdc2      8Gb    root
/dev/md2        /dev/hda3+/dev/hdc3     450Gb   /home

This may not be the best, if the machine will serve large Web sites (/var/www on Debian) or receive large amounts of mail (/var/spool). It is however easy to move things around later, using symbolic links or binding (see mount(8)). The partitionning can be changed while running from flash; we'll see how to do that later on).

So, we'll now create a Debian base system on /mnt:

# cd /mnt
# rm -rf NVRConfig tmp
# ifconfig eth0 10.1.163.10
# route add default gw 10.0.0.1
(change the network settings to something meaningful for your network)
# debootstrap --arch arm woody . ftp://194.80.135.30/sites/ftp.debian.org/debian

(the IP address is that of ftp.mirror.ac.uk -- we don't have a name server yet; replace with your favourite mirror.)

debootstrap then proceeds to download, unpack and configure all the base packages. Finally it writes "Base system installed successfully"

We now need to add a valid fstab: edit /mnt/etc/fstab with:

/dev/md1 / ext3 errors=remount-ro 0 1
/dev/md2 /home ext3 defaults 0 0
/dev/md0 none swap sw 0 0
proc /proc proc defaults 0 0

and edit /mnt/etc/inittab, comment out all the 'tty' lines (as we obviously don't have any virtual consoles) and add:

T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100
Set up the networking for the Debian system: edit /mnt/etc/network/interfaces with:
auto lo eth0

iface lo inet loopback

iface eth0 inet static
        address 10.1.163.10
        netmask 255.224.0.0
        gateway 10.0.0.1
/mnt/etc/resolv.conf:
nameserver 10.0.0.8

(use your own settings of course)

and add a hostname in /etc/hostname, and /etc/hosts:

127.0.0.1 localhost
and finally authorise root to log in on the serial console (this is disabled by default in case the serial port is connected to a modem -- you may want to disable it again later if that is the case):
echo "ttyS0" >> /mnt/etc/securetty

Debian is now installed!

The system is now more or less in the state that a CD install would create. Now we can reboot, and tell blob to boot straight through by changing the command line:
blob> cmd mem=64M console=115200,ttyS0 rootfstype=jffs2 root=/dev/mtdblock2 init=/startup
Rebooting should now bring us to a Debian boot prompt (yay!) Log in as root (no password), and run 'base-config' The rest is just a normal Debian install. Now apt-get install nethack, and enjoy the best adventure game ever, all over a serial console!

What next?

I plan to write a cut-down monitor program to switch on the watchdog and blink the alive LED (possibly it would be nice to be able to tell that monitor what other processes it should watch over) and switch on the CPU LED when something happens. Not sure what to do with the alarm LED: blink when e-mail arrives? When Web server servers a page? (also, distribute this as a Debian package?)

The initrd is accessible read/write in /initrd. It should be unmounted, or at least be set read-only.

Technically, I shouldn't be publishing the images above without the source (that's against the GPL). I'll probably write a script that downloads and builds it all from scratch.

Repartitionning

sfdisk is available and will allow you to repartition to your heart's content. You can then use mke2fs to format the new partitions. You can't create swap partitions at this point, you'll have to wait until the system is installed. Then you'll probably need to change /startup to suit your new partitionning scheme. Personally I'd advise you stay away from the RAID0, which cumulates possibilities of hardware faults..

LEDs and watchdog

    mknod /dev/wdt c 10 130
    mknod /dev/pcx c 10 150
    mknod /dev/led c 10 151

mon850 monitors the CPU load, and lights up the CPU LED when the load is higher than 80%. It also keeps the watchdog in check (the watchdog will be off when the system starts).

alarmd creates a FIFO called /dev/alarm and reads from it in the background. You can then control the alarm LED with

    echo on > /dev/alarm
    echo off > /dev/alarm

Contact me

Comments, feature requests, bug reports? Mail me.

Comments (0)