Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
Tool-chain
The GNU/Linux kernel is so-called because the Linux kernel depends upon the GNU compiler collection
(gcc) and binary utilities (binutils) to build the executable vmlinux and it's supporting kernel modules (.ko
files). Without the comprehensive set of tools provided by gcc and binutils the Linux kernel cannot be built
(there are various projects aimed at substituting them but all serious kernel developers I know will only use the
GNU tools).
When building GNU/Linux on an x86-based host for the same x86-based target the regular x86 gcc and
binutils are sufficient. However, when the target is a different architecture as in this case (ARM) a version of
the tool-chain capable of emitting ARM-compatible executable code is required.
Many GNU/Linux distributions do not pre-package the full set of multi-arch tools required to successfully
cross-build (e.g. the Debian/Ubuntu binutils-multiarch package is missing gas, the GNU assembler). Building
the tool-chain can be quite a tortuous and time-consuming experience so the pragmatic solution is to install
pre-built packages.
Code Sourcery is a company that is licensed and supported by ARM to maintain the GNU ARM tools. They
provide several subscription-based pre-built packages for developers (Sourcery G++) that contain a multitude
of additional time-saving tools, but they also provide a free-of-cost pre-packaged IA32 set of tools: Sourcery
G++ Lite (Note that at this time Code Sourcery do not provide pre-built IA64 packages).
There are three package options provided by Code Sourcery: a GUI-based self-extracting installer, a
compressed archive (known as a tar-ball), and the source-code. The GUI (Graphical User Interface) installer
is bundled with a Java engine for running the installer and runs a series of 'wizard' dialogs before installing
and configuring the package.
I prefer using the tar-ball installation since I can be sure where tools are and control what environment files
are changed. Also, the tar-ball can be installed from a text terminal session whereas the GUI cannot.
1 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
2 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
3 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
Now arm-gcc-switch can be used to easily change all the symbolic links to tools in /usr/local/bin/,
for example to check the current default version look for the asterisk (*):
$ arm-gcc-switch
arm-gcc-switch version 1.0
Copyright 2010 TJ <linux@tjworld.net>
Licensed on the terms of the GNU GPL version 3
Usage: arm-gcc-switch [-f] <version>
-f
force removal of existing executables in common bin/ directory
Versions available (default*): 4.4.1 4.5.1*
To change the version:
$ arm-gcc-switch 4.4.1
arm-gcc-switch version 1.0
Copyright 2010 TJ <linux@tjworld.net>
Licensed on the terms of the GNU GPL version 3
Replacing existing default version 4.5.1
[sudo] password for tj:
Default version now 4.4.1
Done
Building Linux
Now the tool-chain is installed a build test is possible. There are so many sources for, and methods of delivery
of, the GNU/Linux kernel - it could be from the main-line kernel repository, a distribution, a device
manufacturer or a community special-interest project and it could be fetched as a tar-ball or using git, the
distributed version control system used by the Linux kernel developers.
Because I originally wrote this guide to help amateur hackers working on the HTC Vision I'll use that in the
example here.
mkdir sourcecode
cd sourcecode
wget http://member.america.htc.com/download/RomCode/Source_and_Binaries/vision-2.6.32-g8
tar -xzf vision-2.6.32-g814e0a1.tar.gz
If you wanted to get the Linux main-line, and have the git package installed (sudo apt-get install
git-core on Debian and Ubuntu), you could do:
mkdir sourcecode
cd sourcecode
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
4 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
Power-users Tips
Before showing how to cross-compile I want to recommend a couple of options for Make and tips that will
significantly improve a hack-build-test cycle.
Concurrent Builds
The first one is concurrent builds (-j) - that is, more than one file being built at the same time. If the
development PC has more than one CPU or core (dual core is extremely common and quad-cores are
widespread too) then it makes sense to reduce the build time by allowing Make to run multiple tasks
concurrently. On a dual core CPU a setting of "-j2" would fully utilise the system. On a quad-core a setting of
"-j4" might be more appropriate. If you wish to do something else on the PC whilst make is running then
leaving one core unused (-j3) by Make will allow the foreground applications to get sufficient processor
resources to not feel sluggish.
Out-of-Tree builds
The second is out-of-tree builds. Usually, when a compiler converts source code into object code it writes the
files it creates into the same directories as the source code file it is processing. For a complex project like
Linux with hundreds of sub-directories and thousands of files, this can make quite a mess, especially when
these files are being written into working directories of the git version control system since the object files which are not wanted in the source package - will complicate and confuse several key git commands. The
solution is to have all the intermediate and final object code files written to another directory that is out-of-tree
- in other words, it is a directory out-side of the git working directory. First, create a directory for the builds.
Convention dictates we create a new directory builds/ in the parent directory of the git working directory. In
other words we want:
sourcecode/
sourcecode/vision-2.6.32-g814e0a1/
sourcecode/builds/
In the builds directory we want one sub-directory for each project we're building, so to create the sub-directory
for the HTC Vision project:
cd sourcecode
mkdir -p builds/vision-2.6.32-g814e0a1
Now, when building the project using Make we pass it the path to this directory with the Make output option
"O=". The path is usually specified as relative to the project directory, so something like this:
5 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
export MAKE_VISION='-j2 O=../builds/vision-2.6.32-g814e0a1 CROSS_COMPILE=arm-none-linuxWith this variable set in the environment you can use much shorter and clearer commands, E.g:
make
make
make
make
make
$MAKE_VISION
$MAKE_VISION
$MAKE_VISION
$MAKE_VISION
$MAKE_VISION
vision_defconfig
prepare
all
modules_prepare
M=../custom-module
Cross Compiling
Because the target architecture (ARM) is different to the host (IA32) Make needs to be instructed to create
output suitable for ARM with "ARCH=arm".
In addition Make has to know how to find the cross-compile tool-chain. The convention is that the various tools
have names prefixed with the architecture and platform they target. So the compiler that builds for the same
target as the host is called "gcc" but the one that targets ARM linux is called "arm-none-linux-gnueabi-gcc"
(This is the prefix used by all the tools installed by Sourcery G++ Lite). Because there are many tools, not just
"gcc", Make accepts the CROSS_COMPILE option that gives the prefix all the tools use: in this case
"CROSS_COMPILE=arm-none-linux-gnueabi-". Because the tools are already in the executable search
path (/usr/local/bin/) we do not need to specify the absolute path.
Because the ARM target source-code contains instructions for the NEON (Advanced SIMD Single Instruction
Multiple Data) FPU (floating point processor) we must also pass an extra option to the assembler to let it know
this using "EXTRA_AFLAGS=-mfpu=neon" otherwise we'll see assembler errors early in the build:
AS
arch/arm/mach-msm/idle-v7.o
/home/all/SourceCode/android/HTC/vision-2.6.32-g814e0a1/arch/arm/mach-msm/idle-v7.S: Ass
/home/all/SourceCode/android/HTC/vision-2.6.32-g814e0a1/arch/arm/mach-msm/idle-v7.S:47:
/home/all/SourceCode/android/HTC/vision-2.6.32-g814e0a1/arch/arm/mach-msm/idle-v7.S:48:
/home/all/SourceCode/android/HTC/vision-2.6.32-g814e0a1/arch/arm/mach-msm/idle-v7.S:117:
/home/all/SourceCode/android/HTC/vision-2.6.32-g814e0a1/arch/arm/mach-msm/idle-v7.S:125:
/home/all/SourceCode/android/HTC/vision-2.6.32-g814e0a1/arch/arm/mach-msm/idle-v7.S:126:
make[2]: *** [arch/arm/mach-msm/idle-v7.o] Error 1
make[1]: *** [arch/arm/mach-msm] Error 2
make: *** [sub-make] Error
So, the cross-compiler specific options are:
Building
6 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
These examples rely upon creating the MAKE_VISION environment variable as described above in the
section Short Command Line.
There are several steps involved in building the kernel. Start off by changing to the project directory:
cd vision-2.6.32-g814e0a1
Create .config for this target
The first and most important step is to provide Make with the kernel configuration file ".config" (Note that
file-names that begin with a "." (dot a.k.a period) are usually hidden from directory listings). The kernel source
tree contains many default config files for various architectures so we tell Make to use the one for the HTC
Vision (which is in arch/arm/configs/vision_defconfig):
make $MAKE_VISION vision_defconfig
This will create the required configuration in ../builds/vision-2.6.32-g814e0a1
ls -A1 ../builds/vision-2.6.32-g814e0a1/
.config
include
Makefile
scripts
source
Prepare
Now we need to prepare some scripts and header files based on this configuration:
make $MAKE_VISION prepare
Build the Kernel
Now we're ready to build. Let's use the "all" target to build the entire kernel:
make $MAKE_VISION all
Build a Custom Module
If you're developing and/or building a custom module for this kernel there are several steps you can take to
keep the source-code of the module separate from the kernel source, and to avoid rebuilding the kernel whilst
testing and modifying.
Let's create a custom module in a new directory that is a sibling (brother or sister) of the kernel directory:
mkdir ../custom-module
And let's add a module skeleton there sufficient for a successful build. Using your preferred text-editor create
the file ../custom-module/skeleton.c with the contents:
/*
7 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
skeleton.c
Copyright (C) 2010 TJ
Author: TJ <linux@tjworld.net>
This software is licensed under the terms of the GNU General Public
License version 2, as published by the Free Software Foundation, and
may be copied, distributed, and modified under those terms.
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 General Public License for more details.
#include <linux/module.h>
#include <linux/init.h>
static const char *module_name = "skeleton";
static int __init skeleton_init(void)
{
printk(KERN_INFO "Module %s loaded\n", module_name);
return 0;
}
static void __exit skeleton_exit(void)
{
printk(KERN_INFO "Module %s unloaded\n", module_name);
return;
}
module_init(skeleton_init);
module_exit(skeleton_exit);
MODULE_AUTHOR("TJ <linux@tjworld.net>");
MODULE_DESCRIPTION("Skeleton example module");
MODULE_LICENSE("GPL");
Create the accompanying ../custom-module/Makefile:
obj-m += skeleton.o
To avoid the compile-time warning:
8 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
9 of 10
Linux/Kernel/ARMCrossCompileOnIntel TJworld
http://tjworld.net/wiki/Linux/Kernel/ARMCrossCo...
mrproper
make $MAKE_VISION mrproper
mrproper will do a clean and then remove the files created by prepare such as .config and
Modules.symvers.
After mrproper you'll need to install the .config file again (e.g. using the vision_defconfig target) and a
prepare to install scripts and headers. Obviously the .config file you install will depend on the architecture and
device you are targeting.
Attachments
10 of 10