Configuring and Installing Linux on
Xilinx FPGA Boards

The BYU Linux on FPGA's Project

BYU Configurable Computing Laboratory
Brent Nelson and Brad Baillio

Revision Date: 7 November 2005

Introduction

XIlinx boards containing PowerPC CPU's are now widely available and present an interesting target for Linux-based embedded systems development.  These include boards based on Virtex-II Pro as well as Virtex-4 FPGA's. The Xilinx XUPV2P board is a Virtex-II Pro board created by Xilinx for the XIlinx University Program (XUP).  This document describes installing an open-source Linux kernel on that board

However, the information provided herein is general and has successfully been used to install Linux on the Xilinx ML-403 board here at BYU.  The only difference had to do with the options used to create the SystemACE file.  Special considerations, if any, for installing on boards other than the XUP board are noted in the sections below.  See the final section of this document for a general wrap-up discussion on installing Linux on other boards.

To comment on or make corrections/suggestions to this writeup, please send mail to:

 linuxfpga a  t  ee.byu.edu.

Topics covered in this document include:
  1. Creating an EDK-based hardware design for the FPGA which supports running Linux.

  2. Creating a cross-compiler environment to build the Linux kernel.

  3. Obtaining, configuring and compiling the Xilinx kernel.

  4. Configuring the board with the Xilinx kernel from a Parallel-IV cable or from compact flash.

  5. Creating an open-source root file system using Busybox for use with the kernel.

  6. Configuring networking on the board for a number of different configurations.

  7. Booting the kernel with the root file system using a compact flash, DHCP, and NFS.

The information included in this document is all freely available on the WWW.  The point of this document is to pull it together from a variety of sources to created a more self-contained cookbook to aid students and researchers who are performing the steps described below for the first time.  In particular, this page was written to be used by our Computer Engineering senior project students in their work.  Thus, it provides step-by-step instructions to get them going, some of which may seem overly elementary to some users. 

This document assumes a working knowledge of the EDK and the ability to create, configure, and execute designs/programs on the XUP board.  At a minimum the EDK tutorials should be completed before starting with this document.  Better yet, creating a few different designs using the EDK and the Standalone software on the XUP board on your own would be good for laying the foundation required.

This work is based on the ML300 Linux port described in a fair amount of detail in:

     http://www.klingauf.de/v2p/index.phtml

and more recently at:

     http://www.crhc.uiuc.edu/IMPACT/gsrc/hardwarelab/docs/kernel-HOWTO.html#toc1

The port of Linux to the ML300 that these pages describe was done by MontaVista.  Klingauf seems to have been the first we have found to document a number of the steps required to use that port.  Morever, Klingauf has done a very good job of documenting the creation of the root file system part of the process.  However, the Klingauf page was for an older version of the EDK tools (the V2PDK) while the UIUC page is more recent and is for the EDK.

Parts of the current document closely follow and refer to those two prior documents.  In some places, the current document duplicates those previous documents.  The purpose of this document is to more fully elaborate on a number of the steps required to build and install the kernel, bring parts of these documents up-to-date w.r.t. the latest Xilinx EDK tools (7.1i sp2 as of the time of this writing), and describe a number of ways of booting the board (using the compact flash, diskless using NFS, etc).  The goal is that students and researchers can come up to speed in using Linux on a range of Xilinx development boards in a shorter time that we initially took.  Further, our intent is for this document to grow over time to include other topics which those desiring to use Linux on these boards can benefit from.  To that end, we solicit contributions from others using the boards.


Acknowledgements

The Klingauf page:

    http://www.klingauf.de/v2p/index.phtml

written by Wolfgang Klingauf provided significant information for this work. 

The UIUC page:

    http://www.crhc.uiuc.edu/IMPACT/gsrc/hardwarelab/docs/kernel-HOWTO.html#toc1

is part of a larger effort which is documented at:

    http://www.crhc.uiuc.edu/IMPACT/gsrc

These pages provide a number of helpful documents and quick start guides regarding setting up the design environment, tutorials on the EDK, and JumpStart guides to the ML300 and ML310 boards. 

We found that both guides were useful in our work and recommend them both to the reader. 


0. Our Build System

The version of EDK we used for this work was Version 7.1 SP2.  The ISE version was 7.1 SP3.  The WinXP box was running WinXP, Service Pack 2.  The Linux box used for parts was an i386 running Debian-sarge.  A Parallel-IV cable was used for configuring the FPGA since, at the time of this writing, XMD/GDB didn't seem to have full support for the Platform-USB cable.

Disclaimer: if you aren't comfortable with the EDK in general and programming the PPC's in the FPGA using the EDK, you should not continue.  The process we document below is not for EDK novices.  It assumes a solid (strong) foundation in the EDK, base system builder, and the non-Linux use of the XUP board.  If you are an EDK novice, you should consult other documentation and experiment with the board and create a variety of projects on the board before before you continue.  The UIUC pages referenced above are good sources for some of this.  The Xilinx-provided documentation is also a good place to start. 


1. Building the Hardware

To get started, build a hardware project using Base System Builder for the board. Include the following minimal set of modules:

PPC (set to 300MHz)
opb_sysace
opb_ethernet (no DMA)
DDR memory controller for your DDR DIMM
opb_uart_16550

Make everything interrupt-driven.  Leave the PPC O/S as stand-alone for both CPU's.

Also, under PLB BRAM IF CNTRL (last peripherals screen of base system builder), set the memory size to the max it will allow.  For the XUP board, this is 128KB.

Note: you must have your EDK project in a directory whose pathname doesn't contain spaces. Else, the BSP generation process described below will fail. Thus, anything in C:\Documents and Settings on a WinXP box will not work.

At this point, do a build and ensure that you can a simple "Hello, world"  program or the EDK-provided memory test application independent of Linux.  This will help increase the chances that if/when Linux doesn't boot, it isn't a hardware problem.  Remember to have the BootLoop program configured into BRAM in your software projects section in EDK.


2. Creating an ACE File

Using an ACE file allows you to more easily program the FPGA and load software on it than using a Parallel-IV cable and XMD.

To generate an ACE file from a Xilinx xygwin shell:

xmd -tcl genace.tcl -opt xupGenace.opt

where the file xupGenace.opt contains the following:

-jprog
-board user
-target ppc_hw
-hw implementation/download.bit
-elf TestApp_memory/executable.elf
-configdevice devicenr 1 idcode 0x1127e093 irlength 14 partname xc2vp30
-debugdevice devicenr 1 cpunr 1
-ace system.ace
 

Be sure to change the -hw and -elf lines to match your situation.

If you copy the resulting system.ace file onto a compact flash the board will configure from that bitstream and run that executable.  On the board be sure to set the switches so that it will boot from JTAG (this causes it to try to boot from the SystemACE controller).

Note #1: The Xilinx SystemACE controller is very particular about the parameters used to create the file system on the compact flash.  Yours may or may not have been created correctly.  The program mkdosfs is one way to correctly format a CF card.  On a WinXP box, run:

mkdosfs -s 64 -F 16 -R 1 F:

where F: is the compact flash's volume letter.  You can find the mkdosfs program on the WWW to usedownload and .

Note #2: Impact can be used to generate an ACE file as well.  However, as we use the command line method you will want to consult the documentation on Impact to learn how to do it from there. 

Note #3: Generating an ACE file for a board known to the Xilinx tools (such as the ML-403 board) is easier than for the XUP board.  Here are the instructions for the ML-403:

xmd -tcl genace.tcl -opt xupGenace.opt

where the file xupGenace.opt contains the following:

-jprog
-board ml403
-hw implementation/download.bit
-elf TestApp_memory/executable.elf
-ace system.ace

By telling it you are using the ml403 board, you need not specify a number of the other options since the tools know about that board.   Other Xilinx-specific boards can be handled in a similar fashion.  To see which boards are supported in this way, consult the genace.tcl file in the EDK installation directories.


3. Generate the BSP in EDK

The BSP (Board Support Package) is the set of files required so that Linux will compile and contain the required drivers and .h files for your board.

In EDK's software settings:

  1. Set PPC_405_0 to use Linux kernel (linux_mvl31 version 1.01.a)
  2. Under Library/OS Parameters:

    Set MEM_SIZE to size of DDR (example: 0x10000000 for 256MB).  Be sure it matches the DDR you configured into the board design  in the "Building the Hardware" section.

    Set PLB_CLOCK_FREQ_HZ to the PLB speed (usually 100000000)

    Set TARGET_DIR for where you want the board support package placed (use forward quotes or it will fail!) (I put it in /tmp and then later tar-ed it up). 

    Under connected_periphs you should add all of the devices you want Linux to know about.  In our case, we added the RS232, the ethernet mac, the SysAce, and the interrupt controller.
  3. Run libgen from within EDK.

Pay attention to warnings.

Since  we are using the latest ethernet driver '1.00.f', the following fixes should be made to allow it to be used with the kernel we downloaded:

  1. In file arch/ppc/platforms/xilinx_ocp/Makefile, make this change:

    xilinx_ocp-objs += xbasic_types.o xdma_channel.o xdma_channel_sg.o \
                   xipif_v1_23_b.o \
                   xpacket_fifo_v2_00_a.o xpacket_fifo_l_v2_00_a.o \
                   xversion.o

    The key point to note here is that there are two xpacket_fifo entries and the version used is newer than in the original Makefile

  2. In arch/ppc/platforms/xilinx_ocp/xilinx_syms.c, the old V1.00.b XPacketFifo files are included and symbols are exported.  Change them to V200.a by modifying that file.
     

Finally, if you have problems with the BSP generation process, you can always go into:

.../EDK/sw/ThirdParty/bsp/linux_mvl31_v1_00_a/data/

and read the .tcl file that actually does the BSP generation to see what other restrictions on versions there are.

At this point you have a working bitstream and the BSP files required for Linux in /tmp. Tar up the BSP directory and move it to a Linux box.

It is now time to go to a Linux box and work on creating the Linux kernel.


4. Create a cross compiler for PPC

A cross-compiler will let you compile C-code to PPC machine code on an arbitrary host. In our case we use an x86 box running Linux to generate PPC executables.

In this section simply follow exactly the UIUC instructions.

We set the following parameters w.r.t. the UIUC instructions:

 %setenv TARGET powerpc-405-linux
 %setenv PREFIX /opt/${TARGET}

This will make /opt/powerpc-405-linux the place where the final cross compiler gets put.

We have encountered no problems getting the creation of the cross-compiler to work.  It just takes a few hours for it to run.

NOTE: as of the time of this writing, the line of interest in demo-ppc405.sh that is uncommented (and therefore gets used) starts with this:

     eval `cat powerpc-405.dat gcc-3.4.1-glibc-2.3.3.dat` ...

This specifies the precise combination of gcc/glibc that is to be used.  You may try other combinations but this work is based on the versions shown.

When it is done, go into /opt and find the PPC cross compiler tools directory that you have now created and add that directory to your path.

At this point, you can now compile C-code to PPC binaries on your i386 machine.  In other words, you have a cross compiler.


5. Get the Linux sources using bitkeeper:

As of July 1, 2005, bitkeeper as described in UIUC and Klingauf is no longer available.  This section uses a new client.

The free client is now available at bitmover.

Once you download it, unpack and build the free-client:

% /bin/sh bk-client.shar
% cd bk_client-1.1
% make

To download the repository source file, run the following from the command line:

% ./sfioball bk://ppc.bkbits.net/linuxppc_2_4_devel linuxppc_2_4_devel

The download will produce an editable copy of the repository source. Unlike the previous instructions found at UIUC and Klingauf's page, there is now no edit or clone command.  You just use the sources downloaded in the command above.


6. Configuring the Linux Kernel - the .config File

The Linux kernel will be built using the above-created cross compiler. The file .config is used to control which parts of Linux are included in the kernel. In our experience you have to be careful about what features of Linux you configure in and how you modify .config.  If you do it wrong you may encounter problems (things won't compile, you get errors about illegal declarations of things, etc).

You are not supposed to directly edit .config but are to either make xconfig or make menuconfig which run configuration programs. We found that using "make xconfig" as suggested by Klingauf DID NOT WORK- it turned on some features (without our knowledge) that resulted in code being included which would not compile. We use "make menuconfig" only

We suggest you start with a minimal .config file, get a working kernel, and then add features.  That is what we describe here.

The first step is to modify the Makefile so that the tools know you are going to build a PPC kernel. Make these changes in Makefile:

ARCH := ppc
CROSS_COMPILE = powerpc-405-linux-gnu-

Now, run "make menuconfig".

Below is one set of .config file features which we have used as a starting point.  Some of these are undoubtedly not used in our kernel but were turned on by default.  We have yet to experiment to find the minimal set of features required.  However, the following has worked and will get you started:

Code Maturity Level Options
   * Prompt for development and/or incomplete drivers

Platform Support
   * 40x Processor Type
   * Xilinx-ML300 Machine Type
   * Math emulation
   * <UART0> TTYS0 device and default console
   * UART0

General Setup
   * Networking support
   * Sysctl support
   * System V IPC
   * Default bootloader kernel arguments
      "console=ttyS0,38400 root=/dev/xsysace/disc0/part3 rw"

Memory Technology Devices (MTD)
   * Memory Technology Device (MTD) Support
   * MTD partitioning support
   * RedBoot partition table parsing
   * Direct char device access to MTD devices
   * Caching block device access to MTD devices
   * RAM/ROM flash chip device drivers
   * Detect flash chips by Common Flash Interface (CFI) probe
   * Suport for AMD/Fujitsu flash chips

Block Devices
   * Xilinx on-chip System ACE
   * Loopback device support
   * Network block device support
   * RAM disk support
       (4096) Default RAM disk size
   * Initial RAM disk (initrd) support

Networking Options
   * Socket Filtering
   * Unix domain sockets
   * TCP/IP networking
   * IP: multicasting
   * IP: kernel level autoconfiguration
   * IP: DHCP support
   * IP: TCP syncookie support (disabled per default)

Network Device Support
   * Network device support
   * Ethernet(10 or 100Mbit)
   * Ethernet (10 or 100Mbit)
   * Xilinx on-chip ethernet

Character devices
   * Standard/generic (8250/16550 and compatible UARTs) serial support
   * Support for console on serial port
   * Unix98 PTY support

File systems
   * Journaling Flash File System v2 (JFFS2) support
       (0) JFFS2 debugging verbosity (0=quiet, 2=noisy)
   * Virtual memory file system support (former shm fs)
   * /proc file system support
   * /dev file system support (EXPERIMENTAL)
   * Automatically mount at boot
   * /dev/pts file system for Unix98 PTY
   * Second extended fs support
   * Network file systems
   * NFS file system support
   * Provide NFSv3 client support
   * Root file system on NFS
   * NFS server support
   * Provide NFSv3 server support
   * SMB file system support (to mount Windows shares etc.)
   Native Language Support
      Default NLS Option: "iso8859-1"

Kernel hacking
   * Kernel debugging
   * Include BDI-2000 user context switcher
   * Add any additional compile options
   Additional compile arguments: "-g -ggdb"
     (0) Kernel messages buffer length shift (0=default)


7. Installing the BSP

Find the BSP directory tar file you generated in EDK above and un-tar it into your working Linux sources, overwriting files that were already there.


8. Making Kernel Patches

  1. I really don't like 9600 baud TTY's. On the XUP board there is only one serial port. So, the boot loader, boot process, and subsequent getty's all need to agree on the same baud rate for that one tty. To get the boot loader to talk at 38400, change the kernel source file: arch/ppc/boot/common/ns16550.c. In that file, changing SERIAL_BAUD from 9600 to 38400  makes the bootloader talk at 38400.
  2. By default, the MAC address of the ethernet will be set to Xilinx's default of: 00:0A:35:00:22:00. This means that if you have multiple such boards on a network, they will all have the same MAC address. This may or may not be a problem. You can change this in arch/ppc/boot/simple/embed_config. Look for this line:

    bd->bi_enetaddr[5] = 0x00;

    and change it to some other HEX value to change the MAC address.  There is a better way to do this using a hardware core but for now, this is how we are doing it.

9. Compiling the Kernel

At this point you should be able to compile the kernel as Klingauf and UIUC suggest:

% make dep && make zImage

The first error to appear is that arch/ppc/boot/simple/embed_config.c has an error due to needing an I2C eprom to hold the MAC address. It instructs you to comment a line out if you don't have an I2C eprom. Make that change and remake.

Late in the compilation process, the last Makefile to run (in arch/ppc/boot/simple/Makefile) has a problem. After creating the actual kernel (zvmLinux) it tries to move it twice. However, after the first move, it no longer is there. Find and change the first move to a copy.  In the process you may also want to change where the kernel gets put.  The default result is a kernel in arch/ppc/boot/images called zImage.elf.

You will notice that we have no dynamically loaded modules in our configuration so we don't need to "make modules".


10. The Initial Boot Attempt

As Klingauf puts it, you now have a freshly squeezed Linux kernel in your hands which you should give a try. 

At this point you could use EDK and XMD to configure the FPGA and load the kernel (zImage.elf) into memory to execute as the EDK supports.  However, the kernel is big enough that using the SystemACE for this purpose is preferable.

Up above, we gave instructions for creating a system.ace file which you can put onto a compact flash card.  Change the file xupGenace.opt to use the zImage.elf you just created and re-generate, put that CF in and reset the board.  If all goes well you should see something like this on a 38400 baud terminal tied to the serial port:

loaded at: 00400000 004C41E4
board data at: 004C113C 004C1154
relocated to: 00405684 0040569C
zimage at: 00405B89 004C0936
avail ram: 004C5000 10000000

linux/PPC load: console=ttyS0,38400 root=/dev/xsysace/disc0/part3 rw

This is the boot loader running.  If you wait 5 seconds, it will uncompress the Linux kernel (which is embedded in it as a compressed data structure) and then attempt to boot from it.  Or, you can start typing and change the parameters used to boot.  Here is the beginning of what is printed on our machine as it boots:

Now booting the kernel
linux version 2.4.26 (gcc version 3.4.1) #32 Mon Jul 11 01:49:29 MDT 2005
Xilinx Virtex-II Pro port (C) 2002 MontaVista Software, Inc.(source@mvista.com)
On node 0 totalpages: 65536
zone(0): 65536 pages.
zone(1): 0 pages.
zone(2): 0 pages.
...

Eventually, however, it will want to mount a root file system from the compact flash (due to the root=/dev/xsysace/disc0/part3 rw) in the parameters.  Since it doesn't yet have one, errors will ensue.


11. Root File System

The kernel will need a root file system to use. This root file system contains the startup files necessary to get the system up to a fully running state where you can log in.  It also provides all the utilities you will use (ls, chmod, ...) as well as as file system for you to do your work in.

There are two options for where the root file system can be located. The first is to put it onto the same compact flash (in a different partition) as the system.ace file is on. The second is to boot diskless and let the board find one on the network. The procedure for building both are the same - the difference is in where you put them and what you tell the kernel about where to find them.  In this section we focus on how to create the foot file system.

Klingauf's page tells how to build a root file system using BusyBox. We followed their instructions quite closely.

Basically, you download Busybox from the WWW and configure it.  You then download a sample /etc directory from Klingauf, and then run a mkrootfs.sh script of Klingauf's that builds the entire root file system.

Caution: the mkrootfs.sh script as well as the contents of the files in /etc that we got from Klingauf's page all had DOS newlines in what we downloaded. This caused some confusing errors until we figured it out.  We wrote and ran a quick perl script to fix them all. 

Klingauf's mkrootfs.sh script is an important script which saves a _lot_ of work.  It does the following:

  1. Blows away the existing root file system if one exists.
  2. Creates all the directories needed for the file system (/bin, /dev, /etc, ...).
  3. Sets up glibc.
  4. Fills the directories with the items Klingauf provides such as the /etc directory files.
  5. Makes busybox and other needed files and puts them into the new root file system.

The first step is to configure busybox.  You do this by running "make menuconfig" in the busybox directory.  Follow the instructions given by Klingauf.  We specifically turned the following off from the defaults:

General Configuration -> Runtime SUID/SGIDconfiguration via /etc/busybox.conf

We specifically turned the following on from the defaults:

   Build Options -> Do you want to build BusyBox with a Cross Compiler?
      (and set prefix correctly)

   Login/Password Management Utilites ->
      getty
      passwd
      su
      sulogin

   Networking Utilities->
      inetd
      ifconfig
      netstat
      nslookup
      telnet
      telnetd

The second step is to modify mkrootfs.sh.  The top few lines require customization for paths to be set up correctly.  This works since our stuff was compiled into /opt on our development platform:

LFS=/opt/xup_rootfs
CC=powerpc-405-linux-gnu
TARGET_PREFIX=/opt/powerpc-405-linux/powerpc-405-linux-gnu
BUILD_TOOLS=/opt/powerpc-405-linux
PPC_KERNEL_VERSION=2.4.26

In addition, at least two files in the final root file system had permissions which prevented them from executing when the board booted up.  To fix this and any other problems with ownerships/permissions we added the following to the bottom of mkrootfs.sh:

echo "Changing permissions and ownerships"
chown -R root ${LFS}
chmod -R a+x ${LFS}

Further, we made the following changes to Klingauf's /etc/inittab file:

::sysinit:/etc/init.d/rcS
#::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
::respawn:/sbin/getty 38400 tts/0

Finally, when running Klingauf's mkrootfs.sh we run it as root since it cannot remove the old file system when it starts up due to those files being owned by root.


At this point our instructions diverge from the Klingauf and UIUC pages.


12. Putting the Root File System on a Compact Flash

Following how the ML300 CF card was laid out in the ML300 development kit we have, we made 3 partitions on our CF card.

Under Linux, when we plugged in our reader and the CF (which came with a single DOS FAT16 partition), an entry was automagically made in /etc/fstab:

/dev/sdb1 /mnt/flash auto defaults,user,noauto 0 0

This tells us that /dev/sdb is the basic device.  Now, running:

fdisk /dev/sdb

lets us partition it.

After deleting the existing partition, make the following partitions: Partition 1 FAT16 (6), Partition 2 Linux Swap (82), and Partition 3 Linux (83).  The first partition only needs to be large enough to hold the system.ace file.  The 3rd partition is where the root file system will go.  We have yet to make use of the 2nd partition.

12.1 Formatting the 3rd Partition Under Linux

To format partition 3 with a Linux file system, run:

mke2fs /dev/sdb3

Then, add an entry for it to /etc/fstab:

/dev/sdb3 /mnt/rootfs auto defaults, user,noauto 0 0

and then mount it:

mount /mnt/rootfs

Finally, copy the root file system created in the previous step over to it and then unmount it and move the card to a WinXP box.

12.2 Formatting the 1st Partition Under WinXP

The first partition (the SystemACE partition) needs a special format for SystemACE to recognize it.  Back on a WinXP box, run:

mkdosfs -s 64 -F 16 -R 1 F:

You can find the mkdosfs program on the WWW.

Make and put a system.ace on partition 1 and you are ready to boot. 

12.3 Formatting the 2nd Partition Under Linux

The second partition (the SystemACE partition) needs a swap file system put on it.  On a Linux box, run:

mkswap /dev/sdb2


13. Booting From Compact Flash

When the board boots now, it should mount "/" from the compact flash as desired.  You can then log in as root (no password) and you are running .

Before you learn how to mount the foot file system using NFS (which is far easier than using the compact flash if you want to make modifications to the root file system), you need to get networking up.


14. Networking

A number of different ways exist to configure networking on the board.  We document two of the ways:  hard-wiring the board's IP address and gateway and using DHCP to get a dynamically-assigned address.

14.1 Static IP Address Networking

Once the board has booted from above, execute:

ifconfig eth0 192.168.0.7 up
route add default gw 192.168.0.1

This will bring up the ethernet connection (eth0) with an IP address and will use the specified address as a gateway (192.168.0.1). A place to put these commands is in the root file system under: /etc/init.d/rcS so they automatically execute when you reboot the board in the future. Remember that if you write to the CF root file system, be sure to do a couple of 'sync' commands to flush the data to the card before power-cycling the board.  Alternatively, you can execute reboot to reboot the board.

This method above presumes the board is wired into a network and the use of 192.168.x.x addresses implies it is an internal network only.

One setup is to use a Linux box to do NAT (network address translation) between the board and the rest of the network. To do so:

  1. Tie FPGA board to a Linux box using a crossover cable and a 2nd NIC on the Linux box.
  2. The 2nd NIC in the Linux box should be set to address 192.168.0.1. Add the following to /etc/network/interfaces so that the 2nd NIC will configure at boot time:

    auto eth1
    iface eth1 inet static
    address 192.168.0.1
    netmask 255.255.255.0
     
  3. Set up routing between the 2 NIC cards on the Linux box using IP-Masquerade (NAT). To learn about this, go to http://www.tldp.org/HOWTO/IP-Masquerade-HOWTO/index.html for info. Start reading in Section 3.

    NAT is a way for the Linux box to gateway traffic originating on the 192.168.x.x network (the crossover cable and corresponding NIC) to the network on the first NIC.

    To set up IP-Masquerade, you first determine that your Linux kernel has what is needed in the kernel, you then copy down their file called rc.firewall-iptables into /etc/init.d on the Linux box, and then you execute it from the command line. Packets coming to 192.168.0.1 should now be re-routed out to the rest of the network. 
  4. Once it is working, put the command to execute /etc/init.d/rc.firewall-iptables at the bottom of /etc/init.d/rc so it will re-execute on a reboot.

14.2 Setting up Name Resolution

Once you have IP-Masquerade working on your Linux box and the default route set up on your XUP board, packets on your XUP board will get forwarded out to the general network by the Linux box as needed.  However, you may find that things like: 'nslookup ee.byu.edu' may still not work from the XUP board since name resolution may not be set up correctly.  In your root file system find the file /etc/resolv.conf.  This should contain the address of a valid name server (the default the Klingauf's script uses is: 134.169.33.1.  Find one closer to home and put into that file.  Now you can 'nslookup ee.byu.edu' and it should work, as should 'ping cs.utah.edu' and other similar commands that require name resolution.

14.2 Using DHCP to Automagically Get an IP Address

Alternatively, you can use DHCP to automagically get an IP address for the board.

  1. Configure the kernel to include DHCP if it isn't already configured.
  2. In the kernel command line set ip=on.  That is, the kernel command line which you configured should be:

    console=ttyS0,38400 root=/dev/xsysace/disc0/part3 rw ip=on

    You can either add this to the command line when the bootloader gives you a chance to do so or you can re-build the kernel with this included.
  3. If you have added lines to /etc/init.d/rcS or any other startup file to set a hardwired IP address, remove those now.  Otherwise, they will over-ride the DHCP-obtained addresses and mess things up.

Now, run dhcpd on the Linux box with the the FPGA board plugged into it. Put the following into /etc/dhcpd.conf:

subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.7 192.168.0.15;
}

Then, run dhcpd like this:

dhcpd -f eth1

from the command line. This will start up the daemon but only on the 2nd NIC on the Linux box.

When the board boots, the Linux box will give it a 192.168.0.x address as well as gateway information.

When you like the results, put the 'dhcpd eth1' command into a startup file (leave off the -f parameter since that is for running it interactively).  A good place to put this is at the end of /etc/init.d/rc on your Linux box.

14.3 Using DHCP With a WinXP Box

You may be working in a lab where the only box you have to plug your board into is a WinXP box.  If so, you can still talk to the network.  Here is a quick way:

  1. As before, use a 2nd NIC in the WinXP box and a crossover cable to tie it to the board.
  2. In WinXP Network Connections, set the IP address of the 2nd NIC to 192.168.0.1
  3. In WinXP Network Connections, bridge the 1st and 2nd NIC's (select both, right click, and select 'Bridge Connections').
  4. As above, put ip=on into the kernel command line.

On a reboot, the board gets an IP address via DHCP. It is quite slow to do so on our network (10-30 seconds) but it eventually gets an address.  However, the address received is now from the general network rather than a local 192.168.x.x address.  If your network only gives out addresses to known MAC-ID's, this may fail.  This is because the WinXP box is bridging rather than routing.  Figure out how to get the WinXP box to do routing if you need to.


15. Mounting a Remote Root File System Using NFS

With networking operational, you can now get the board to boot 'diskless' (mount its root file system from somewhere else other than the CF). This can have some nice advantages for system development. That is, you can edit things on the root file system from a Linux box and not have to keep copying it over to the CF  card. There are at least two options for this: BOOTP and NFS. This document will only discuss NFS.

  1. Be sure NFS is configured into the kernel as well as "Root file system on NFS".

  2. On the kernel command line when it boots, use the following:

    root=/dev/nfs nfsaddrs=client:server:gateway:netmask rw nfsroot=/opt/xup_rootfs console=ttyS0,38400

    The "root=/dev/nfs" tells it to look at NFS for the root file system.

    Client is what the board's address will be (we insert 192.168.0.10 here).  Server is the address of the machine that actually will serve the root file system (we use 192.168.0.1). It can be any address that is reachable.  Gateway is how the board is to get to the network, and thereby to the server (we use 192.168.0.1).  Netmask should be obvious (we use 255.255.255.0). Server and gateway can both be the same but they need not be.

  3. As before, if you use this option, remove any commands which set up the network to a hard IP address (like in /etc/init.d/rcS) which you may have set or things will not work as desired.  

Setting up the Linux box to serve the file system is standard stuff.  Put the following in /etc/exports:

/opt/xup_rootfs 192.168.0.10(rw,no_root_squash,sync)

where the first arg is what is to be NFS-exported and the second arg is who to export it to (the board).

Next, put the following in /etc/hosts.deny:

portmap:ALL
lockd:ALL
mountd:ALL
rquotad:ALL
statd:ALL

This prevents any machine from using these services.

Then, put the following in /etc/hosts.allow to allow the board access to the services:

portmap:192.168.0.10
lockd:192.168.0.10
mountd:192.168.0.10
rquotad:192.168.0.10
statd:192.168.0.10

Finally, any time you change /etc/exports, you should get the daemon to re-read that file using:

exportfs -ra

A good short document on how to do this setup is at: 

http://nfs.sourceforge.net/nfs-howto/server.html

Another document on Linux kernel command line parameters for this is:

http://stommel.tamu.edu/~baum/linux-kernel/nfsroot.txt.

15.1 Other NFS Mounts

To mount other volumes, do the following:

mount -t nfs 192.168.0.1:/remoteDirectoryName localDirectoryName


16. Networking Summary

16.1 Hard-wired IP Address + Compact Flash Root File System

Put the following into /etc/init.d/rcS on the compact flash root file system:

ifconfig eth0 192.168.0.10 up
route add default gw 192.168.0.1

In addition, use the following for your kernel boot command line:

console=ttyS0,38400 root=/dev/xsysace/disc0/part3 rw

An alternative would be to not put the ifconfig and route commands into the rcS file but rather execute them each time you boot the machine.

16.2 DHCP IP Address + Compact Flash Root File System

REMOVE the ifconfig and route commands from /etc/init.d/rcS on the compact flash root file system. 

Use the following for your kernel boot command line:

console=ttyS0,38400 root=/dev/xsysace/disc0/part3 rw ip=on

The additional "ip=on" tells it to use DHCP.

16.3 Hard-wired IP Address + NFS Root file system

REMOVE the ifconfig and route commands as above.  Then, use the following for your kernel command line (all on one line):

console=ttyS0,38400 root=/dev/nfs nfsaddrs=client:server:gateway:netmask rw nfsroot=/opt/xup_rootfs

where the contents of the NFS addresses are as described above and the path to the NFS root file system is set as above.   When you do this, make sure you do not have any ifconfig or route commands in the remote /etc/init.d/rcS file as these will conflict with the IP address you hard-wired on the boot command line.


17. Troubleshooting

  1. A common error is changing the actual files in your exported root file system and then re-generating it back on the Linux box.  This removes the existing root file system and builds a brand new one.  Thus, if you add networking commands to /etc/init.d/rcS but then re-generate the root file system, the commands are gone after the re-generate. 
  2. Related to above, another common error is to change the template /etc/init.d/rcS in the root file system creation directory and then re-generating the root file system.  As above, after the re-generate things are not what you may have expected.
  3. If you originally hard-code the IP address in your /etc/init.d/rcS and then later decide to try to use DHCP or an NFS-mounted root file system, the two IP address assignments will conflict.
  4. After you re-build your root file system on your Linux box, you need to re-run 'exportfs -ra'.  The reason?  When you blow away the entire exported directory (which the mkrootfs.sh script does) while it is being exported, NFS gets confused.  Re-running this command causes it to re-initialize itself.

18. Cleanup

A number of the files from the provided root file system have references to the ML300 board, etc. This is because these instructions were adapted from that port. You may want to change some of these messages or others (see, for example, /etc/motd).


19. Other Boards

This discussion is somewhat specific to the XUP board.  However, large sections are independent of the board and will therefore be useful for other boards.  The only board-specific parts of the process seem to be:

  1. The options to use when creating a system.ace file are board dependent.  Note the section above for specifics for the ML-403 board.

  2. The devices included in this design include only the ethernet, the serial port, and the SystemACE.  The ML300 reference design which is documented by Klingauf and UIUC include other devices (and therefore drivers).  These include: opb_gpio, opb_iic, dcr_intc, opb_spi, opb_tsd_ref, plb_tft_cntrl_ref, opb_pci_ref, and opb_ps2_dual_ref.

    As a result, the ML300 reference design should provide guidance on the use of these additional peripherals.  However, if you have a board that requires additional peripherals, you will have to look elsewhere for instructions.


Indexing Keywords: Linux, Xilinx, Virtex-II Pro, Virtex-4, XUPV2P