Embeddding OpenBSD

For some of my projects such as DNS/DHCP servers, routers, firewalls, NTP Servers, or for some Arduino projects, I embed OpenBSD on small footprint and low power consumption machines.

I use machines based on a PC architecture such as Wyse WinTerm, Neoware, that can be found on eBay for less than $30, or machines like Soekris or Alix boards from PCEngines. Some of these machines have the ability to boot on a hard drive, but having a machine booting from a flashcard can have some advantages. For example, they are completely quiet, and they use less power (less than 20 Watts). Also having no moving parts in a computer incrases its life span, and allow it to work in high vibrations environment.

For these projects, my favorite operating system is OpenBSD. It is a complete Unix system, lightweight, and secure by default. This makes it the ideal choice for network attached devices. To create the bootable flashcard or USB thumb drive I use a tool called flashrd created by Chris Cappucci. This tool helps you create a bootable image with a mix of read-only and in memory filesystems to avoid the wear problem of flash memory.

I have also used flashboot for OpenBSD, or NanoBSD for FreeBSD, but these tools are more complex to use and require compiling the entire source distribution to create the image. Flashrd only compiles a new kernel suited for your machine and uses the OpenBSD binary distribution for the rest of the OS.

Preparation steps

Before creating the image there are a couple of steps that need to be taken to prepare your build environment.

Download the latest version of flashrd

fred$ git clone https://github.com/yellowman/flashrd.git
Cloning into flashrd...
remote: Counting objects: 261, done.
remote: Compressing objects: 100% (161/161), done.
remote: Total 261 (delta 165), reused 186 (delta 90)
Receiving objects: 100% (261/261), 66.91 KiB, done.
Resolving deltas: 100% (165/165), done.

Get the base distribution files

fred$ OBSDDIST=ftp://ftp5.usa.openbsd.org/pub/OpenBSD/$(uname -r)/$(uname -m)/
fred$ mkdir dist
fred$ for file in base52.tgz comp52.tgz man52.tgz etc52.tgz
fred$ do
fred$    ftp ${OBSDDIST}$file
fred$    tar xzpf $file dist
fred$ done
. . .

You also need to have the sources of the kernel installed on your machine. You can check the directory /usr/src/sys and if the directory is empty you need to download the file sys.tar.gz from the OpenBSD servers and extract the files as shown here:

fred$ tar xvf sys.tar.gz -C /usr/src

Now that everything is ready you can generate your OS images.

Generating your first OS image

Now that everything is ready you can generate your first image. Just go to the directory where you have installed flashrd and call the script flashrd using the command sudo or as root with the path to where you have unpacked your OpenBSD distribution. You need to be root to run this command because flashrd needs to have the super user privileges to use tools like fdisk(8), disklabel(8) and vnconfig(8).

fred$ cd ~/flashrd
fred$ sudo ./flashrd <path>/dist
flashrd 1.1

Creating ramdisk rootfs
Crunchgen (ksh pax ls fsck fsck_ffs reboot init mount mount_ffs mount_vnd umount
cp mv)
Linking kcopy stand/tar stand/pax stand/mount_vnd stand/vnconfig stand/umount bin/sh
bin/ksh bin/ls bin/cp bin/mv sbin/init sbin/mount sbin/mount_ffs sbin/fsck
sbin/fsck_ffs sbin/reboot
Copying etc/login.conf etc/pwd.db
Copying pre-mount firmware to ramdisk rootfs atu-at76c503-i3863-ext
atu-at76c503-i3863-int atu-at76c503-rfmd-acc-ext atu-at76c503-rfmd-acc-int
atu-at76c505-rfmd-ext atu-at76c505-rfmd-int atu-intersil-ext atu-intersil-int
atu-rfmd-ext atu-rfmd-int atu-rfmd2958-ext atu-rfmd2958-int atu-rfmd2958smc-ext
atu-rfmd2958smc-int bnx-b06 bnx-b09 bnx-rv2p bnx-xi-rv2p bnx-xi90-rv2p fxp-d101a
fxp-d101b0 fxp-d101ma fxp-d101s fxp-d102 fxp-d102c fxp-d102e kue ral-rt2561
ral-rt2561s ral-rt2661 ral-rt2860 rum-rt2573 run-rt2870 run-rt3071 tusb3410
zd1211 zd1211b
Using disk geometry 968/32/63 (952 MB)
Creating filesystem on /dev/rvnd2a
Installing bootblocks
Configuring FLASHRD, FLASHRD.MP kernels
Compiling FLASHRD kernel (make depend) (make)
Compiling FLASHRD.MP kernel (make depend) (make)
Analyzing /root fs 50MB (0MB files 49MB free)
Analyzing /bin fs 15MB (5MB files 10MB free)
Analyzing /etc fs 50MB (4MB files 45MB free)
Analyzing /sbin fs 42MB (14MB files 28MB free)
Analyzing /usr fs 558MB (372MB files 186MB free)
Size openbsd.vnd 717MB
Finalizing /root newfs copy
Finalizing /bin newfs copy
Finalizing /etc newfs copy
Finalizing /sbin newfs copy
Finalizing /usr newfs copy
Creating var.tar 2MB files copy

Done
fred$ ls -ltrh
. . .
-rw-r--r--  1 root  fred   2.2M Nov 26 23:36 rd.i386-20121126
-rw-r--r--  1 root  fred   953M Nov 26 23:38 flashimg.i386-20121126

Flashrd has now created a 1G flashcard image. The first time you run the flashrd command a new kernel will be compiled. Depending on the speed of your machine it may take a few minutes to half an hour or more to compile the kernel. Next time flashrd will be run though, the system will not need to recompile the entire kernel and the command will run much faster.

Before creating an image it is good practice to figure out the geometry of your flashcard. The geometry is the number of cylinders, number of heads and the number of sectors. All these values are emulated on a flashcard, they help the software calculate the exact size of your flashcard. To find out these details you can plug the card in your computer and fire the tool fdisk. Or you can boot your Soekris or your PC Engines computer and the bios of these machines will show you that information (as show on ine 6). In this example the geometry of the drive is 945 cylinders, 128 heads and 63 sectors.

PC Engines ALIX.2 v0.99h
640 KB Base Memory
261120 KB Extended Memory

01F0 Master 848A Memory Card Adapter
Phys C/H/S 7566/16/63 Log C/H/S 945/128/63
Using drive 0, partition 3.
Loading......
probing: pc0 com0 com1 pci mem[640K 255M a20=on]
disk: hd0+
>> OpenBSD/i386 BOOT 3.18
boot>

Now that you know the exact size of the flashcard, you can create an image specifically crafted for it. Just indicate the geometry of your card to flashrd.

fred$ cd ~/flashrd
fred$ sudo ./flashrd -c 945 -h 128 -s 63 <path>/dist
flashrd 1.1

Creating ramdisk rootfs
Crunchgen (ksh pax ls fsck fsck_ffs reboot init mount mount_ffs mount_vnd umount
cp mv)
. . .

Configure your OpenBSD image.

Now that your image has been created it is time to configure it. The tool for configuring the image is called cfgflashrd. After answering the questions to set the hostname, the root password and few other things, the image will be ready to be used.

One important argument to cfgflashrd is -c. With this argument you indicate to your OpenBSD image if the computer has to boot from the serial or from the VGA console. The value after -c indicates the speed of the serial connection.

fred$ sudo cfgflashrd -i flashimg.i386-20121126 -r rd.i386-20121126 \
  -c 19200 -t PST8PDT
/dev/rvnd2a: file system is clean; not checking
/dev/rvnd3a: file system is clean; not checking
Current image device auto
New physical device name (as seen by destination system)[auto]? wd0
Setting ramdisk root image
Installing boot.conf for com0 at 19200 baud
/dev/rvnd3e: file system is clean; not checking
Modifying /etc/ttys for tty00 at 19200 baud

Please assign a system hostname...
Hostname: Alix52

Please assign a root password...
Password:
Verify:

NTP Servers: [us.pool.ntp.org ]
Configuring ntpd.conf for NTP servers us.pool.ntp.org
DNS Servers: [192.168.1.1 ]
Configuring resolv.conf for DNS servers 192.168.1.1
Done

Tranfering the image and booting.

Now that your image is ready and configured it is time to transfer it to a flashcard. Insert the flashcard into your computer using a USB adpter and use the following command to copy the image.

fred$ dd if=flashimg.i386-20121126 of=/dev/rsd0c bs=64k

Once the image transfer to the flashcard is complete, install the flashcard into your embedded computer (be careful not to break any pins on the flash card connector). Connect the serial console, or the display and keyboard if your machine has a VGA card and plug the power cord to boot your machine.

Here is an example of boot messages for OpenBSD-5.2 on Alix 2d3.

Once the login prompt appears, use the root account with the password you provided during the configuration of the image. Now that your are logged in, you just need to configure the network and your machine is ready to be used as a secure access point for example.


Comments !