Home»Projects »Native gcc c compiler for PowerPC405 on the Xilinx ML403 board

Native gcc c compiler for PowerPC405 on the Xilinx ML403 board

This page provides a native ppc405 gcc for MontaVista Linux Professional Edition 3.1 on the Xilinx ML403 board. Scroll right to the bottom of this page for download. The remainder of this page simply explains how gcc was ported.

Xilinx ML403 Development Platform

Go to Xilinx-ML403 picture

Xilinx ML403 development board and Platform Cable USB, a JTAG probe.

The Xilinx ml403 development board is built around a Xilinx Virtex-4 XC4VFX12. The XC4VFX12 contains a 300 MHz PowerPC 405 processor and an FPGA. Main memory is 64 Mbyte RAM. The 512 MByte Compact Flash shipped with the board contains a demo of MontaVista Linux Professional Edition 3.1.
I use the ml403 board to develop hardware acceleration for MPEG2 decoding; the port of gcc is a by-product of that development effort.

NFS root and swap

Giving our ML403 development system a bigger "hard disk"

Suppose you have the ml403 board up and running, but you find the compact flash disk is a bit too small for comfort; and the memory available is too tight. You could, of course, buy a bigger Compact Flash or even a Microdrive. Another possibility is using NFS to get a bigger disk and some swap. In what follows the NFS server is called "laptop" and has ip 192.168.153.4; the NFS client is the ml403 development board with ip 192.168.153.5.

Extracting the linux disk image from compact flash

Download the compact flash image from the Xilinx web site. How one extracts a disk partition from a disk image is explained in Splitting The Disk. Basically, you use fdisk to see how the disk image is set up, and extract the partition you want using dd.

root@laptop:~# wget http://www.xilinx.com/products/boards/ml403/files/ml403_cf.img.zip
root@laptop:~# unzip ml403_cf.img.zip
Archive: ml403_cf.img.zip
inflating: ml403_cf_71b.img
root@laptop:~# fdisk -ul ml403_cf_71b.img
You must set cylinders.
You can do this from the extra functions menu.

Disk ml403_cf_71b.img: 0 MB, 0 bytes
16 heads, 63 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes

Device Boot Start End Blocks Id System
ml403_cf_71b.img1 63 196559 98248+ 6 FAT16
ml403_cf_71b.img2 196560 1000943 402192 83 Linux

We want the second partition, the one marked "Linux". Let's calculate the size of the Linux partition in 512-byte sectors.

root@laptop:~# bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1000943-196560+1
804384
quit
root@laptop:~# dd if=ml403_cf_71b.img of=ml403.ext3 bs=512 skip=196560 count=804384
804384+0 records in
804384+0 records out

After this, the file ml403.ext3 contains the linux disk image.

Increasing the size of the disk image

Let's make the disk image bigger; say 4 Gbyte. Writing zeroes beyond the end of file extends the disk image.

root@laptop:~# dd if=/dev/zero of=ml403.ext3 bs=1M seek=4095 count=1
1+0 records in
1+0 records out
root@laptop:~# e2fsck -y -f ml403.ext3
e2fsck 1.35 (28-Feb-2004)
Pass 1: Checking inodes, blocks, and sizes
Inode 93117 has illegal block(s). Clear? yes
...

Lots of output here. Maybe the filesystem image was truncated, or someone switched the system off without unmounting flash? Anyhow, now we can extend the filesystem.

root@laptop:~# resize2fs -p ml403.ext3
resize2fs 1.35 (28-Feb-2004)
Resizing the filesystem on ml403.ext3 to 4194304 (1k) blocks.
Begin pass 1 (max = 974)
Extending the inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 2 (max = 270)
Relocating blocks XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 50)
Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 5 (max = 9)
Moving inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*** glibc detected *** double free or corruption (!prev): 0x080536b0 ***
Aborted

Oops. Let's run fsck a few times to clean up the filesystem:

root@laptop:~# e2fsck -y -f ml403.ext3 
root@laptop:~# e2fsck -y -f ml403.ext3

Mounting the disk image on the NFS server

We set up a loopback device with the disk image and mount it:

root@laptop:~# losetup /dev/loop0 ml403.ext3 
root@laptop:~# mount /dev/loop0 /mnt/hd
root@laptop:~# mount
...
/dev/loop/0 on /mnt/hd type ext2 (rw)
root@laptop:~# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda2 28297628 13146320 15151308 47% /
/dev/loop/0 4064034 362180 3534082 10% /mnt/hd
root@laptop:~# ls /mnt/hd/
bin dev home lost+found opt root tmp var
boot etc lib mnt proc sbin usr

Exporting the disk image over nfs

On the NFS server:

root@laptop:~ # more /etc/exports 
# See exports(5) for a description.
# This file contains a list of all directories exported to other computers.
# It is used by rpc.nfsd and rpc.mountd.
/mnt/hd 192.168.153.5(rw,sync,no_root_squash)
root@laptop:~ # /etc/rc.d/rc.nfsd start
Starting NFS services:
/usr/sbin/exportfs -r
/usr/sbin/rpc.rquotad
/usr/sbin/rpc.nfsd 8
/usr/sbin/rpc.mountd
/usr/sbin/rpc.lockd
/usr/sbin/rpc.statd

On the NFS client, ml403:

root@ml403:~# more /etc/fstab 
# /etc/fstab: static file system information.
#
# <file system> <mount point> <type> <options> <dump> <pass>
/dev/root / auto defaults,errors=remount-ro 0 0
proc /proc proc defaults 0 0
192.168.153.4:/mnt/hd /mnt/nfs nfs timeo=60,rsize=8192,wsize=8192,vers=2,intr,tcp,noauto 1 0
root@ml403:~# mount /mnt/nfs/
root@ml403:~# mount
rootfs on / type rootfs (rw)
/dev/root on / type ext3 (rw)
none on /dev type devfs (rw)
proc on /proc type proc (rw)
tmpfs on /dev/shm type tmpfs (rw)
192.168.153.4:/mnt/hd on /mnt/nfs type nfs (rw,v2,rsize=8192,wsize=8192,hard,intr,tcp,lock,addr=192.168.153.4)

Note the 2.4.20 MontaVista kernel shipped with the ml403 development board has a NFS client bug. Nagle hasn't been switched off in the NFS TCP client, leading to poor performance. A workaround is disabling Nagle altogether:

root@ml403:~# sysctl -w net.ipv4.tcp_sack=0                                     
net.ipv4.tcp_sack = 0

This disables Nagle for all applications; the resulting increase in packets usually isn't a problem if your traffic is mainly LAN-based, not WAN.

Swapping over the network

Create a large file on the server, access it over NFS and swap on it:

root@ml403:~# mount
rootfs on / type rootfs (rw)
/dev/root on / type ext3 (rw)
none on /dev type devfs (rw)
proc on /proc type proc (rw)
tmpfs on /dev/shm type tmpfs (rw)
192.168.153.4:/mnt/hd on /mnt/nfs type nfs (rw,v2,rsize=8192,wsize=8192,hard,intr,tcp,lock,addr=192.168.153.4)
root@ml403:~# dd if=/dev/zero of=/mnt/nfs/swapfile bs=1M count=128
128+0 records in
128+0 records out
root@ml403:~# losetup /dev/loop0 /mnt/nfs/swapfile
root@ml403:~# mkswap /dev/loop0
Setting up swapspace version 1, size = 134213632 bytes
root@ml403:~# swapon /dev/loop0
Adding Swap: 131064k swap-space (priority -1)
root@ml403:~#

Going to the chroot

root@ml403:~# chroot /mnt/nfs /bin/bash
root@ml403:/# pwd
/
root@ml403:/# ls
bin dev home lost+found opt root swapfile usr
boot etc lib mnt proc sbin tmp var
root@ml403:/# mount -t proc none /proc
root@ml403:/# mount -t devfs none /dev
root@ml403:/# swapon -s
Filename Type Size Used Priority
/dev/loop/0 partition 131064 0 -1
root@ml403:/# mount
rootfs on / type rootfs (rw)
/dev/root on / type ext3 (rw)
none on /dev type devfs (rw)
proc on /proc type proc (rw)
tmpfs on /dev/shm type tmpfs (rw)
192.168.153.4:/mnt/hd on / type nfs (rw,v2,rsize=8192,wsize=8192,hard,intr,tcp,lock,addr=192.168.153.4)
proc on /proc type proc (rw)
none on /dev type devfs (rw)

So there we have it: to all effects, it now looks as if we have 4G of disk space, and 128M of swap on our ml403.

 

Native gcc Compiler

We have memory, we have disk space. Now all we need is a native C compiler on the ml403 and we're ready to do some serious porting. But compilers don't grow on trees - if you have a native compiler someone somewhere once cross-compiled the compiler.

I don't like cross-compiling. I avoid it if I can. But if I have to cross-compile, I'll try to have as few differences between development and target system as possible. Hence choosing a PowerPC Linux as build platform.

To get a native compiler for the ppc405 in the Xilinx ML403 board, following steps were taken:

The /usr/lib/crt* files are the C Run-Time files. These files contain the code that runs before main() and after exit(). Unfortunately, /usr/lib/crt1.o, crti.o and crtn.o on the ml403 target system were stripped of all symbol information, making them not very useful for linking with. C run-time files with symbol information were obtained by compiling glibc on the imac, and copying crt1.o, crti.o and crtn.o over to the ml403. YMMV.

As a small test, I compiled and installed Gnu flex natively on the ml403. To give an indication of compilation speed: ./configure took 28 seconds, make 81 seconds. Note when using NFS it's better if server and client system clocks are synchronized, or you'll get clock skew when using make.

 

 

Downloads

ml403-ppc405-gcc402-1.0.tar.bz2 (25 Mbyte) Native PowerPC 405 binutils-2.16.1, gcc-4.0.2, flex-2.5.4a and crt.* files. The tar archive contains a script, ml403-ppc405-gcc402-install, which downloads the ml403 compact flash image from the Xilinx web site, extracts the linux filesystem from the compact flash image, and adds the gcc binaries to the ml403 filesystem. As your linux setup may differ from mine, I suggest you do not blindly execute this script. Execute the scripts' commands one by one instead, manually verifying each step.

ml403-ppc405-gcc402-1.0.tar.bz2.md5sum MD5 checksum.

Last update page: November 12, 2005