FreeBSD on Zynq-7000 / Zedboard

This page describes running FreeBSD on the Zedboard and other Xilinx Zynq-7000 platforms. The Zynq-7000 is an interesting platform combing a Xilinx 7-series FPGA fabric with a dual-core ARM Cortex-A9 based Application Processor Unit (System-on-a-Chip).

The Zedboard is an evaluation board for the Zynq-7000. It is manufactured by Digilent. More information on the Zedboard can be found at

The information on this page is migrating to the FreeBSD wiki at

Pre-built SD card image

I will try to get builds for Zedboard started again. Meanwhile, I've put an SD card image here.

MD5 (FreeBSD-armv6-11.0-ZEDBOARD-286926.img.bz2) = c9b38f49e592ecf2419df241b2c3022c

An SD card image for the Zedboard is available in FreeBSD's snapshot releases directory.

If you'd like to test-drive FreeBSD on a Zedboard, download the latest bzip2 compressed SD card image from there. Uncompress and copy the image to the SD card. On my machine, the SD card shows up as /dev/da0. Be sure that is the same on your machine before cut and pasting this.

# bunzip2 FreeBSD-11.0-CURRENT-arm-armv6-ZEDBOARD.img.bz2
# dd if=FreeBSD-11.0-CURRENT-arm-armv6-ZEDBOARD.img of=/dev/da0 bs=1M

Boot It

Power down the Zedboard. Insert the SD card in the SD slot and be sure the Zedboard's configuration mode jumpers are set for booting from the SD card before powering up. (If you've already been booting the Linux image from the SD card shipped with the Zedboard, you shouldn't need to change anything.)

The USB-UART connected to connector J14 acts as the FreeBSD console (device uart1). This is the same console as the stock Linux image. The Zedboard should automatically boot U-boot and then the FreeBSD kernel.

The FreeBSD kernel has drivers for the UARTs, SDHCI, Gig Ethernet, and a USB host driver for the USB OTG connected at J13. There is also a GPIO driver which allows reading of switches and buttons and controlling the LEDs.

Please send any feedback to me via E-mail


To run this image on a MicroZed, start with the Zedboard SD image but you need to change a few files. Download microzed_extrafiles.tgz and extract the files. Then mount the SD card partitions on your machine and copy the files over:
# mkdir /mnt/boot /mnt/armroot
# mount -t msdosfs /dev/da0s1 /mnt/boot
# mount /dev/da0s2a /mnt/armroot

# tar xzvf microzed_extrafiles.tgz
# cp microzed_extrafiles/{boot.bin,u-boot.img,uenv.txt,microzed.dtb} /mnt/boot
# cp rc.conf /mnt/armroot/etc/rc.conf

# umount /mnt/boot
# umount /mnt/armroot

Note: At boot-up, the USB-Host interface on MicroZed is held in reset by a Zynq GPIO signal (PS_MIO7). The quick-and-dirty way to release it from reset is as follows:

# gpioctl -c 7 OUT
# gpioctl 7 1
I haven't yet come up with a start-up script for /etc/rc.d to automate this.


FreeBSD can run on Parallella. But, the stock u-boot installed in flash memory on Parallella cannot directly boot FreeBSD. To avoid the risk of reprogramming the flash, I created a second u-boot with the proper options to boot FreeBSD and disguised it as a Linux uImage. So, the boot sequence is FSBL --> U-boot --> U-boot--> FreeBSD.

To run this image on a Parallella, start with the Zedboard SD image but you need to replace all the files in the boot partition. Download parallella_freebsd.tgz.

Mount the SD card boot partition on your machine:

# mkdir /mnt/boot
# mount -t msdosfs /dev/da0s1 /mnt/boot
Remove all the files in the boot partition:
# rm /mnt/boot/*
Copy your Parallella board's FPGA bitstream to the partition. There are several different bitstreams for the various board configurations. See section 3 of this guide to creating an SD card.
# cp parallella_????.bit.bin /mnt/boot/parallella.bit.bin
Extract the files from parallella_freebsd.tgz into the boot partition:
# tar xzvf parallella_freebsd.tgz -C /mnt/boot
Unmount the boot partition
# umount /mnt/boot

Note: Changing the hostname from zedboard to parallella is an exercise left to the reader. :-)

Building an SD Image

Note: Tim Kientzle's crochet-freebsd tool can build ZedBoard images.

Here's how I create the SD image from the source.

Building boot files for Zedboard

The Zynq chip needs several files in an msdos boot partition to boot FreeBSD:

The boot.bin and u-boot.img files are built from Xilinx sources located at

To cross-compile these on FreeBSD requires ports devel/arm-none-eabi-gcc. You should be able to install this with pkg:

# pkg install arm-none-eabi-gcc

You will also need Python:

# pkg install python2

Fetch the Xilinx sources with git:

# git clone u-boot-xlnx

The Secondary Program Loader embedded in boot.bin needs code to initialize the Zynq's PS section. The files are ps7_init.c and ps7_init.h and need to be placed in the directory u-boot-xlnx/board/xilinx/zynq. This code is very board-specific and is generated by Xilinx Vivado tools for every system design. But, ps7_init.c and ps7_init.h for some common Zynq boards are available at{zed,microzed,zc702,zc706}. Fetch the proper files for your board and be sure they are in board/xilinx/zynq. Without the files, u-boot will still build but will produce a boot.bin that doesn't work.

Build u-boot.img and boot.bin:

# cd u-boot-xlnx
# gmake CROSS_COMPILE=arm-none-eabi- distclean
# gmake CROSS_COMPILE=arm-none-eabi- zynq_zed_config
# gmake CROSS_COMPILE=arm-none-eabi- HOSTCC=cc
The bootfiles boot.bin and u-boot.img will be located in the top directory.

Note: Other Zynq configurations in the u-boot-xlnx source do not set the proper option to boot FreeBSD. You will need to patch the configuration's include file to add the CONFIG_ZYNQ_BOOT_FREEBSD option. For example, to create u-boot for microzed, you will need to make the following patch:

--- a/include/configs/zynq_microzed.h
+++ b/include/configs/zynq_microzed.h
@@ -19,6 +19,8 @@
 #define CONFIG_DEFAULT_DEVICE_TREE     zynq-microzed

Next, we need ubldr:

# cd /usr/src
# make TARGET_ARCH=armv6 buildenv
Entering world for armv6:arm
# cd sys/boot/arm
# make UBLDR_LOADADDR=0x80000
ubldr will be in /usr/obj/arm.armv6/usr/src/sys/boot/arm/uboot/ubldr.

uenv.txt replaces u-boot's default boot commands to boot FreeBSD:

cat >uenv.txt <<EOM
uenvcmd=echo Booting FreeBSD from SD...; mmcinfo && fatload mmc 0 ${ubldr_addr} ubldr && fatload mmc 0 ${dtb_addr} ${dtb_name} && fdt addr ${dtb_addr} && bootelf ${ubldr_addr}

Build world and kernel

Next, we need to build world for armv6 and a kernel for Zedboard:

From the directory /usr/src:

make TARGET_ARCH=armv6 KERNCONF=ZEDBOARD buildworld buildkernel

Create an SD card image

The following creates SD card image with an msdos boot partition.
dd if=/dev/zero of=SDCARD.img count=1048576
mdconfig -f SDCARD.img -u 0

gpart create -s MBR md0
gpart add -s64m -t \!14 md0
gpart set -a active -i 1 md0
newfs_msdos -F 16 /dev/md0s1

gpart add -t freebsd md0
gpart create -s BSD md0s2
gpart add -t freebsd-ufs md0s2
newfs /dev/md0s2a
tunefs -n enable /dev/md0s2a

Mount SD card partitions

mkdir /mnt/boot /mnt/armroot
mount -t msdosfs /dev/md0s1 /mnt/boot
mount /dev/md0s2a /mnt/armroot

Populate root and boot partitions

From within the source directory:
make TARGET_ARCH=armv6 KERNCONF=ZEDBOARD DESTDIR=/mnt/armroot installworld distribution installkernel
Copy these files generated above to the boot partition:
cp boot.bin u-boot.img ubldr zedboard.dtb uenv.txt /mnt/boot

Final tweaks

Create a mount point for the boot partition:
mkdir /mnt/armroot/boot/msdos

Unmount file systems

umount /mnt/boot
umount /mnt/armroot
mdconfig -d -u 0

Copy to an SD card

dd if=SDCARD.img of=/dev/da0 bs=32768

Thomas Skibo

E-mail Me