Archives For Uncategorized

RIoTboard support

November 12, 2015 — Leave a comment

My career as a trendy videoblogger starts to pay off. Nice people from Newark element14 offered to send me some hardware for experiments (no strings attached) I took them up on their offer and few days later received RIoTboard. It’s iMX6 Solo in developer-friendly package, not as compact as Beaglebone but nicely built and comes with more connectors.

FreeBSD’s iMX6 support is very good, so it took two one-line fixes to FreeBSD kernel code to make it work on RIoTboard. The other chunk of work was U-Boot package. Took more time than it should have due to some operator errors. The bring up process is more or less the same as for any other iMX6 system, so it should be really easy to add this board to crochet. Step by step it looks like this (some of the code came from crochet):

Prepare environment for the build

export TARGET=arm
export TARGET_ARCH=armv6
export SRCROOT=/src/FreeBSD/head
export MAKEOBJDIRPREFIX=/src/FreeBSD/obj
export MAKESYSPATH=$SRCROOT/share/mk

Build world and kernel

make -j16 -C $SRCROOT buildworld
make -C $SRCROOT KERNCONF=$KERNCONF -j16 buildkernel

Create and partition SD card image


rm -f $IMG
dd if=/dev/zero of=$IMG bs=1000000 count=1024
MDUNIT=$(mdconfig -a -f $IMG)
gpart create -s mbr $DEV

# Create FAT partition
gpart add -a 63 -b 16384 -s 50m -t '!12' $DEV
gpart set -a active -i 1 $DEV
newfs_msdos -L "BOOT" -F 16 ${FAT_DEV}

# Create UFS partition
gpart add -t freebsd  $DEV
gpart create -s BSD $UFS_DEV
gpart add -t freebsd-ufs -a 64k $UFS_DEV

newfs $UFS_PART
# Turn on Softupdates
tunefs -n enable $UFS_PART
tunefs -j enable -S 4194304 $UFS_PART
# Turn on NFSv4 ACLs
tunefs -N enable $UFS_PART

mdconfig -d -u $MDUNIT

Mount UFS partition

MDUNIT=$(sudo mdconfig -a -f $IMG)

sudo mount $UFS_DEV $MNTDIR

Install world + kernel

sudo -E make -C $SRCROOT installworld -DDB_FROM_SRC DESTDIR=$MNTDIR
sudo -E make -C $SRCROOT distribution -DDB_FROM_SRC DESTDIR=$MNTDIR
sudo -E make -C $SRCROOT installkernel DESTDIR=$MNTDIR

Install come configuration. We need hw.fdt.console in loader.conf because riotboard’s DTS file does not have stdout-path property in chosen node. In this case FreeBSD falls back to serial0 node but user-accessible UART on RIoTboard is UART2 so as a result no kernel output visible on serial port.

echo 'hw.fdt.console="/soc/aips-bus@02100000/serial@021e8000"' > /tmp/loader.conf
cat > /tmp/fstab <<__EOF__
/dev/mmcsd0s2a  /               ufs rw,noatime          1 1
/dev/mmcsd0s1   /boot/msdos     msdosfs rw,noatime      0 0
tmpfs           /tmp            tmpfs rw,size=31457280  0 0
tmpfs           /var/log        tmpfs rw,,size=15728640 0 0
tmpfs           /var/tmp        tmpfs rw,size=5242880   0 0
cat > /tmp/rc.conf <<__EOF__

# minimal network config

# turn off sendmail

sudo mv /tmp/loader.conf $MNTDIR/boot/loader.conf
sudo mv /tmp/fstab $MNTDIR/etc/fstab
sudo mv /tmp/rc.conf $MNTDIR/etc/rc.conf
sudo mkdir $MNTDIR/boot/msdos

Unmount UFS and mount FAT partition

sudo umount $MNTDIR

sudo mount -t msdosfs $FAT_DEV $MNTDIR

Build and install ubldr, unmount FAT partition

buildenv=`make -C $SRCROOT TARGET_ARCH=armv6 buildenvvars`
eval $buildenv make -C $SRCROOT/sys/boot -m $MAKESYSPATH obj
eval $buildenv make -C $SRCROOT/sys/boot -m $MAKESYSPATH clean
eval $buildenv make -C $SRCROOT/sys/boot -m $MAKESYSPATH depend
eval $buildenv make -C $SRCROOT/sys/boot -m $MAKESYSPATH UBLDR_LOADADDR=0x12000000 all

sudo cp ${MAKEOBJDIRPREFIX}/arm.armv6/${SRCROOT}/sys/boot/arm/uboot/ubldr $MNTDIR
sudo umount $MNTDIR

Download and install u-boot-riotboard port. Then flash u-boot to the image

sudo dd if=/usr/local/share/u-boot/u-boot-riotboard/u-boot.imx of=$DEV bs=1k oseek=1 conv=sync

Detach md device

sudo mdconfig -d -u $MDUNIT

Configure boot switch selector on board to boot from SD card as described in this document

Insert SD card to either SD slot or uSD slot. When powered up you should see u-boot prompt


Boot command would look something like:

=> fatload mmc 0 $loadaddr ubldr
=> bootelf

For SD slot mmc unit is 0, for uSD it's probably 1, I didn't test.

Boot log: here

Next step for me is to get my imx6_video branch up to date and see if I can commit it to HEAD.

Quick update on progress in FreeBSD’s support of Raspberry Pi:
- VCHIQ driver was updated to the latest vendor code and bunch of FreeBSD-specific problems was fixed: locking, handling of non-cacheline aligned data
- Raspberry Pi userland code was updated to the latest vendor code
- Mikael Urankar created misc/raspberrypi-userland for userland libraries/utilities
- Mikael also created multimedia/omxplayer port for OMXPlayer, video player developed for RPi. It’s also used in Kodi player on Pi.
- I created misc/ioquake-pi port to make it easier for people to try it out

I put together all this stuff on my brand new Pi 2 and recorded demo that showcases, OpenGL, Quake3, omxplayer, camera, and audio. I hope all these ports will be committed/updated before next round of armv6 packages build.

Received yesterday and had to assembly it first thing today. Display part works like a charm without any system modifications. Haven’t researched touchscreen part though.






And yet another demo of 4DCAPE-43T, this time it’s touchscreen. On AM335x SoC touchscreen controller is coupled with analog-to-digital converter, for which there is a driver in FreeBSD HEAD: ti_adc. I had to implement touchscreen part and add driver <-> userland communication protocol. For proof of concept I used significantly dumbed-down version of Linux input event protocol. tslib serves as a userland part of the demo. I believe it’s de-facto standard for touchscreen devices interface in Linux world. Only two things were changed comparing to stock one: I added bsd-raw input plugin to communicate with kernel and rewrote framebuffer-related routines.

Code is in gpiokeys branch in my work-in-progress GitHub repo and in freebsd branch of tslib fork.

I like Qt. It runs on everything. More than 10 years ago you could run it on Linux/ARM on Sharp Zaurus and now you can run it on FreeBSD/Pi. I thought it would look neat on LCD screen on BBB and coded small demo player (qt-demo-player sources) just for the fun of it. Stock Qt does not have FreeBSD framebuffer support so I had to hack it up (qt-platform-scfb sources). Also it seems they still consider FreeBSD/clang second class citizen comparing to FreeBSD/gcc which causes some minor POSIX-related incompatibility fallout. But other than that it was smooth sailing, patch against vendor tree is really small. I’ll post it later along with build instructions. In addition to scfb platform support Qt console input plugins required: qt5-bsd-input

Demo was built using cross-compiled Qt 5.5.1, audio support is gstreamer Qt plugin.

Just quick (and overdue) update: HDMI for BBB is in HEAD as of r284534.

HDMI support for Beaglebone Black is stable now and supports reading EDID, you can get the path here. Before committing it I’d like to make interoperability between HDMI framer and FB/LCD drivers as generic as possible and for this I need at least one more system with working HDMI to find common patterns. For this purpose I picked up i.MX6-based Hummingboard and now try to get video output working on it. There is some minor progress but it seems before getting to HDMI/IPU I need to do some work on clock management part of the system. So it’s going to be some time before I see first pixels on my monitor.

I also got 4DCAPE-43, neat Beaglebone Black LCD cape by 4D Systems. Patch (download here) for it is pretty minimal: VT support in kernel config, panel info and pins configuration in dts, and one improvement in GPIO driver (setting default values for OUT GPIO pins). None of the other features except reset button work yet but getting GPIO keyboard working would be an interesting project by itself.

Here is the picture of cape in action:


Today for the first time I’ve got stable and correctly positioned output on HDMI monitor connected to BeagleBone Black. It involved fixing bug in AM335x LCDC controller, fixing bug in I2C controller, and a lot of experiments with register-pushing. Code requires major clean-up and is not ready for the tree yet. I’ll post patch when it’s in readable form.


I’ve update ioquake binaries and pushed respective changes to github. New version has support for mouse and keyboard so you can actually play Quake3 on FreeBSD/Pi alas without sound. It should run out of the box on normal console. Make sure you have moused running or specify mouse device by setting Q_MOUSE_DEV environment variable, e.g.:

env Q_MOUSE_DEV=/dev/ums0 ioquake3.arm +set s_initsound 0

A week ago Adrian Chadd asked me to take a loot at FreeBSD/MIPS emulation. So last week I’ve been busy tidying up stuff in that department and looking up bits of information on various emulators. This morning I finally committed last changeset so now is the time to write up summary.


There are two widely used MIPS emulatoes that FreeBSD supports: QEMU and GXemul. Both of them support numerous MIPS devices but we’re interested in only two.

MALTA is more or less standard for MIPS emulation and supported by both emulators. QEMU supports 32 and 64 bit variants with both big and little-endian byte order. So four modes in total. Also for MALTA machine QEMU provides PCNet NIC emulation.

GXemul supports 32 and 64 bit modes of MALTA but only for little-endian byte order. Big-endian byte order is not supported due to incomplete PCI controller implementation. No NIC support for MALTA machine. Also Gxemul provides so-called oldtestmips emulation mode: generic implementation of abstract MIPS machine with very simplified NIC/disk devices. In theory it should be faster then actual hardware emulation but I haven’t got around to benchmarking yet. oldtestmips can be run in 32 and 64 bit mode, but only big-endian byte order is supported.

Disk images

I used raw disk images created by makefs(8) utility. The advantage of raw disk image is that they can be used with both emulators. qemu provides more options in this area but they’re out of scope of this article. I created four images for my tests: disk.img, disk64.img, diskel.img, and disk64el.img. 32-bit big-endian, 64-bit big-endian, 32-bit little-endian, 64-bit big-endian. The process looks somewhat like this script:

set -e

export TARGET=mips
export TARGET_ARCH=mips
export SRCCONF=/dev/null
export SRCROOT=/src/FreeBSD/head
export MAKEOBJDIRPREFIX=/src/FreeBSD/obj/head
export DESTDIR=/src/FreeBSD/tftproot/$TARGET_ARCH
make -C $SRCROOT buildworld

sudo -E mkdir -p /src/FreeBSD/tftproot/$TARGET_ARCH

# modify /etc/fstab and /etc/rc.conf in $DESTDIR

# Create 512Mb disk image with big-endian UFS
# For TARGET_ARCH set to mipsel or mips64el use "-B le" switch 
sudo -E makefs -M 538968064 -B be /src/FreeBSD/disk.img $DESTDIR

Change TARGET_ARCH and disk image name accordingly for mipsel/mip64/mips64el targets.


As of QEMU 1.6.0 there is one known problem with it: NIC emulation does not work in big-endian mode. See this patch for fix and details. Also, amount of memory limited to 128Mb. Use MALTA kernel config for 32-bit mode and MALTA64 for 64-bit mode.

Command lines for various modes/byte orders are:

qemu-system-mips -M malta -kernel /path/to/mips.mips/MALTA/.../kernel -hda /src/FreeBSD/disk.img -nographic
qemu-system-mips64 -M malta -kernel /path/to/mips.mips64/.../MALTA64/kernel -hda /src/FreeBSD/disk64.img -nographic
qemu-system-mipsel -M malta -kernel /path/to/mips.mipsel/.../MALTA/kernel -hda /src/FreeBSD/diskel.img -nographic
qemu-system-mips64el -M malta -kernel /path/to/mips.mips64el/.../MALTA64/kernel -hda /src/FreeBSD/disk64el.img -nographic


GXemul requires two patches for proper FreeBSD/MIPS emulation. First one implements rdhwr op for reg 29 required by TLS support. The second one fixes UDP packet checksum calculation and required for proper functioning of emulated DHCP server. Both of these patches have been committed upstream but there were no GXemul release after that so they’re not available as part of emulators/gxemul port.

As with QEMU kernel configs for MALTA are MALTA and MALTA64. And since only little-endian byte order is supported command lines for this emulation mode are:

gxemul -e malta -C 4Kc -d /home/gonzo/FreeBSD/diskel.img /path/to/mips.mipsel/.../MALTA/kernel
gxemul -e malta -d /home/gonzo/FreeBSD/disk64el.img /path/to/mips.mips64el/.../MALTA64/kernel

For oldtestmips emulation mode is other way around, only big-endian. And to make things more complicated it’s GXEMUL kernel config for 64-bit and GXEMUL32 for 32-bit. So here you are:

gxemul -M 256 -E oldtestmips -d /home/gonzo/FreeBSD/disk64.img /path/to/mips.mips64/.../GXEMUL/kernel
gxemul -M 256 -C 4Kc -E oldtestmips -d /home/gonzo/FreeBSD/disk.img /path/to/mips.mips/.../GXEMUL32/kernel

Maximum amount of memory set could be set by -M command-line switch for oldtestmips emulation is 256M. Otherwise physical memory would overlap with memory-mapped regions reserved by devices. There are some preliminary work to work around this limitation but no results yet.