Crostool-NG 1.18.0 on Fedora 18

I have already posted descriptions about how to setup the crosstool-ng version 1.16.0 for Raspberry Pi on Fedora in hese posts: cross-compile, debug. Since the 1.18.0 version of crostool-ng has been released, I will create a short summary about what needs to be done to set it up for Raspberry Pi. Please note that the rest of the steps are identical with those that I described in the former posts, therefore I only the differences will be described:

Prerequisites
Please make sure that the required dependecnies are installed.

sudo yum install bison flex gperf libtool texinfo gcc gcc-c++ gmp-devel expat expat-devel python python-devel kernel-devel patch

Configuration
The main difference to the former version that it seems the strace build problem and the cannot find GMP version 4.1.3 or higher problem has disappeared in 1.18.0, therfore the config for RPi would look like the following:

  • Paths and misc options
    • Enable “Try features marked as EXPERIMENTAL”
    • If you don’t like the default toolset installation directory, then set the “Prefix directory” from “${HOME}/x-tools/${CT_TARGET}” to “${XTOOLS_HOME}/crosstool-ng-1.18.0-tools/${CT_TARGET}”. The ${XTOOLS_HOME} needs to be defined in your .bash_profile in advance
  • Target options
    • Be sure that the “Target Architecture” is set to “arm”
    • Be sure that “Little Endian” and “32bit” are selected
    • Be sure that “Floating point” is set to “hardware (FPU)”
    • Be sure that “Use EABI” is selected
  • Operating system
    • Set “Target OS” to Linux
  • C compiler
    • Enable “Show Linaro versions”
    • The “gcc version” set it to latest version: “linaro-4.7-2013.01”
    • Enable “C++” in order to have C++ compiler
    • Disable “Link libstdc++ statically into gcc binary” otherwise you will get the the following error “[ERROR] Static linking impossible on the host system ‘x86_64-build_unknown-linux-gnu'”
  • Debug facilities
    • Enable “ltrace”
    • Enable “gdb”
    • Enable “duma”
    • Enable “dmalloc”
    • Enable “strace”

Note: It is not recommended to build the crosstool-ng as root and by default crosstool-ng will not allow to execute the build as root

Advertisements

Fedora 18 hostname resolution problems

After you have installed Fedora 18, you probably noticed that it starts up with the default localhost.localdomain hostname. In the former versions of Fedora the HOSTNAME variable that determined the hostname of your machine was stored in /etc/sysconfig/network file, but starting from from Fedora 18 it is not there anymore. Furtunately there is a command that can be used to update your hostname:

$ sudo hostnamectl set-hostname DESIRED_HOST_NAME


The hostname command can be used to check whether the hostname was successfully updated or not on your machine. However you might notice that pinging or nslookup your own hostname will not work and you gey and error for the hostname -f.

#The hostname will return your current hostname
$ hostname
DESIRED_HOST_NAME

#However it is not able to reslove it (nor does the ping or nsloookup)
$hostname -f
hostname: Name or service not known


The reason behind of this is that you probably don’t have a DNS server (or it is misconfigured). The easy solution to fix this without having a DNS server is to edit the nsswitch.conf file and add myhostname for host resolution.

Please be sure that the nss-myhostname is installed on your machine.

$ sudo yum install nss-myhostname


Edit the /etc/nsswitch.conf file and add myhostname value to hosts section.

$ sudo vi /etc/nsswitch.conf

#Note: just add the myhostname value as you see below and not your real host name!!!
hosts:      files dns myhostname


After these changes you shall be able to resolve your own hostname with hostname -f or even with nslookup.

You might think that editing of /etc/hosts file is also a good workaround, but please consider that if your machine is getting its IP address dynamically then you always need to update the /etc/hosts file, but with the above solution your hostname will be resolved always correctly even in case of variable IP addresses.

Debug cross-compiled executable on Raspberry Pi from Eclipse

If you were able to launch a cross compiled executable on the target machine (Raspberry Pi) as described in my former post, then you probably would like to debug it remotely as well.

Update crosstool-ng
I have already described how to setup crosstool-ng for cross-compiling purposes, but in order to enable cross-debug support a few other steps needs to be done. First of all you need to install some additional packages from Fedora repository.

su - #change to root
#Install dependencies for crostool-ng debug support
yum install expat expat-devel python python-devel

If these packages are not installed then probably you will get the following error message during the build of crosstool-ng tools.

[INFO ]  Installing cross-gdb
[ERROR]    configure: error: expat is missing or unusable
[ERROR]    make[2]: *** [configure-gdb] Error 1

After the dependencies are successfully installed just need to follow the same steps what are described in the Configure the toolchain chapter and additional to those steps select the required debug options in the menuconfig of ct-ng.

  • Debug facilities
    • Enable “ltrace”
    • Enable “gdb”
    • Enable “duma”
    • Enable “dmalloc”
    • Keep “strace” on disable since it does not seem to build with crosstool-ng 1.16.0

Save the changes, exit from the menuconfig and build the crosstool-ng tools as usual…

Debug Configuration in Eclipse
I suppose you have already setup Run Configuration in Eclipse and successfully executed your cross-compiled binary on the target machine as described here. If not then it is the right time to do it. After it is done, just open Debug Configuration for your project and select the Debugger tab.

GDB debugger

Fill the GDB debugger field with the browse button. The cross-debugger shall be available under your crostool-ng tools:

/opt/crosstool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gdb

Click on the Debug button and Eclipse is going to copy your cross-compiled binaries to remote machine and start to debug it remotely.

Eclipse Remote Debug

Launch cross-compiled executable on Raspberry Pi from Eclipse

If you have cross compiled your source files as described in the former post, then you probably want to execute your cross compiled binaries on the target machine. The simplest and most time consuming way is just to manually copy over the binaries to Raspberry Pi. Luckily you can save some time, since the Eclipse has a built-in support to copy and execute the binaries remotely. In order to do this just follow the description below.

Run Configuration
Open the “Run Configuration” menu and create a new “C/C++ Remote Application”. As you can see the “Connection” dropdown will be empty by default, and we need to setup a connection to Raspberry Pi.

Default Run Configuration with empty Connection

New Linux Connection
To create a connection click on the “New” button next to the connection dropdown box and select the Linux Connection and configure the connection as shown on the following screenshots.

Configure Raspberry Pi host name (rpi already present in /etc/hosts)

Files Menu

Processes Menu

Shells Menu

SSH Terminals Menu



Remote File setup
You need to setup the location of remote file by clicking on the “Browse” button. Please note that the full qualified path can be browsed, but you need to type the binary executable name as well. In other words the “Remote Absolute File Path for C/C++ Application” field shall contain a path like /home/pi/Workspace/helloworld where the helloworld is the name of the binary executable. It is also important that the directories must be present on the target system and the user what you are using to connect must have sufficient rights to copy the file to that directory.

Properly configured Run Configuration dialog



Run the executable remotely
When you click on the “Run” button, then Eclipse will transfer the executable to the target machine, launch it and display the standard error and output on the Eclipse console:

Console out in Eclipse

Note: As an alternative you can share the data with sshfs or nfs between your workstation and target board.

Setup Eclipse for cross-compiling

After you have successfully created your cross-compiling toolchain with crosstool-ng as described in Cross compiling kernel for Raspberry Pi on Fedora 17 you probably want to use the tools not only form command line but also from a rich IDE like Eclipse.

Install Eclipse IDE for C/C++ Developers
Navigate to Eclipse download page and download the Eclipse IDE for C/C++ Developers and extract it. This post is based on the Juno version of Eclipse for 64bit Linux platforms, but probably with slight modification you can apply it for later versions as well.

Optional step: After the Eclipse has been downloaded and extracted you can create a desktop icon for it if you wish:

gnome-desktop-item-edit ~/Desktop/eclipse_cpp.desktop --create-new

Create a C or C++ Project
Start Eclipse and create a new C Project from New menu (description shall work also for C++). On the first dialogue screen, please select the “Hello World ANSI C Project” with “Cross GCC” Toolchains and press the Next button, the settings on the following dialogues can remain as default. On the last dialogue called “Cross GCC Command”, please select the Cross compiler prefix and also the Toolchain Path as shown in the screenshot below.

Verifying the projects
After you have successfully executed the above steps your projects can be compiled on your desktop and executed on the target machine. Eclipse will load all required libraries and tools from the above defined Toolchain path. You can double-check your Eclipse project as shown in the screenshot:

Eclipse with with multiple cross compile projects

Cross compiling kernel for Raspberry Pi on Fedora 17 – Part 2

There are multiple ways to install a cross compiler on Fedora 17. The simplest way was described in Part 1. The problem is that the available cross-build binary utilities for ARM (sudo yum info gcc-arm-linux-gnu) does not support cross-building of user space programs. A slightly more complicated option is to use build frameworks like OpenEmbedded or crosstool-ng.

Install crosstool-ng
By the time of writing this post the latest stable version of crosstool-ng is 1.16.0. Installation of a stable version is quite straightforward and it is very clearly described in “Download and usage section” of crosstool-ng.org. For your reference I copy it here with slight modifications.

su - #change to root
#Install dependencies
yum install bison flex gperf libtool texinfo gcc gcc-c++ gmp-devel
#Download and install crosstool-ng
cd /opt
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.16.0.tar.bz2
bunzip2 crosstool-ng-1.16.0.tar.bz2
tar xf crosstool-ng-1.16.0.tar
cd crosstool-ng-1.16.0
#The --prefix parameter shall be set to the installation directory 
./configure --prefix=/opt/crosstool-ng-1.16.0
make
make install
#For auto-completion, do not forget to install 'ct-ng.comp' into your bash completion directory
cp ct-ng.comp /etc/bash_completion.d/    


The bash_completion will automatically pick up the auto completion parameters after restart. You can read more about autocopletion feature of bash here and here.

Edit the .bash_profile of root user and also your user and add the /opt/crosstool-ng-1.16.0/bin to PATH in order make the crostool-ng comands available from shell.

PATH=$PATH:/opt/crosstool-ng-1.16.0/bin

Configure the toolchain
The crosstool-ng has been installed and ready to build a toolchain for the Raspberry Pi (or other environment)

su -
mkdir /opt/crosstool-ng-1.16.0-config 
cd /opt/crosstool-ng-1.16.0-config
ct-ng menuconfig


The last command will pop up a kernel-like menuconfig configuration interface where the following changes needs to be made.

  • Paths and misc options
    • Enable “Try features marked as EXPERIMENTAL”
    • Set the “Prefix directory” from “${HOME}/x-tools/${CT_TARGET}” to “/opt/crosstool-ng-1.16.0-tools/${CT_TARGET}”, please note that the /opt/crosstool-ng-1.16.0-config directory will contain the configuration, downloaded tools, temporary build files and the /opt/crosstool-ng-1.16.0-tools will contain your actual toolchain.
  • Toolchain options
    • Tuple’s version string is set to “unknown” by default, if would like to change it please see the “Note” in the bottom of this post
  • Target options
    • Be sure that the “Target Architecture” is set to “arm”
    • Be sure that “Little Endian” and “32bit” are selected
    • Be sure that “Floating point” is set to “hardware (FPU)”
    • Be sure that “Use EABI” is selected
  • Operating system
    • Set “Target OS” to Linux
  • C compiler
    • Enable “Show Linaro versions”
    • The “gcc version” should automatically change to latest linaro version, if not then set it manually. Currently the latest is “linaro-4.7-2012.07”
    • Enable “C++” in order to have C++ compiler
    • Disable “Link libstdc++ statically into gcc binary” otherwise you will get the the following error “[ERROR] Static linking impossible on the host system ‘x86_64-build_unknown-linux-gnu'”
    • Disable “GRAPHITE loop optimisations” otherwise you will get the the following error “Installing PPL for host [ERROR] configure: error: Cannot find GMP version 4.1.3 or higher.”

Exit from the menuconfig save the changes and build it still as root

ct-ng build


The build takes a while, but after it is done the toolchain should appear in the /opt/crosstool-ng-1.16.0-tools directory.

Switch from root to your regular user and append the /opt/crostool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin to PATH variable in .bash_profile to make the cross compiler binaries available in shell

PATH=$PATH:/opt/crosstool-ng-1.16.0/bin:/opt/crosstool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin

Now you have a full featured cross-compile environment and you can build user space programs or you can compile kernel as described in Part 1. Of course in the CROSS_COMPILE parameter you need to specify the /opt/crosstool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- instead of /usr/bin/arm-linux-gnu-. For example:

make ARCH=arm CROSS_COMPILE=/opt/crosstool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- oldconfig

After you have executed every kernel compilation step described in the Part 1 you should see

pi@raspberrypi ~ $ uname -a
Linux raspberrypi 3.2.27-crosstool-ng #1 PREEMPT Tue Oct 2 20:28:03 CEST 2012 armv6l GNU/Linux

To test the cross-building capability of user space programs just creat a little hello world as hello.c

#include <stdio.h>

int main () {
  printf("Hello Cross Compiled Pi\n");
  return 0;
}

Compile it and check the result of compilation with file command

~ $ arm-unknown-linux-gnueabi-gcc -o arm-hello hello.c
~ $ file arm-hello
arm-hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.5.0, not stripped


After transfering it to Raspberry pi with scp

pi@raspberrypi ~ $ ./arm-hello
Hello Cross Compiled Pi

Note: The “arm-unknown-linux-gnueabi” name is crated based on form “arch-vendor-kernel-system”. You can set the vendor to whatever you think fits better. For that you can navigate to “Toolchain options” -> “Tuple’s vendor string” and change it from “unknown” to e.g. “rpi” and build the whole tool-chain as described above, after this modification your tools will be named like “arm-rpi-linux-gnueabi”.

Cross compiling kernel for Raspberry Pi on Fedora 17 – Part 1

The Raspberry Pi is very limited in CPU and memory and doing computation heavy tasks like compiling the entire kernel on it would take a lot of time. In order to make this process faster a cross compiler is required.
There are multiple ways to install a cross compiler on your Fedora 17 powered development workstation, one of the simplest is just to install the gcc-arm-linux-gnu from the repository using the yum package manager.

yum -y install gcc-arm-linux-gnu
arm-linux-gnu-gcc --version
arm-linux-gnu-gcc (GCC) 4.7.1 20120606 (Red Hat 4.7.1-0.1.20120606)

Get kernel source code
Kernel sources can be obtained from Raspberry PI git repository. If you like experimenting then you can download (or clone with appropriate git commands) the master version of kernel which contains the latest codebase. If you are a bit less adventurous then you can download an older version of kernel from branch section that are considered more stable.

mkdir ~/raspberrypi   
cd ~/raspberrypi
wget -O raspberrypi-linux-3.2.27.tar.gz https://github.com/raspberrypi/linux/tarball/rpi-3.2.27
tar xzf raspberrypi-linux-3.2.27.tar.gz
mv raspberrypi-linux-965b922 kernel-3.2.27

Configure the kernel
Setting up a proper kernel configuration file from scratch is a very challenging task, therefore it is worth to download current config file (.config) from your current Raspberry Pi and us it as a base for kernel compilation. In order to do this execute the following command on the Raspberry Pi:

zcat /proc/config.gz  > /tmp/.config

Copy the .config file to your development workstation with scp.

scp pi@rpi:/tmp/.config ~/raspberrypi/kernel-3.2.27

If you prefer to use a default config instead of the above described one then you can pick one from the available configs in the kernel source tree. The Raspberry Pi configs are prefixed with “bcmrpi_”.

cd ~/raspberrypi/kernel-3.2.27
cp arch/arm/configs/bcmrpi_defconfig .config

It is usually a good idea to execute oldconfig before the menuconfig since the oldconfig will prompt only the newly introduced kernel configuration options and if you execute the menuconfig then maybe some important newly introduced kernel options will remain unnoticed.

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- oldconfig
  HOSTCC  scripts/basic/fixdep
  #For the sake of clarity rest of the lines are removed...
*
* CPU Frequency scaling
*
CPU Frequency scaling (CPU_FREQ) [N/y/?] (NEW) 

To have the nice menu based kernel configuse the menuconfig:

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- menuconfig

In the “General Setup” menu of the Kernel Configuration (menuconfig) you can set up a custom version string that will be appended to kernel version. Change the “Local version – append to kernel relase” to “-tutorial”. In older kernels where this menu item does not exist the following command will have the same effect

sed -i 's/EXTRAVERSION =.*/EXTRAVERSION = Tutorial/' Makefile

Compile kernel
To start compiling and create a the architecture specific kernel image:

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu-
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- modules

Transfer kernel to Raspberry Pi
The transfer is described on RPi_Kernel_Compilation site. Make sure that the sshfs is installed on the Raspberry (you can use also NFS if you wish) and the firewall on your workstation allows the connection to it. For the sake of clarity I copy the code here

sudo bash #Execute everything as root on Raspberry Pi
apt-get install sshfs
cd /mnt
mkdir raspberrypi
sshfs user@host:/home/user/raspberrypi raspberrypi
cd raspberrypi/kernel-3.2.27
make modules_install
cp arch/arm/boot/Image /boot/kernel.img

After reboot you will see that the newly complied (3.2.27-tutorial) kernel is running

pi@raspberrypi ~ $ uname -a
Linux raspberrypi 3.2.27-tutorial #1 PREEMPT Mon Sep 24 22:01:27 CEST 2012 armv6l GNU/Linux

There is a problem with gcc-arm-linux-gnu utilities. If you check the description of the package (sudo yum info gcc-arm-linux-gnu) you will see that it does not support cross-building of user space programs. If you would like to have a cross compiler that can be used for compiling user space code then build frameworks like OpenEmbedded or crosstool-ng might be the right tools for you. In the Part 2 I will show how to set up a full featured cross-compile environment on Fedora 17.