Posted on

Dockerized FPGA toolchains

For a while, LXC (linux container) technology might have been known for the better chroot. Docker takes this approach even further by letting you mess with changes and undo them easily. You can just install foreign binaries and play with dependencies without compromising your desktop host’s runtime libraries. This article describes how to easily put commercial FPGA toolchains into a docker environment and carry them around on an external hard disk for quick installation on a new developer machine.

Lattice Diamond

The Lattice Diamond toolchain comes as RPM package and is recommended to be run under a Redhat OS. It is possible to convert to a DEB and install and run it on a Debian system likewise, but we try basing it on a minimal RPM compatible environment as an existing CentOS container.

This short howto describes the necessary steps for Diamond v3.10 (older versions work likewise):

First create a file called Dockerfile, like:

FROM centos

RUN yum update ; \
	yum install -y freetype libSM libXrender fontconfig libXext libXt \
		tcl tcsh perl libXft xorg-x11-fonts-Type1 net-tools \
		libXScrnSaver-1.2.2 \
		libusb-0.1.4 usbutils

RUN adduser -u 1000 -g 100 diamond; echo "." >> /home/diamond/.bashrc

COPY /home/diamond

ENTRYPOINT ["/bin/bash"]

You could automate things more by copying the RPM into the docker container, but that would just take useless space in the image (and stripping this back down would take extra action). Therefore we mount the directory where the RPM was downloaded to into the container. Unfortunately, there is no clean way to pull it from an official source the wget way.

You may have to sort out permissions first (by adding yourself to the ‘docker’ group) or prepend ‘sudo’ to each docker call.

The is a small setup script needed to initialize the environment:


export DISPLAY=:0.0


source $bindir/diamond_env

export LM_LICENSE_FILE=$HOME/license.dat

Building the container

  1. Change UID and GID for adduser command in the Dockerfile, if necessary
  2. Run
    docker build -t diamond .
  3. Then you can start the docker container using the following command. Note you have to replace $ETHADDR by the ethernet MAC address you have registered your license.dat to. Also, make $PATH_TO_RPM_INSTALLDIR point to the directory where the downloaded RPM resides.
    docker run -ti -e DISPLAY=:0 \
    --mac-address=$ETHADDR \
    --privileged --ipc host \
    -v /dev/bus/usb/:/dev/bus/usb/ \
    -v /tmp/.X11-unix/:/tmp/.X11-unix diamond:latest
  4. Then install diamond by
    rpm -i /mnt/diamond_3_10-base_x64-111-2-x86_64-linux.rpm
  5. You still need to copy your license.dat into your /home/diamond/ directory within the docker container. If it’s supposed to be elsewhere, edit the LM_LICENSE_FILE environment variable in
  6. Then you should be able to start the diamond GUI as user ‘diamond’:
    su -l diamond
  7. Finally, if you are happy with your changes, you might want to commit everything to a new image:
    docker commit -m "Diamond install" $HASH_OF_YOUR_CONTAINER diamond:v3.10

A few notes

The -v option takes care about sharing your X11 sockets with the docker sandbox. Note that there also some options inside the to make QT work in this limited environment. Don’t try to run Diamond as root, as the X11 forwarding will not be allowed.

Lattice iCEcube2

The iCEcube2 2017.0.8 release includes a mix of 32 and 64 bit binaries, therefore requires installation of the i686 variants of some libraries. The minimal Dockerfile would here look as follows:

FROM centos

RUN yum update ; \
    yum install -y libXext libpng libSM libXi libXrender libXrandr \
        libXfixes libXcursor libXinerama freetype fontconfig

# 32 bit support:
RUN yum install -y glibc.i686 glib2.i686 \
    zlib.i686 libXext.i686 libpng12.i686 \
    libSM.i686 libXrender.i686 libXfixes.i686 libXrandr.i686 \
    libXcursor.i686 freetype.i686 fontconfig.i686 

RUN adduser -u 1000 -g 100 icecube2

ENTRYPOINT ["/bin/bash"]

Run the iCEcube2 installer binary obtained from as user icecube2 and select the license file you have registered via the /mnt directory from your host OS.

Xilinx ISE

The same procedure works  for the ISE 14.7 toolchain. The Dockerfile in this case is almost similar, although includes a few X11 extras.

FROM centos

RUN yum update ; \
    yum install -y freetype libSM libXrender fontconfig libXext \
        tcl xorg-x11-fonts-Type1 net-tools libXScrnSaver-1.2.2 \
        libXi libXrandr \
        libusb-0.1.4 usbutils

RUN adduser -u 1000 -g 100 ise; echo "." >> /home/ise/.bashrc

COPY /home/ise

ENTRYPOINT ["/bin/bash"]

Downloading and unpacking ISE

Make sure you have downloaded the following files from the Xilinx website:


Then untar the first one by

> tar xf Xilinx_ISE_DS_14.7_1015_1-1.tar

This directory path will have to be exported to docker under $PATH_TO_UNPACKED_XILINX_TAR below.

The file:


export DISPLAY=:0.0

alias ise=$XILINXDIR/ISE/bin/lin64/ise

Likewise, the docker container is run by something like:

docker run -ti -e DISPLAY=:0 \
--mac-address=$ETHADDR \
--privileged --ipc host \
-v /dev/bus/usb/:/dev/bus/usb/ \
-v /tmp/.X11-unix/:/tmp/.X11-unix ise:latest

Once you’re inside docker, install as root by running /mnt/xsetup. This may take a long time. Left to do:

  • Install a license file
  • Mess with the USB drivers for Impact. This is left open to the user. I am using xc3sprog from my host system.
Posted on

DPF hacking

As some people avoid to get bored over christmas holidays, they tend to analyze presents like those cheap hongkong digital picture frames (DPF) that you normally give to your children so that they can lose it the next day.

Of course, other people always have kind of a similar idea, so it is not surprising that there are web pages describing internals of those undocumented devices.

However, the device I got is using another chip (AX206) than the already exploited st2205 based DPFs.
Since the AX206 has a 8051 instruction set, I had a sneak peak with my d52 disassembler. And it turned out, it was possible to have my own code run on the frame, without actually knowing anything about the environment. To access the internal flash, there are various tools listed at the site linked below. The DPF emulates a mass storage device over USB, vendor specific commands are used to do the standard SPI flash operations. The AX206 seems a powerful chip, and we were actually thinking on using it on a project, however there were too many unanswered open questions and the mass price (30k units) was not competitive considering the puzzling support. If a company buries a simple 8052 controller behind NDAs, the suspicion may arise that the chip has too many bugs.

Hacking a more or less unused vendor specific SCSI command in the DPF, I was able to make lcd4linux work with it:

lcd4linux on DPF
lcd4linux on DPF

Find more information on this Wiki: