Home > Articles

  • Print
  • + Share This
This chapter is from the book

Building tbdev1, the Embedded Linux Development Workstation

The Silverjack engineers decided to consolidate all the Project Trailblazer development tools in a single place. They devoted a single computer to act as a development workstation, hosting all the compilers, cross-compilers, debuggers, libraries, and kernel and application source code. This consolidation simplified the development activities because the engineers didn't have to spend time configuring each engineer's workstation for cross-development. This section outlines the steps for building tbdev1, the Project Trailblazer development workstation:

  1. Getting started

  2. Installing the Linux operating system

  3. Installing the native GNU tool chain and other applications

  4. Building the GNU tool chain for cross-compiling

After these four steps have been completed, tbdev1 will be capable of compiling C code for the x86 using gcc. Cross-compilers for PowerPC (powerpc-linux-gcc), and ARM (arm-linux-gcc) processor will also be created. All the examples in subsequent chapters utilize the tbdev1 workstation. The remaining sections in this chapter help you to create your own tbdev1 workstation that's identical to Project Trailblazer's tbdev1.

TIP

Creating a cross-development environment generates a set of libraries for another CPU architecture, such as PowerPC or ARM. During the installation process, you have an opportunity to overwrite the existing x86 libraries with a PowerPC or ARM version. Devoting a computer to act as the cross-development workstation eliminates the possibility of destroying your personal desktop workstation x86 libraries.

Getting Started

In this section we'll build the tbdev1 development workstation, using the Debian distribution potato, which is Debian version 2.2r5 (kernel 2.2.19). You can download potato and install it on tbdev1 using a LAN Internet connection and three floppy disks. The resultant workstation will contain only the software required to build the cross-development environment. Other programs, such as sendmail, Web servers, and X Windows, will not be installed, thus lowering hardware requirements for tbdev1. Here's what you need to get started:

  • An x86 computer with 32MB RAM and 1.5GB or larger drive, with a master drive on the primary IDE controller and an Ethernet card

  • Three 1.44 floppy disks

  • A LAN Internet connection

  • A keyboard and a monitor

To start, you need to download three floppy image files from the Debian Web site (http://www.debian.org). At this point, you might not have a Linux machine running. Therefore, Microsoft Windows instructions are included here, but only to the point where you get Linux up and running. After that, only Linux instructions are given because Project Trailblazer is, after all, a Linux project.

You need to download three images files, using your browser, FTP, wget, or lynx. You should download the files into a temporary directory called /tmp or c:\tmp, which you might need to create. Here's the base URL for the image files:

http://ftp.us.debian.org/debian/dists/stable/
main/disks-i386/current/images-1.44/idepci/

Download these three image files: rescue.bin, root.bin, and driver-1.bin.

If you are a Windows user, you need to also download a program called rawrite2.exe from ftp://ftp.debian.org/debian/tools.

Now you need to create the installation disks. To do so, Unix users should use the following commands:

holla@taylor[501]: cd /tmp
holla@taylor[502]: dd if=rescue.bin of=/dev/fd0 bs=1024 conv=sync ; sync
holla@taylor[503]: dd if=root.bin of=/dev/fd0 bs=1024 conv=sync ; sync
holla@taylor[504]: dd if=driver-1.bin of=/dev/fd0 bs=1024 conv=sync ; sync

Windows users should open a DOS window by choosing Run from the Start menu, entering command and pressing Enter. Then in the DOS window enter following:

C:\> cd c:\tmp
C:\tmp> rawrite2 -f rescue.bin -d a:
C:\tmp> rawrite2 -f root.bin -d a:
C:\tmp> rawrite2 -f driver-1.bin -d a:

Label the disks "rescue," "root," and "drivers." You are now ready to start the potato installation on tbdev1.

Installing the Linux Operating System

The instructions in the following sections step through the potato network installation process. The steps include a portion of what you'll see on your installation screen and the action you should take. The intention here isn't to teach you about the Debian installation; please read Debian's detailed install guides at http://www.debian.org/releases/stable/#new-inst for more information. In this section you'll quickly build a Linux workstation to compile the cross-compiler and libraries. The numbered lines in the steps below match what you should see on your workstation monitor during the Debian installation process.

Step 1: Boot tbdev1

In this step, you boot your workstation, using the floppy disks that you just created. The rescue disk contains the Linux kernel. The root disk contains a compressed filesystem that this kernel uses during the installation process. Follow these steps:

  1. Insert the floppy disk marked rescue and turn on your workstation.

  2. The Welcome screen should appear, with a boot: prompt. Press Enter.

  3. The Linux kernel on the rescue disk loads into memory and begins executing. You should see about 50 lines showing the status of the boot process. The boot process stops when the kernel needs access to the root filesystem. You see this: VFS: Insert root floppy to be loaded into RAM disk and press ENTER:. Remove the rescue disk and insert the root floppy and press Enter.

  4. The Release Notes Screen appears. Read through the notes if you want, and then press Enter.

Step 2: Partition the Hard Disk

In this step, you remove the existing partitions on the master drive on your primary IDE controller. Then you create a swap and root partition on that drive. This operation destroys all the information on that disk. Make sure that you have the correct disk installed, and then follow these steps:

TIP

If you have multiple drives in your computer, you might want to disconnect all of them except the one you're installing Linux on. This ensures that you don't accidentally install Linux on the wrong drive.

  1. The Debian installation screen has an option Partition a Hard Disk. Use the arrow keys to highlight this option and then press Enter.

  2. The Select Hard Drive screen allows you to select a hard disk drive to partition. Select /dev/hda and press Enter.

  3. The LILO Limitations screen appears. Read about the limitations and then press Enter.

  4. At this point you're about to repartition the master drive on your primary controller. Make sure you have the correct disk installed. The cfdisk screen presents you with a list of current partitions and a menu along the bottom. Use the up and down arrows to select from the partition list. Use the right and left arrows to select a menu item. Select the first partition, and then select Delete and press Enter. Continue until you have deleted all the drive partitions.

  5. Make a new 64MB swap partition by first selecting the New menu and pressing Enter. Then select Primary and press Enter, set the size to 64 and press Enter, and select Beginning and press Enter.

  6. The partition list should now have an hda1 entry. With it selected, select the Type menu and set the type to 82 (Linux Swap). At this point, the partition list should show a 64MB swap partition called hda1.

  7. Select Free Space from the partition list.

  8. Make new partition by first selecting the New menu and then selecting Primary. Set the size to use the remainder of the drive space, and then select Beginning.

  9. The partition list should now have an hda2 entry. With it selected, select the Type menu and set the type to 83 (Linux). At this point, the partition list should show a 64MB swap partition called hda1 and another partition with filesystem, FS type, Linux.

  10. Select hda2 from the partition list, and then make hda2 bootable by selecting the Bootable menu.

  11. Finalize this partitioning by selecting Write and confirm the write operation with by typing yes.

  12. Exit from the cfdisk screen by selecting Quit.

Step 3: Configure the Keyboard and Activate the Partitions

In step 3 you configure and activate the hda1 and hda2 partitions you just created. Remember that hda1 is the 64MB swap partition. Follow these steps:

  1. Select the Configure Keyboard menu and press Enter. Select the keyboard that best fits your situation and press Enter.

  2. Activate the swap partition by selecting the Initialize and Activate a Swap Partition menu, and then select /dev/hda1. When you're asked to skip the scan for bad blocks, select No. When you're asked whether you are sure, confirm by selecting Yes.

  3. Activate the Linux partition by selecting the Initialize a Linux Partition menu, and then select /dev/hda2. When asked about Pre-2.2 Linux kernel compatibility, select No. When asked to skip the scan for bad blocks, select No. When asked whether you are sure, confirm by selecting Yes.

  4. Finalize the activation by mounting /dev/hda2 as the root file system. When asked "Mount As Root Filesystem?" select Yes.

Step 4: Install the Operating System Kernel and Modules

Now that the hard disk is partitioned, initialized, and mounted, it's time to copy the Linux kernel and modules. To do so, follow these steps:

  1. Start copying by selecting the Install Operating System Kernel and Modules menu.

  2. At the Select Installation Medium screen, select /dev/fd0 and press Enter.

  3. Insert the rescue disk and then select Continue. The installation program copies the kernel file contained on the rescue disk to the hard disk.

  4. When asked to insert Driver Disk 1, remove the rescue disk and insert the drivers disk and then select Continue. The drivers are then copied to the hard disk.

  5. Select Configure Device Driver Modules from the main menu.

  6. When asked about skipping the additional drivers floppy, select Yes.

  7. Configure the workstation's Ethernet card. The driver's floppy disk contains Ethernet drivers for a wide variety of Ethernet cards. Start by selecting Net: Drivers for Network Interface Cards and Network Protocols.

  8. TIP

    Drivers for these Ethernet cards—3COM, Western Digital/SMC, Racal-Interlan, AMD PCnet32, DECchip Tulip, EtherExpressPro/100, PCI NE2000, and VIA Rhine—are already built in to the potato kernel.6 If you have one of these cards, you can skip to the section "Step 5: Configure the Network."

  9. Select your Ethernet card from the list. For example, select ne for a NE2000 compatible. Select OK by pressing Enter.

  10. When asked to install this module in the kernel, confirm by selecting Yes.

  11. Some Ethernet cards require additional configuration. When asked to enter command-line arguments, enter your Ethernet card's I/O address and IRQ if necessary. For this example, you might enter io=0x300 irq=5.

  12. The installation program loads the Ethernet driver, and the driver attempts to find the Ethernet card. If the driver finds the card, a screen announces successful loading of the driver. If the card is not found, you have the option to restart and correct the Ethernet card configurations. Your ethernet card needs to be functioning correctly to complete the installation.

  13. Exit the module configuration by selecting Exit from the Select Net Modules menu, and then select Exit from the Category menu.

Step 5: Configure the Network

Now that the kernel is installed and the Ethernet driver has found the Ethernet card, it is time to configure the network. Later, you'll need the network to install the various applications that you download from the Debian Web site. Follow these steps to configure the network:

  1. Select Configure Network from the main menu.

  2. When asked to choose the host name, enter tbdev1 and press Enter.

  3. When asked about automatic network configuration, select No. No DHCP or BOOTP server exists. You are going use static IP addressing.

  4. When asked to choose the IP address, type 192.168.1.11 and press Enter.

  5. When asked to choose the network mask, type 255.255.255.0 and press Enter.

  6. When asked what your IP gateway address is, type 192.168.1.254 or your network gateway address and press Enter.

  7. When asked to choose the domain name, leave the name blank and press Enter.

  8. When asked to choose the DNS name addresses, enter 192.168.1.1 or your DNS server address and press Enter.

  9. Next, you need to install a collection of programs called the base system. Select Install Base System and press Enter.

  10. You will be downloading the base system from the Debian Web site. Select Network: Retrieve from Network and press Enter.

  11. The installation program announces that it is about to fetch the base2_2.tgz installation over the network using HTTP. Select Continue.

  12. At the Select installation server screen, use the Tab key to select OK, and then press Enter.

  13. The installation program downloads the 16MB Base2_2.tgz file from the Debian Web site. This is a perfect time to take a break.

Step 6: Configure the Base System

The installation program finishes the download of Base2_2.tgz, decompresses it, and installs various applications and files on your hard disk. There's not much involved in configuring the base system other than setting the time zone. Follow these steps:

  1. Select Configure Base System from the main menu and press Enter.

  2. Scan through the list and select your time zone. Then use the Tab key to select OK.

  3. When asked to set your clock to GMT, select Yes.

Step 7: Make Linux Bootable Directly from the Hard Disk

With the kernel, device drivers, and base system installed, one more step remains: making Linux bootable directly from the hard disk. In this step, you write the Linux Loader (LILO) bootloader to the hard disk's master boot record (MBR). When the computer boots, the bootloader code executes first and loads the Linux kernel from the hard disk to memory. Then the kernel executes. Follow these steps:

  1. At the main menu, select Make Linux Bootable Directly From Hard Disk and press Enter.

  2. Choose /dev/hda from the Where Should the LILO Bootloader Be Installed? menu and press Enter.

  3. Select Reboot the System at the main menu and confirm by selecting Yes. Eject the disk. The computer reboots from the hard disk and the installation process continues.

Step 8: Set Passwords, Accounts, and PPP

After rebooting, the installation process continues: You configure passwords, accounts, and point-to-point protocol options. To do so, follow these steps:

  1. When asked "Shall I enable MD5 Passwords?", select No.

  2. When asked "Shall I install shadow passwords?", select No.

  3. When prompted "Enter a password for root", type p or something you'll remember and press Enter.

  4. When prompted to re-enter password to verify, retype the password you just entered and press Enter.

  5. When asked, "Shall I create a normal user account?", select No. You can add user accounts later, with the adduser command.

  6. When asked, "Shall I remove pcmcia packages?", select Yes.

  7. When asked, "Do you want to use a PPP connection to install the system?", select No.

Step 9: Configure apt

All major Linux distributions support a software package management system that ensures clean and easy software installations through dependency and conflict checking. The Debian package system, apt, works with packages called debs, and its command-line interface program is called apt-get. System administrators use apt-get to install and remove software packages. The apt package management system requires updated package lists. In this step, you use the installation program to configure apt and download the current package lists from the Debian Web site:

  1. At the Apt Configuration menu, select http and press Enter.

  2. When asked, "Use non-US software?", select Yes.

  3. When asked, "Use non-free software?", select Yes.

  4. When asked, "Use contrib software?", select Yes.

  5. When asked to select a country, select your country and press Enter.

  6. When asked to choose the Debian mirror to use, select http.us.debian.org or the mirror closest to you.

  7. When asked to enter http proxy information, leave a blank or fill in your HTTP proxy information.

  8. At this point, the install program downloads apt package information from the Debian site.

  9. When asked to add another apt source, select No.

  10. When asked, "How do you want to choose additional software to install?", select Advanced and then select OK.

  11. A program called dselect starts. Don't install any software with dselect at this time. At the Start dselect screen, select OK.

  12. Exit from dselect by selecting Quit.

Step 10: Have Fun!

The potato installation is now complete. Follow these steps:

  1. The installation program instructs you to have fun. So select OK and start having some fun!

  2. You now get a tbdev1 login prompt. Log in as root, with the password you set earlier. This logs you in to tbdev1 as root, running the bash shell.

  3. Check the disk filesystem space usage with the df command. This shows the hard disk space requirement for a clean potato installation. Here's a sample of df output:

  4. Filesystem      1k-blocks   Used Available Use% Mounted on
    /dev/hda2       4854520     67496  4540428  1% /

You have now completed the potato installation. Next, you need to use apt-get to install a few packages that are required to build the GNU tool chain.

Installing the Native GNU Tool Chain and Other Applications

The potato base system that was installed in the section "Step 6: Configure the Base System" does not contain many development tools. You need to install a few packages to build the GNU tool chain. At the prompt, type these apt-get commands to install additional development tools:

root@tbdev1[501]: apt-get -y install gcc
root@tbdev1[502]: apt-get -y install make
root@tbdev1[503]: apt-get -y install file
root@tbdev1[504]: apt-get -y install flex
root@tbdev1[505]: apt-get -y install bison
root@tbdev1[506]: apt-get -y install patch
root@tbdev1[507]: apt-get -y install libc6-dev
root@tbdev1[508]: apt-get -y install perl
root@tbdev1[509]: apt-get -y install bzip2
root@tbdev1[510]: apt-get -y install wget
root@tbdev1[511]: apt-get -y install libncurses4-dev
root@tbdev1[512]: apt-get -y install telnetd

You're now ready to build the GNU tool chain for cross-compiling. The gcc compiler you just downloaded is the native x86 compiler that generates x86 executables. You are going to use this x86 compiler to compile two new versions of gccpowerpc-linux-gcc and arm-linux-gcc—that create PowerPC or ARM executables. The next section discusses cross-compiling and the creation of powerpc-linux-gcc and arm-linux-gcc, the cross-compilers and their appropriate glibc library files, and gdb.

Building the GNU Tool Chain for Cross-Compiling

A cross-compiler runs on a processor but generates executable code for a different processor. For example, an ARM cross-compiler running on an x86 processor generates code for an ARM processor, and a PowerPC cross-compiler generates code for a PowerPC.

Why does Project Trailblazer require a cross-compiler? Typically embedded systems don't have the RAM or storage resources to compile their own executables. A host processor, in this case tbdev1, can cross-compile code to create an executable. This executable is then transferred and executed on the target board. The GNU tool chain is capable of cross-compiling, but not as a command-line option. The entire tool chain requires compiling for operation as a cross-compiler. This is not a simple make, make install, apt-get, or rpm process. The cross-compiler build process is not completely documented or kept current.

The Trailblazer engineers are using the Embedded Planet RPX-CLLF (PowerPC MPC860) and the Brightstar MediaEngine (ARM SA-1110). They found two HOWTOs that explain building the GNU tool chain for the ARM and PowerPC processors:

Reading through these HOWTOs, the engineers discovered that building a cross-compiled version of the GNU tool chain is quite an operation. They first manually built the tool chain. Later, they switched kernel versions and found that they had to rebuild the tool chain because gcc and glibc depend on kernel header files. Manually building the tool chain is tedious and prone to mistakes, so the engineers automated the process by developing a bash script called buildtoolchain.

buildtoolchain can build either PowerPC and ARM cross-compiled versions of gcc, glibc, gdb, GNU utilities, and a helloworld test program. The buildtoolchain script simplifies compiling of powerpc-linux-gcc and arm-linux-gcc, the appropriate glibc library files, and gdb. buildtoolchain isn't a monolithic script with 12 steps; rather, it is a collection of 14 scripts. First, there's buildtoolchain itself, which merely calls 13 other scripts. Because buildtoolchain is broken into steps, the build process can be restarted in case of failure. tbdev1 (which is a 400MHz Celeron) requires more than an hour to completely run buildtoolchain.

buildtoolchain starts by executing the script called buildtoolchain-environment, which sets a series of environment variables. buildtoolchain continues by executing additional scripts that perform these steps:

  1. Checks for the required source files:

  2. buildtoolchain-step01-check
  3. Cleans up old builds:

  4. buildtoolchain-step02-clean
  5. Makes build directories:

  6. buildtoolchain-step03-makebuilddirectories
  7. Builds binutils:

  8. buildtoolchain-step04-binutils
  9. Sets up the kernel source and headers:

  10. buildtoolchain-step05-kernelsourceheaders
  11. Builds a cross-compiled version of gcc:

  12. buildtoolchain-step06-gcc
  13. Builds a cross-compiled version of glibc:

  14. buildtoolchain-step07-glibc
  15. Builds a cross-compiled version of gdb:

  16. buildtoolchain-step08-gdb
  17. Checks the version of gcc:

  18. buildtoolchain-step09-gccversion
  19. Checks the tool chain build by cross-compiling helloworld:

  20. buildtoolchain-step10-helloworld
  21. Rebuilds gcc:

  22. buildtoolchain-step11-rebuildgcc
  23. Rebuilds glibc:

  24. buildtoolchain-step12-rebuildglibc

The following text explains each script in greater detail.

Let's use buildtoolchain to build the GNU tool chain for the PowerPC. buildtoolchain version 0.8 compiles the following versions of binutils, gcc, glibc, and gdb for PowerPC:

BINUTILSVERSION=binutils-2.11.2
GCCVERSION=gcc-2.95.3
GLIBVERSION=glibc-2.2.3
GLIBCTHREADSVERSION=glibc-linuxthreads-2.2.3
KERNELVERSION=linux-2.4.7
GDBVERSION=gdb-5.0

Start by logging on to tbdev1 as root. Make a directory called /root/cross and change directory into it. Use wget to fetch buildtoolchain and tar to extract all the bash scripts. Finally, run buildtoolchain with powerpc as the command-line parameter. Here are the bash commands to get started:

root@tbdev1[526]: mkdir /root/cross
root@tbdev1[527]: cd /root/cross
root@tbdev1[528]: wget http://www.embeddedlinuxinterfacing.com/
chapters/03/buildtoolchain/buildtoolchain.tar.gz
root@tbdev1[529]: tar zxvf buildtoolchain.tar.gz
root@tbdev1[530]: ./buildtoolchain powerpc

The command buildtoolchain powerpc executes the buildtoolchain-environment script and the 12 other scripts listed in the steps above. The buildtoolchain script, shown in Listing 3.1, completely creates the cross-development environment for the PowerPC. Each script prints out information concerning the build process. The remainder of this chapter describes the buildtoolchain scripts and provides source code listings and relevant script output.

TIP

The buildtoolchain script generates more than 8MB of output. You might want to execute buildtoolchain in the background and redirect its output to a file. Then use tail –f to view your output file as it is being created.

Listing 3.1 The buildtoolchain Script

#!/bin/bash
# buildtoolchain v0.8 10/30/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
#
# This program is free software; you can redistribute it and/or modify it 
# under the terms of the GNU Library General Public License as published by 
# the Free Software Foundation; either version 2 of the License, or (at your 
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 
# License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software Foundation, 
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Files needed and source locations
# binutils      ftp://ftp.gnu.org/gnu/binutils/ 
# kernel       ftp://ftp.kernel.org/pub/linux/kernel
# gcc        ftp://ftp.gnu.org/pub/gnu/gcc/
# glibc       ftp://ftp.gnu.org/pub/gnu/glibc/
# glibc-linuxthreads ftp://ftp.gnu.org/pub/gnu/glibc/
# gdb        ftp://ftp.gnu.org/pub/gnu/gdb/
#
# ARM specific patches
# Toolchain ftp://ftp.armlinux.org/pub/toolchain
# Kernel  ftp://ftp.arm.linux.org.uk/pub/armlinux/source/kernel-patches/
# Kernel  ftp://ftp.netwinder.org/users/n/nico/
#
#
# references
# The GNU Toolchain for ARM targets HOWTO
#  http://www.armlinux.org/docs/toolchain/
# The Linux for PowerPC Embedded Systems HOWTO
#  http://penguinppc.org/usr/embedded/howto/PowerPC-Embedded-HOWTO.html
#
# Change Log
#
# v0.5 
#   a. added $SRCFILELOC to filenames in Step 1 
#   b. made helloworld.c do a little counting
#   c. now saving linux/.config in tmp then restoring in Step 5
#
# v0.6
#   a. changed clean to remove
#   b. fixed *PATCH being undefined and file check for it
#
# v0.7
#   a. split steps into files, so you can tinker in middle and not
#    have to start over from the beginning
#   b. added targetboard in step5, this keeps you from running make 
#    menuconfig
#   c. added KERNELPATCH3 for arm mediaengine needs 3 patches
#   d. kernel patches are now done in the linux directory with patch -p1
#
# v0.8
#   a. added wgets to step01 to get sources except for patches 
#    (arch dependent)
#   b. changed command line parameter ppc to powerpc

set -e

. ./buildtoolchain-environment $1

buildtoolchain-step01-check
buildtoolchain-step02-clean
buildtoolchain-step03-makebuilddirectories
buildtoolchain-step04-binutils
buildtoolchain-step05-kernelsourceheaders
buildtoolchain-step06-gcc
buildtoolchain-step07-glibc
buildtoolchain-step08-gdb
buildtoolchain-step09-gccversion
buildtoolchain-step10-helloworld
buildtoolchain-step11-rebuildgcc
buildtoolchain-step12-rebuildglibc

The buildtoolchain script is simple; it merely calls the buildtoolchain-environment script and the scripts for the 12-step build process.

The buildtoolchain-environment script, shown in Listing 3.2, either sets environment variables for PowerPC/ARM builds or removes a previous installation. If you want to use different versions of the GNU tools or the kernel, you can modify the buildtoolchain-environment script and then run buildtoolchain.

Listing 3.2 The buildtoolchain-environment Script

#!/bin/bash
# buildtoolchain-environment 10/30/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement


export SRCFILELOC=/root/cross
export BUILDLOC=/root/cross/builds
export PREFIX=/usr

case "$1" in
"powerpc" )
export ARCH=ppc
export TARGET=powerpc-linux
export TARGETBOARD=rpxcllf
#export TARGETBOARD=bseip
export BINUTILSVERSION=binutils-2.11.2
export GCCVERSION=gcc-2.95.3
export GCCPATCH=
export GLIBVERSION=glibc-2.2.3
export GLIBCTHREADSVERSION=glibc-linuxthreads-2.2.3
export KERNELVERSION=linux-2.4.7
export KERNELPATCH1=
export KERNELPATCH2=
export KERNELPATCH3=
export GDBVERSION=gdb-5.0
;;
"arm" )
export ARCH=arm
export TARGET=arm-linux
export TARGETBOARD=mediaengine
export BINUTILSVERSION=binutils-2.11.2
export GCCVERSION=gcc-2.95.3
export GCCPATCH=gcc-2.95.3-diff-010218.bz2
export GLIBVERSION=glibc-2.2.3
export GLIBCTHREADSVERSION=glibc-linuxthreads-2.2.3
export KERNELVERSION=linux-2.4.2
export KERNELPATCH1=patch-2.4.2-rmk1.gz
export KERNELPATCH2=diff-2.4.2-rmk1-np2.gz
export KERNELPATCH3=patch-2.4.2-rmk1-np2-bse.gz
export GDBVERSION=gdb-5.0
;;
"remove-arm" )
TARGET=arm-linux
echo Removing $TARGET files
rm -rf $BUILDLOC/$TARGET*
rm -rf $PREFIX/bin/$TARGET*
rm -rf $PREFIX/$TARGET
rm -rf $PREFIX/src/$TARGET
rm -rf $PREFIX/lib/gcc-lib/$TARGET
rm -rf /usr/man/man1/$TARGET
exit 0
;;
"remove-powerpc" )
TARGET=powerpc-linux
echo Removing $TARGET files
rm -rf $BUILDLOC/$TARGET*
rm -rf $PREFIX/bin/$TARGET*
rm -rf $PREFIX/$TARGET
rm -rf $PREFIX/src/$TARGET
rm -rf $PREFIX/lib/gcc-lib/$TARGET
rm -rf /usr/man/man1/$TARGET*
exit 0
;;
* )
  echo "Usage $0 arm|powerpc|remove-arm|remove-powerpc"
  exit 1
;;
esac

echo buildtoolchain environment setup complete
echo

export BUILDTOOLCHAINENV=1

The following sections describe the steps in the process of building buildtoolchain.

Step 1: Check for Required Source Files

Before you start building the GNU tool chain, you need the source code for binutils, gcc, glibc, glibc-linuxthreads, the kernel source, gdb, and any patches. You can download the source from the following locations or have buildtoolchain-step01-check do it for you:

Needed File

Locations

binutils

ftp://ftp.gnu.org/gnu/binutils

kernel

ftp://ftp.kernel.org/pub/linux/kernel

gcc

ftp://ftp.gnu.org/pub/gnu/gcc

glibc

ftp://ftp.gnu.org/pub/gnu/glibc

glibc-linuxthreads

ftp://ftp.gnu.org/pub/gnu/glibc

gdb

ftp://ftp.gnu.org/pub/gnu/gdb


You also need the ARM-specific patches if you are compiling for the ARM processor:

Patch

Location

Toolchain

ftp://ftp.armlinux.org/pub/toolchain

Kernel

ftp://ftp.arm.linux.org.uk/pub/armlinux/source/kernel-patches

Kernel

ftp://ftp.netwinder.org/users/n/nico


The buildtoolchain-step01-check script, shown in Listing 3.3, determines whether the required files exist. If any are missing, this script downloads them, by using wget.

Listing 3.3 The buildtoolchain-step01-check Script

#!/bin/bash
# buildtoolchain-step01-check v0.2 10/30/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement


if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

#
# Step 1 - Check for required src files
#
echo Step 1 - Check for required src files
if [ ! -f $SRCFILELOC/$BINUTILSVERSION.tar.gz ]
then
  echo Missing $BINUTILSVERSION.tar.gz
  wget ftp://ftp.gnu.org/gnu/binutils/$BINUTILSVERSION.tar.gz
fi

if [ ! -f $SRCFILELOC/$GCCVERSION.tar.gz ]
then
  echo Missing $GCCVERSION.tar.gz
  wget ftp://ftp.gnu.org/pub/gnu/gcc/$GCCVERSION.tar.gz
fi

if [ $GCCPATCH ]
then
  if [ ! -f $SRCFILELOC/$GCCPATCH ]
  then
    echo Missing $GCCPATCH
    exit 1
  fi
fi

if [ ! -f $SRCFILELOC/$GLIBVERSION.tar.gz ]
then
  echo Missing $GLIBVERSION.tar.gz
  wget ftp://ftp.gnu.org/pub/gnu/glibc/$GLIBVERSION.tar.gz
fi

if [ ! -f $SRCFILELOC/$GLIBCTHREADSVERSION.tar.gz ]
then
  echo Missing $GLIBCTHREADSVERSION.tar.gz
  wget ftp://ftp.gnu.org/pub/gnu/glibc/$GLIBCTHREADSVERSION.tar.gz
fi

if [ ! -f $SRCFILELOC/$KERNELVERSION.tar.gz ]
then
  echo Missing $KERNELVERSION.tar.gz
  wget ftp://ftp.kernel.org/pub/linux/kernel/v2.4/$KERNELVERSION.tar.gz
fi

if [ $KERNELPATCH1 ]
then
  if [ ! -f $SRCFILELOC/$KERNELPATCH1 ]
  then
    echo Missing $KERNELPATCH1
    exit 1
  fi
fi

if [ $KERNELPATCH2 ]
then
  if [ ! -f $SRCFILELOC/$KERNELPATCH2 ]
  then
    echo Missing $KERNELPATCH2
    exit 1
  fi
fi

if [ $KERNELPATCH3 ]
then
  if [ ! -f $SRCFILELOC/$KERNELPATCH3 ]
  then
    echo Missing $KERNELPATCH3
    exit 1
  fi
fi

if [ ! -f $SRCFILELOC/$GDBVERSION.tar.gz ]
then
  echo Missing $GDBVERSION.tar.gz
  wget ftp://ftp.gnu.org/pub/gnu/gdb/$GDBVERSION.tar.gz
fi

echo Step 1 - Complete
echo

Step 2: Clean Up Old Builds

The buildtoolchain-step02-clean script removes old versions of the build directories, previously created versions of the tool chain binaries, any cross-compiled libraries, temporary kernel source files, and any man pages (that is, online versions of manuals) for the cross-compiled tools. Listing 3.4 shows the buildtoolchain-step02-clean script. When buildtoolchain-step02-clean script completes, the workstation is clean and ready to compile the tool chain.

Listing 3.4 The buildtoolchain-step02-clean Script

#!/bin/bash
# buildtoolchain-step02-clean v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement


if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

# Step 2 - Clean Up
#
#clean up from before we start, this only cleans for TARGET
echo Step 2 - Clean Up
echo Removing previous $TARGET files
rm -rf $BUILDLOC/$TARGET*
rm -rf $PREFIX/bin/$TARGET*
rm -rf $PREFIX/$TARGET
rm -rf $PREFIX/lib/gcc-lib/$TARGET
rm -rf /usr/man/man1/$TARGET*

echo Step 2 - Complete
echo

Step 3: Make Build Directories

The buildtoolchain-step03-makebuilddirectories script creates build directories for binutils, gcc, glibc, and gdb (see Listing 3.5). These directories will contain the intermediary object files created during the compilation process. When buildtoolchain completes execution, you can remove these build directories.

Listing 3.5 The buildtoolchain-step03-makebuilddirectories Script

#!/bin/bash
# buildtoolchain-step03-makebuilddirectories v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

#
# Step 3 - Make Build Directories
#
echo Step 3 - Make Build Directories
echo Making build directories in $BUILDLOC

if [ ! -e $BUILDLOC ]
then
  mkdir $BUILDLOC
fi

mkdir $BUILDLOC/$TARGET-binutils
mkdir $BUILDLOC/$TARGET-gcc
mkdir $BUILDLOC/$TARGET-glibc
mkdir $BUILDLOC/$TARGET-gdb

echo Step 3 - Complete
echo

Step 4: Build binutils

The buildtoolchain-step04-binutils script builds the cross-compiled versions of the binary utilities (see Listing 3.6). These programs are used in the cross-compile process to create executables. The buildtoolchain-step04-binutils script performs the following:

  1. It extracts the binutils source from the tar file in the build directory.

  2. It runs the configuration from the build directory.

  3. It makes the binary utilities.

  4. It installs the binary utilities. These binutils are x86 executables that manipulate PowerPC binary files. They are installed in /usr/bin but have the prefix powerpc-linux.

  5. It cleans the build directory.

  6. It lists what was built and installed in the /usr/bin directory.

Listing 3.6 The buildtoolchain-step04-binutils Script

#!/bin/bash
# buildtoolchain-step04-binutils v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi


#
# Step 4 - Build binutils
#
echo Step 4 - Build binutils
echo Building $BINUTILSVERSION for $TARGET
cd $BUILDLOC
tar zxf $SRCFILELOC/$BINUTILSVERSION.tar.gz

cd $TARGET-binutils
../$BINUTILSVERSION/configure --target=$TARGET --prefix=$PREFIX -v
make
make install

cd $BUILDLOC
rm -rf $TARGET-binutils
rm -rf $BINUTILSVERSION

ls –1 $PREFIX/bin/$TARGET-*

echo Step 4 - Complete
echo

Here's buildtoolchain-step04-binutils output, which lists the powerpc-linux binutils:

/usr/bin/powerpc-linux-addr2line
/usr/bin/powerpc-linux-ar
/usr/bin/powerpc-linux-as
/usr/bin/powerpc-linux-c++filt
/usr/bin/powerpc-linux-gasp
/usr/bin/powerpc-linux-ld
/usr/bin/powerpc-linux-nm
/usr/bin/powerpc-linux-objcopy
/usr/bin/powerpc-linux-objdump
/usr/bin/powerpc-linux-ranlib
/usr/bin/powerpc-linux-readelf
/usr/bin/powerpc-linux-size
/usr/bin/powerpc-linux-strings
/usr/bin/powerpc-linux-strip
Step 4 - Complete

Step 5: Set Up the Kernel Source and Headers

Cross-compiling gcc and glibc requires kernel headers. The buildtoolchain-step05-kernelsourceheaders performs the following steps to prepare the kernel headers (see Listing 3.7):

  1. It extracts the kernel in the build directory.

  2. It applies any patches.

  3. It preserves the preexisting kernel configuration file, .config.

  4. It removes the preexisting kernel source directory.

  5. It moves the newly created kernel directory from the build directory to /usr/src.

  6. It copies the saved .config file to config.original in the new kernel source directory.

  7. It modifies the top-level kernel makefile, changing the ARCH and CROSS_COMPILE statements for the architecture that is being built.

  8. It configures the kernel source and headers, using a default target board configuration from the arch directory.

  9. It makes mrproper and dep.

  10. It creates kernel headers that include directories for the cross-compiling process.

Listing 3.7 The buildtoolchain-step05-kernelsourceheaders Script

#!/bin/bash
# buildtoolchain-step05-kernelsourceheaders v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

#
# Step 5 - Setup Kernel Source and Headers
#
echo Step 5 - Setup Kernel Source and Headers
echo Setting up $KERNELVERSION source and headers for $TARGET
cd $SRCFILELOC

echo Removing $SRCFILELOC/linux
rm -rf $SRCFILELOC/linux

echo Extracting $KERNELVERSION.tar.gz
tar zxf $KERNELVERSION.tar.gz

cd linux
if [ $KERNELPATCH1 ]
then
  echo Patching with $KERNELPATCH1
  gzip -cd ../$KERNELPATCH1 | patch -p1
fi
if [ $KERNELPATCH2 ]
then
  echo Patching with $KERNELPATCH2
  gzip -cd ../$KERNELPATCH2 | patch -p1
fi
if [ $KERNELPATCH3 ]
then
  echo Patching with $KERNELPATCH3
  gzip -cd ../$KERNELPATCH3 | patch -p1
fi

# save the existing kernel configuration if it exists
cd $SRCFILELOC
if [ -f $PREFIX/src/$TARGET/.config ]
then
  echo Saving $PREFIX/src/$TARGET/.config
  mv $PREFIX/src/$TARGET/.config /tmp/config.original
fi

# remove all the exist kernel source code for this target
echo Removing $PREFIX/src/$TARGET
rm -rf $PREFIX/src/$TARGET

echo Creating $PREFIX/src/$TARGET
mv linux $PREFIX/src/$TARGET

cd $PREFIX/src/$TARGET

if [ -f /tmp/config.original ]
then
 echo Saving $PREFIX/src/$TARGET/.config as $PREFIX/src/$TARGET/config.original
 mv /tmp/config.original $PREFIX/src/$TARGET/config.original
fi


make mrproper  

sed "s/ARCH :=.*$/ARCH := $ARCH/1" Makefile > /tmp/Makefile
cp /tmp/Makefile Makefile
sed "s/CROSS_COMPILE.*=.*$/CROSS_COMPILE = $TARGET-/1" Makefile > /tmp/Makefile
cp /tmp/Makefile Makefile

make mrproper

# use the target board defconfig if defined, 
# otherwise have the user go through make menuconfig
if [ $TARGETBOARD ]
then
  make $TARGETBOARD"_config"
  make oldconfig
else
  make menuconfig
fi

make dep

if [ ! -e $PREFIX/$TARGET ]
then
  mkdir $PREFIX/$TARGET
fi

mkdir $PREFIX/$TARGET/include
cp -dR $PREFIX/src/$TARGET/include/asm-$ARCH $PREFIX/$TARGET/include/asm
cp -dR $PREFIX/src/$TARGET/include/linux $PREFIX/$TARGET/include/linux
 
echo Step 5 - Complete
echo

Step 6: Build a Cross-Compiled Version of gcc

With the binary utilities cross-compiled and installed and the kernel headers properly configured and installed, it's time to build a cross-compiled version of gcc. Before we start, you need to know about a little problem that's about to happen. Generating a cross-compiled version of gcc requires that a cross-compiled version of glibc and headers be installed. glibc has not been created yet; that occurs in step 7. Generating a cross-compiled version of glibc requires a cross-compiled version of gcc. So gcc requires glibc, which requires gcc. This situation occurs on the first-time build of a cross-compiler. The organization of the gcc and glibc source code enables this interdependency situation to exist. The libchack7 solution permits the initial building of gcc without glibc headers. Having gcc enables successful cross- compiling of glibc in step 7. Later, steps 11 and 12 rebuild gcc and glibc without libchack. The buildtoolchain-step06-gcc script performs the following steps to build a cross-compiled version of gcc (see Listing 3.8):

  1. It extracts the gcc source in the build directory.

  2. It applies any patches.

  3. It applies the libchack solution.

  4. It makes a cross-compiled version of gcc.

  5. It installs the cross-compiled version of gcc.

  6. It lists what was built and installed in the /usr/bin directory.

Listing 3.8 The buildtoolchain-step06-gcc Script

#!/bin/bash
# buildtoolchain-step06-gcc v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

#
# Step 6 - Building a Cross-Compiler Version of gcc
#
echo Step 6 - Building a Cross-Compiler Version of gcc
echo Building $TARGET-$GCCVERSION
cd $BUILDLOC

tar zxf $SRCFILELOC/$GCCVERSION.tar.gz

if [ $GCCPATCH ]
then
  cd $GCCVERSION
  bzip2 -cd $SRCFILELOC/$GCCPATCH | patch -p0
  cd ../$TARGET-gcc
fi

cd $BUILDLOC/$TARGET-gcc

# this is called the libchack

if [ $ARCH = "arm" ]
then
  sed "s/TARGET_LIBGCC2_CFLAGS.*$/TARGET_LIBGCC2_CFLAGS = 
-fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h/1"
../$GCCVERSION/gcc/config/arm/t-linux > /tmp/libchack
  cp /tmp/libchack ../$GCCVERSION/gcc/config/arm/t-linux

  ../$GCCVERSION/configure --target=$TARGET \
                 --prefix=$PREFIX \
                 --with-headers=$PREFIX/src/$TARGET/include \
                 --enable-languages=c \
                 --disable-threads 
fi

if [ $ARCH = "ppc" ]
then
  sed "s/TARGET_LIBGCC2_CFLAGS.*$/TARGET_LIBGCC2_CFLAGS =
-fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h/1"
../$GCCVERSION/gcc/config/t-linux > /tmp/libchack
  cp /tmp/libchack ../$GCCVERSION/gcc/config/t-linux

  ../$GCCVERSION/configure --target=$TARGET \
                 --prefix=$PREFIX \
                 --with-headers=$PREFIX/src/$TARGET/include \
                 --enable-languages=c \
                 --disable-threads
fi

make
make install

ls -1 $PREFIX/bin/$TARGET-*

echo Step 6 - Complete
echo

Here's the listing output from the buildtoolchain-step06-gcc script; notice that /usr/bin/powerpc-linux-gcc now exists:

/usr/bin/powerpc-linux-addr2line
/usr/bin/powerpc-linux-ar
/usr/bin/powerpc-linux-as
/usr/bin/powerpc-linux-c++filt
/usr/bin/powerpc-linux-gasp
/usr/bin/powerpc-linux-gcc
/usr/bin/powerpc-linux-ld
/usr/bin/powerpc-linux-nm
/usr/bin/powerpc-linux-objcopy
/usr/bin/powerpc-linux-objdump
/usr/bin/powerpc-linux-protoize
/usr/bin/powerpc-linux-ranlib
/usr/bin/powerpc-linux-readelf
/usr/bin/powerpc-linux-size
/usr/bin/powerpc-linux-strings
/usr/bin/powerpc-linux-strip
/usr/bin/powerpc-linux-unprotoize
Step 6 - Complete

Step 7: Build a Cross-Compiled Version of glibc

The buildtoolchain-step07-glibc script performs the following steps to build glibc (see Listing 3.9):

  1. It extracts the glibc source in the build directory.

  2. It extracts glibc-threads in the build directory.

  3. It configures the build.

  4. It makes a cross-compiled version of glibc.

  5. It installs the cross-compiled version of glibc.

Listing 3.9 The buildtoolchain-step07-glibc Script

#!/bin/bash
# buildtoolchain-step07-glibc v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

# Step 7 - Build a Cross-Compiled Version of glibc
#
echo Step 7 - Build a Cross-Compiled Version of glibc
echo Building $GLIBVERSION for $ARCH
cd $BUILDLOC
tar zxf $SRCFILELOC/$GLIBVERSION.tar.gz
cd $GLIBVERSION
tar zxf $SRCFILELOC/$GLIBCTHREADSVERSION.tar.gz

cd ../$TARGET-glibc


if [ $ARCH = "arm" ]
then
CC=$TARGET-gcc ../$GLIBVERSION/configure $TARGET 
--build=i586-linux --prefix=$PREFIX/$TARGET --enable-add-ons 
fi

if [ $ARCH = "ppc" ]
then
# need to remove memset.S for 8xx processors
rm -rf $BUILDLOC/$GLIBVERSION/sysdeps/powerpc/memset.S

CC=$TARGET-gcc ../$GLIBVERSION/configure $TARGET 
--build=i586-linux --prefix=$PREFIX/$TARGET --enable-add-ons

fi

make
make install

echo Step 7 - Complete
echo

Step 8: Build a Cross-Compiled Version of gdb

The GNU debugger, gdb, is used to debug executables. If you're debugging PowerPC or ARM executables, you need a cross-compiled version of gdb. The buildtoolchain-step08-gdb script performs the following steps to build gdb (see Listing 3.10):

  1. It extracts the gdb source in the build directory.

  2. It configures the build.

  3. It makes a cross-compiled version of gdb.

  4. It installs the cross-compiled version of gdb.

  5. It lists what was built and installed in the /usr/bin directory.

Listing 3.10 The buildtoolchain-step08-gdb Script

#!/bin/bash
# buildtoolchain-step08-gdb v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

#
# Step 8 - Build Cross-Compiled Version of gdb
#
echo Step 8 - Build Cross-Compiled Version of gdb
echo building $GDBVERSION
cd $BUILDLOC
rm -rf $GDBVERSION
tar zxf $SRCFILELOC/$GDBVERSION.tar.gz

cd $TARGET-gdb
../$GDBVERSION/configure --target=$TARGET --prefix=$PREFIX -v
make
make install

ls -1 $PREFIX/bin/$TARGET-*

echo Step 8 - Complete
echo

Here's the listing output from the buildtoolchain-step08-gdb script; notice that /usr/bin/powerpc-linux-gdb now exists:

/usr/bin/powerpc-linux-addr2line
/usr/bin/powerpc-linux-ar
/usr/bin/powerpc-linux-as
/usr/bin/powerpc-linux-c++filt
/usr/bin/powerpc-linux-gasp
/usr/bin/powerpc-linux-gcc
/usr/bin/powerpc-linux-gdb
/usr/bin/powerpc-linux-ld
/usr/bin/powerpc-linux-nm
/usr/bin/powerpc-linux-objcopy
/usr/bin/powerpc-linux-objdump
/usr/bin/powerpc-linux-protoize
/usr/bin/powerpc-linux-ranlib
/usr/bin/powerpc-linux-readelf
/usr/bin/powerpc-linux-run
/usr/bin/powerpc-linux-size
/usr/bin/powerpc-linux-strings
/usr/bin/powerpc-linux-strip
/usr/bin/powerpc-linux-unprotoize
Step 8 - Complete

Step 9: Check the Version of gcc

The buildtoolchain-step09-gccversion script executes the new cross-compiler and outputs the version (see Listing 3.11).

Listing 3.11 The buildtoolchain-step09-gccversion Script

#!/bin/bash
# buildtoolchain-step09-gccversion v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
# See buildtoolchain script for General Public License statement
#

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

#
# Step 9 - gcc Version Check
echo Step 9 - gcc Version Check
echo -n "$TARGET-gcc version is "
$TARGET-gcc --version

echo Step 9 - Complete
echo

Here's the buildtoolchain-step09-gccversion script output:

Step 9 - gcc Version Check
powerpc-linux-gcc version is 2.95.3
Step 9 - Complete

Step 10: Check the Tool Chain Build

buildtoolchain-step10-helloworld creates a helloworld.c source code file and then cross-compiles it (see Listing 3.12). If the helloworld.c file successfully compiles, then gcc, glibc and its headers files were properly configured, compiled and installed. The script then calls the Linux file program that displays the architecture of the new helloworld executable. If helloworld.c doesn't successfully compile, then an error occurred in the buildtoolchain execution. You'll have to find the error in the buildtoolchain output and correct the situation.

Listing 3.12 The buildtoolchain-step10-helloworld Script

#!/bin/bash
# buildtoolchain-step10-helloworld v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

#
# Step 10 - Checking Tool Chain Build by Cross-Compiling Helloworld
#
echo Step 10 - Checking Tool Chain Build by Cross-Compiling Helloworld
echo creating helloworld.c

cd $BUILDLOC
rm -rf helloworld.*

cat > helloworld.c << ENDOFINPUT
#include <stdio.h>

int main(void)
{
  int i;

  for (i = 1; i < 10; i++)
  {
    printf("Hello world %d times!\n",i);
  }
}

ENDOFINPUT

$TARGET-gcc -g -o helloworld-$TARGET helloworld.c
file helloworld-$TARGET


echo Step 10 - Complete
echo

Here's actual Step 10 output.

Step 10 - Checking Tool Chain Build by Cross-Compiling Helloworld
creating helloworld.c
helloworld-powerpc-linux: ELF 32-bit MSB executable, PowerPC or cisco 4500,
version 1, dynamically linked (uses shared libs), not stripped 
Step 10 - Complete

The output ELF 32-bit MSB executable for PowerPC verifies a successful tool chain build.

Step 11: Rebuild gcc

Now that glibc and its header files exist, the libchack solution is no longer necessary. The buildtoolchain-step11-rebuildgcc script configures, makes, and installs gcc again without the libchack (see Listing 3.13).

Listing 3.13 The buildtoolchain-step11-rebuildgcc Script

#!/bin/bash
# buildtoolchain-step11-rebuildgcc v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

#
# Step 11 - rebuilding a Cross-Compiler Version of gcc
#
echo Step 11 - rebuilding the Cross-Compiler Version of gcc
echo Re-building $TARGET-$GCCVERSION
cd $BUILDLOC
rm -rf $GCCVERSION

tar zxf $SRCFILELOC/$GCCVERSION.tar.gz

if [ $GCCPATCH ]
then
   cd $GCCVERSION
   bzip2 -cd $SRCFILELOC/$GCCPATCH | patch -p0
   cd ../$TARGET-gcc
fi

cd $BUILDLOC/$TARGET-gcc

if [ $ARCH = "arm" ]
then
    ../$GCCVERSION/configure --target=$TARGET \
                 --prefix=$PREFIX \
                 --with-headers=$PREFIX/src/$TARGET/include \
                 --enable-languages=c
fi

if [ $ARCH = "ppc" ]
then

"CFLAGS=-msoft-float" ../$GCCVERSION/configure --target=$TARGET \
             --prefix=$PREFIX \
             --with-headers=$PREFIX/src/$TARGET/include \
             --enable-languages=c \
             --without-fp
fi

make
make install

ls -l $PREFIX/bin/$TARGET-*

echo Step 11 - Complete
echo

Step 12: Rebuild glibc

With gcc properly rebuilt, the buildtoolchain-step12-rebuildglibc script recompiles glibc for the final time. Step 12 differs significantly from step 7. The buildtoolchain-step12-rebuildglibc script, as shown in Listing 3.14, configures the prefix command-line option differently. Look back at buildtoolchain-step07-glibc's configuration line. If you do a little environment variable substitution for this PowerPC example, the buildtoolchain-step07-glibc script configuration prefix command-line option expands to this:

--prefix=/usr/powerpc-linux

Listing 3.14 The buildtoolchain-step12-rebuildglibc Script

#!/bin/bash
# buildtoolchain-step12-rebuildglibc v0.1 8/16/01
# http://www.embeddedlinuxinterfacing.com
#
# The original location of this script is
# http://www.embeddedlinuxinterfacing.com/chapters/03/buildtoolchain
#
# Copyright (C) 2001 by Craig Hollabaugh
# See buildtoolchain script for General Public License statement

if [ ! $BUILDTOOLCHAINENV ]
then
. ./buildtoolchain-environment $1
fi

# Step 12 - Build a Cross-Compiled Version of glibc
#
echo Step 12 - Build a Cross-Compiled Version of glibc
echo Building $GLIBVERSION for $ARCH

cd $BUILDLOC
cd $GLIBVERSION

cd ../$TARGET-glibc

if [ $ARCH = "arm" ]
then

CC=$TARGET-gcc ../$GLIBVERSION/configure $TARGET --build=i586-linux \
                         --prefix=/ \
                         --enable-add-ons 
fi

if [ $ARCH = "ppc" ]
then

CC=$TARGET-gcc CFLAGS="-msoft-float -D_SOFT_FLOAT -mcpu=860" \
../$GLIBVERSION/configure $TARGET --build=i586-linux \
                 --prefix=/ \
                 --enable-add-ons \
                 --without-fp
fi

#don't do a make install here, the prefix is /, 
#installing will trash this computer's /lib directory

make

mkdir $BUILDLOC/$TARGET-lib 
make install_root=$BUILDLOC/$TARGET-lib install


echo Step 12 - Complete
echo

The prefix option prefixes a path to /lib; in this case, buildtoolchain-step07-glibc compiles and installs glibc and other libraries, using /usr/powerpc-linux/lib instead of just /lib. The path /usr/powerpc-linux/lib is actually hard-coded into step 7's PowerPC version of glibc and other libraries. The buildtoolchain-step07-glibc script configures this prefix so that the glibc installation script doesn't overwrite the x86 glibc library on tbdev1. Overwriting the x86 glibc with a PowerPC version would cause substantial problems for tbdev1.

Think about running programs on the target PowerPC board, the RPX-CLLF. The library loader, ld.so, expects glibc and other common libraries to exist in the /lib directory. Using the cross-compiled version of glibc from step 7 on the target system with the hard-coded path /usr/powerpc-linux/lib in glibc would cause havoc. The library loader would have problems finding various libraries. The buildtoolchain-step12-rebuildglibc script doesn't merely recompile glibc: It configures with the prefix command-line option to /, it makes glibc, and then it installs glibc in a special build library directory. In this PowerPC example, when buildtoolchain-step12-rebuildglibc completes, /root/cross/builds/powerpc-lib contains glibc libraries for use on the PowerPC target system.

In summary, the buildtoolchain-step07-glibc script generates cross-compiled glibc libraries for use on the host workstation tbdev1 in the /usr/powerpc-linux/lib directory. Using a prefix reduces the chance of overwriting the x86 glibc. Step 7 cross-compiled glibc library files can't be used on the target system; the prefix /usr/powerpc-linux is hard-coded in the library files themselves. The buildtoolchain-step12-rebuildglibc script generates an additional set of libraries with the prefix / for use on the target system.

At this point, the PowerPC cross-compiler, powerpc-linux-gcc, exists in the /usr/bin directory. The PowerPC cross-compiled libraries are located in /usr/powerpc-linux/lib. The buildtoolchain script, using powerpc-linux-gcc and the PowerPC glibc libraries, compiles /root/cross/builds/helloworld.c using the following command:

powerpc-linux-gcc -g -o helloworld-powerpc-linux helloworld.c

The PowerPC executable helloworld-powerpc-linux exists in /root/cross/builds. If you execute helloworld-powerpc-linux on your x86 development station, you should get the following error because helloworld-powerpc-linux is not an x86 executable:

root@tbdev1[530]: cd /root/cross/builds
root@tbdev1[531]: ./helloworld-powerpc-linux
bash: ./helloworld-powerpc-linux: cannot execute binary file 

In Chapter 5, you'll transfer this helloworld-powerpc-linux executable to the Embedded Planet RPX-CLLF target board. You'll also execute it and remotely debug it.

Congratulations on building the GNU tool chain for cross-compiling! If you need to build the tool chain for the ARM processor, run buildtoolchain arm, sit back, and watch tbdev1 configure, compile, and install an ARM version of the G

  • + Share This
  • 🔖 Save To Your Account