Building tbdev1, the Embedded Linux Development WorkstationThe 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:
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 StartedIn 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:
To start, you need to download three floppy image files from the Debian Web site (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 the 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 SystemThe 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 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 tbdev1In 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:
Step 2: Partition the Hard DiskIn 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.
Step 3: Configure the Keyboard and Activate the PartitionsIn 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:
Step 4: Install the Operating System Kernel and ModulesNow 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:
Step 5: Configure the NetworkNow 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:
Step 6: Configure the Base SystemThe 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:
Step 7: Make Linux Bootable Directly from the Hard DiskWith 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:
Step 8: Set Passwords, Accounts, and PPPAfter rebooting, the installation process continues: You configure passwords, accounts, and point-to-point protocol options. To do so, follow these steps:
Step 9: Configure aptAll 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:
Step 10: Have Fun!The potato installation is now complete. Follow these steps:
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 ApplicationsThe 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 gcc powerpc-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-CompilingA 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:
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 # 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 # 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 FilesBefore 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:
You also need the ARM-specific patches if you are compiling for the ARM processor:
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 # 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 BuildsThe 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 # 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 DirectoriesThe 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 # 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 binutilsThe 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:
Listing 3.6 The buildtoolchain-step04-binutils Script#!/bin/bash # buildtoolchain-step04-binutils v0.1 8/16/01 # 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 http://$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 HeadersCross-compiling gcc and glibc requires kernel headers. The buildtoolchain-step05-kernelsourceheaders performs the following steps to prepare the kernel headers (see Listing 3.7):
Listing 3.7 The buildtoolchain-step05-kernelsourceheaders Script#!/bin/bash # buildtoolchain-step05-kernelsourceheaders v0.1 8/16/01 # 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 http://$KERNELPATCH1 | patch -p1 fi if [ $KERNELPATCH2 ] then echo Patching with $KERNELPATCH2 gzip -cd http://$KERNELPATCH2 | patch -p1 fi if [ $KERNELPATCH3 ] then echo Patching with $KERNELPATCH3 gzip -cd http://$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 gccWith 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):
Listing 3.8 The buildtoolchain-step06-gcc Script[View full width] #!/bin/bash # buildtoolchain-step06-gcc v0.1 8/16/01 # 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 http://$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" http://$GCCVERSION/gcc/config/arm/t-linux > /tmp/libchack cp /tmp/libchack http://$GCCVERSION/gcc/config/arm/t-linux http://$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" http://$GCCVERSION/gcc/config/t-linux > /tmp/libchack cp /tmp/libchack http://$GCCVERSION/gcc/config/t-linux http://$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 glibcThe buildtoolchain-step07-glibc script performs the following steps to build glibc (see Listing 3.9):
Listing 3.9 The buildtoolchain-step07-glibc Script[View full width] #!/bin/bash # buildtoolchain-step07-glibc v0.1 8/16/01 # 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 http://$TARGET-glibc if [ $ARCH = "arm" ] then CC=$TARGET-gcc http://$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 http://$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 gdbThe 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):
Listing 3.10 The buildtoolchain-step08-gdb Script#!/bin/bash # buildtoolchain-step08-gdb v0.1 8/16/01 # 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 http://$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 gccThe 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 # 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 Buildbuildtoolchain-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 # 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 gccNow 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 # 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 http://$TARGET-gcc fi cd $BUILDLOC/$TARGET-gcc if [ $ARCH = "arm" ] then http://$GCCVERSION/configure --target=$TARGET \ --prefix=$PREFIX \ --with-headers=$PREFIX/src/$TARGET/include \ --enable-languages=c fi if [ $ARCH = "ppc" ] then "CFLAGS=-msoft-float" http://$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 glibcWith 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 # 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 http://$TARGET-glibc if [ $ARCH = "arm" ] then CC=$TARGET-gcc http://$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" \ http://$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 GNU tool chain. |
Top |