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.
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".
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.
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:
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.
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.
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.
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.
The second partition (the SystemACE partition) needs a swap file system put on it. On a Linux box, run:
mkswap /dev/sdb2
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.
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.
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:
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.
Alternatively, you can use DHCP to automagically get an IP address for the board.
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.
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:
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.
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.
Be sure NFS is configured into the kernel as well as "Root file system on NFS".
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.
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:
Another document on Linux kernel command line parameters for this is:
To mount other volumes, do the following:
mount -t nfs 192.168.0.1:/remoteDirectoryName localDirectoryName
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.
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.
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.
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).
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:
The options to use when creating a system.ace file are board dependent. Note the section above for specifics for the ML-403 board.
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.