FX12 Mini Module Linux System

FX12 The Avnet FX12 Mini Module (right) is a tiny circuit board comprising a Xilinx Virtex-4 FPGA, SDRAM, Flash and an Ethernet header. In the Real-time Systems Group at York, this board is being used to support research and there are plans to use it for teaching in the future. More information about this board can be found on Avnet's site.

The board is capable of running a full Linux 2.6 system on the PowerPC CPU within the FPGA. However, resources for configuring such a system are not easy to find. It took me several weeks to gather the software required to boot Linux with Ethernet support. To do this, I carried out the following tasks:

  • I upgraded the sample Avnet hardware design for Xilinx EDK 10.1, and built the board support package (BSP) for Linux 2.6.
  • I downloaded a copy of Linux 2.6 that had been extended by Xilinx for their ML405 prototyping boards, some of which are based on similar FPGAs. This gave me the drivers for the Xilinx devices, particularly the Ethernet hardware. The source came from http://git.xilinx.com/, which appears to be the best source for Linux kernels with Xilinx drivers. Xilinx has documentation at http://xilinx.wikidot.com/.
  • I added "gen-mhs-devtree" to EDK. It comes from git.xilinx.com, and it provides two new platforms in the "OS and Library Settings" part of the "Software Platform Settings". These are "uboot" and "fdt". The latter is the correct choice. It causes the "Generate Libraries and BSPs" menu option to emit a file named "fdt.dts" which describes the embedded system hardware configuration.
  • In EDK, I changed the kernel boot parameters ("bootargs") to read "console=ttyUL0 root=/dev/ram0 init=/sbin/init rw". The most important of these options is "console=ttyUL0" - if you don't do that, you won't see the kernel messages during boot.
  • I copied "fdt.dts" to arch/powerpc/boot/dts in my Linux kernel source.
  • I modified the Linux kernel sources in the following ways:
    • Added code to the kernel entry point (virtex405-head.S) to copy the kernel from Flash into RAM if it is not already RAM-resident. For this, I used the memmove function which is already part of the kernel boot loader.
    • In the configuration, added (changed) CONFIG_EXTRA_TARGETS="simpleImage.fdt simpleImage.initrd.fdt".
    • Configured the Flash memory driver to split the memory into two partitions (a large one for the kernel and root file system, and a small one for a jffs2 file system). This is done in arch/powerpc/platforms/40x/virtex.c; where I use "arch_initcall" to run an extra setup function during boot.
    • Modified arch/powerpc/boot/wrapper so that "simpleboot-fdt" is handled in the same way as "simpleboot-virtex405-*". Without this change, the kernel entry point is not at the beginning. The kernel will still boot with a smart boot loader (e.g. one that can load ELF files) but not with a simple boot loader like the one I use.
    • Various changes in the Xilinx GPIO driver. I added support for "open firmware", which is the mechanism used to access the device tree (DTS file contents). I also added a kernel-mode JTAG driver and fixed a security hole.
  • I made a root file system and GCC toolchain using the buildroot tool.
  • I wrote a simple boot loader to allow Linux to be loaded onto an empty FX12 board. The boot loader will boot from Flash if a kernel is present there; if not, it will wait for Intel Hex records on the serial line.

Since the result is a free software (GNU GPL) system, I can put the results of my work online. These include an FX12 system in EDK, already configured with TEMAC Ethernet support, GPIOs and serial drivers, and a matching Linux kernel and root file system. If you are setting up Linux for an FX12 module, it's likely that this will help you get started. If you change the hardware design, don't forget to regenerate "fdt.dts". To do that you must install "gen-mhs-devtree" inside EDK.

Because of the intended application for my work, there are a few things in the hardware and software that you may not expect. These include a GPIO configured to act as a JTAG host, four additional UARTs, and a Linux kernel driver for JTAG. You can remove these if you wish.