Building an ARM Linux cross-compilation toolchain
The first step in building a cross compiler is to determine the target platform. In the GNU system, each target platform has a clear format, and this information is used to identify the correct versions of the different tools to be used during the build process. Therefore, when running GCC under a specific target machine, GCC looks for the application path containing the target specification in the directory path. The format of the GNU target specification is CPU-PLATFORM-OS. For example, the x86/i386 target machine is called i686-pc-linux-gnu. The purpose of this chapter is to describe the establishment of a cross tool chain based on the ARM platform, so the target platform is called arm-linux-gnu.
There are usually three ways to build a cross toolchain.
Method 1 compiles and installs the libraries and source code required by the cross-compilation toolchain step by step, and finally generates a cross-compilation toolchain. This method is relatively difficult and is suitable for readers who want to learn in depth about building a cross-compilation toolchain. If you just want to use a cross-compilation toolchain, it is recommended to use method 2 or method 3 to build a cross-compilation toolchain.
Method 2 uses the Crosstool script tool to compile and generate a cross-compilation tool chain in one go. This method is much simpler than method 1 and has very few chances of error. It is recommended to use this method to build a cross-compilation tool chain in most cases.
Method 3: Download the cross-compilation toolchain directly from the Internet (ftp.arm.kernel.org.uk). The advantages of this method are simple and easy, but at the same time, the disadvantages of this method are that it is too limited, because it is built by others, which means it is fixed and inflexible. Therefore, the version of the library and compiler used in the construction may not be suitable for the program you want to compile. At the same time, many inexplicable errors may occur when using it. Readers are advised to use this method with caution.
In order to allow readers to truly learn how to build a cross-compilation tool chain, the following will focus on introducing in detail the first two methods of building an ARM Linux cross-compilation tool chain.
Build a cross-compilation chain step by step
Step-by-step construction, as the name implies, is to build a cross-compilation chain step by step. Different from the one-time compilation generation method of the Crosstool script tool described in Section 2.2.2, this method is suitable for readers who want to learn more about building a cross-compilation tool chain. This method is relatively difficult and usually full of difficulties, just like Tang Monk's journey to the West to obtain Buddhist scriptures. However, this article will introduce each step of the construction in as much detail as possible. Readers can practice independently based on the content of this section and build their own cross-tool chain. This process takes a long time, and readers are expected to have strong patience and perseverance to learn and practice it. Through practice, readers can better understand the construction process of the cross compiler and the role of each toolkit. The resources required for this method are shown in Table 2.1.
Installation package download addressInstallation package download
addresslinux-2.6.10.tar.gz ftp.kernel.org glibc-2.3.2.tar.gz ftp.gnu.org
binutils-2.15.tar.bz2 ftp.gnu.org glibc-linuxthreads-2.3.2.tar.gz ftp.gnu.org
gcc-3.3.6.tar.gz ftp.gnu.org
After downloading the above resources from the relevant sites, you can start building a cross-compilation tool chain.
1. Create a working directory
First, create a working directory. The working directory is the directory where the cross tool chain is built. There are generally no special requirements for the directory construction, and it can be created according to personal preferences. The directory created below is customized by the author. The current user is defined as mike, so the user directory is /home/mike. First, create a working directory (armlinux) under the user directory. The command line operation to create a working directory is as follows:
# cd /home/mike
# mkdir armlinux
Then create three directories build-tools, kernel and tools under this working directory armlinux. The specific operations are as follows:
# cd armlinux
# mkdir build-tools kernel tools
The functions of each directory are as follows.
● build-tools is used to store the downloaded binutils, gcc, glibc and other source codes and the directory used to compile these source codes;
● kernel is used to store kernel source code;
● tools is used to store compiled cross-compilation tools and library files.
The purpose of this step is to facilitate repeated input of the path, because repeating the same operation is always troublesome. If the reader is not used to using environment variables, you can skip this step and directly enter the absolute path. The purpose of declaring the following environment variables is to use them when compiling the tool library later, which is very convenient to input, especially to reduce the risk of entering the wrong path.
# export PRJROOT=/home/mike/armlinux
# export TARGET=arm-linux
# export PREFIX=$PRJROOT/tools
# export TARGET_PREFIX=$PREFIX/$TARGET
# export PATH=$PREFIX/binPATH
Note that variables declared with export are temporary variables, that is, when you log out or change the console, these environment variables will disappear. If you need to use these environment variables, you must repeat the export operation, which is sometimes very troublesome. Fortunately, environment variables can also be defined in the bashrc file, so that when you log out or change the console, these variables will always be valid, and you don't have to export these variables all the time.
3. Compile and install Binutils
Binutils is one of the GNU tools. It includes connectors, assemblers and other tools for object files and archives. It is a binary code processing and maintenance tool. The programs included in the installation of Binutils tools are addr2line, ar, as, c++filt, gprof, ld, nm, objcopy, objdump, ranlib, readelf, size, strings, strip, libiberty, libbfd and libopcodes. A brief explanation of these programs is as follows.
● addr2line converts program addresses into file names and line numbers. Give it an address and an executable file name on the command line, and it will use the executable's debugging information to figure out which file and line number is at the given address.
● ar creates, modifies, and extracts archive files. An archive file is a large file that contains the contents of multiple files. Its structure ensures that the original file contents can be restored.
● as is mainly used to compile the assembly files output by the GNU C compiler gcc, and the generated target files are connected by the connector ld.
● c++filt The linker uses this to filter C++ and Java symbols to prevent overloaded function conflicts.
● gprof displays various data of the program call segment.
● ld is the linker, which combines several object and archive files together, relocates data, and connects symbolic references. Usually, the last step in setting up a new compiler is to call ld.
● nm lists the symbols in an object file.
● objcopy copies the contents of one type of object file to another type of object file.
● objdump displays information about one or more object files. Use options to control the information it displays. The information it displays is usually only of interest to people who write compilation tools.
● ranlib generates an archive file index and saves it to the archive file. The index lists the redistributable object files defined by each member of the archive file.
● readelf displays information of executable files in elf format.
● size lists the size of each section of the object file and the overall size. By default, only one line of output is produced for each object file or each module in an archive file.
● strings prints printable strings of a file. These strings are at least 4 characters long. You can also use the option -n to set the minimum length of the string. By default, it only prints printable characters in the initialization and loadable segments of the target file; for other types of files, it prints the printable characters of the entire file. This program is very helpful for understanding the contents of non-text files.
● strip discards all or specific symbols in the target file.
● libiberty contains functions used by many GNU programs, including getopt, obstack, strerror, strtol, and strtoul.
● libbfd binary file description library.
● libopcode is a library used to process opcodes. It is also used when generating some applications.
The Binutils tool installation depends on tools such as Bash, Coreutils, Diffutils, GCC, Gettext, Glibc, Grep, Make, Perl, Sed, and Texinfo.
After introducing the Binutils tool, the following will introduce the process of installing binutils-2.15 step by step.
First, unzip the binutils-2.15.tar.bz2 package. The command is as follows:
# cd $PRJROOT/build-tools
# tar –xjvf binutils-2.15.tar.bz2
Next, configure the Binutils tool. It is recommended to create a new directory to store configuration and compilation files, so that the source files and compiled files can be separated. The specific operations are as follows:
# cd $PRJROOT/build-tools
# mkdir build-binutils
# cd build-binutils
# ../binutils-2.15/configure --target=$TARGET --prefix=$PREFIX
The option –target means to generate the arm-linux tool, and --prefix indicates the location where the executable file is installed. When executing the above operation, a lot of check information will appear, and finally a Makefile file will be generated. Next, execute the make and installation operations, the command is as follows:
# make
# make install
The compilation process is slow and takes dozens of minutes. After the installation is complete, check the files in the /home/mike/armlinux/tools/bin directory. If the result is as follows, it indicates that the Binutils tool has been installed.
# ls $PREFIX/bin
arm-linux-addr2line arm-linux-ld arm-linux-ranlib arm-linux-strip
arm-linux-ar arm-linux-nm arm-linux-readelf
arm-linux-as arm-linux-objcopy arm-linux-size
arm-linux-c++filt arm-linux-objdump arm-linux-strings
The compiler needs the kernel header files to get the information needed to call the system functions supported by the target platform. For the Linux kernel, the best way is to download a suitable kernel and copy the header files. A basic configuration of the kernel is required to generate the correct header files; however, it is not necessary to compile the kernel. For the target arm-linux in this example, the following steps are required.
(1) Unzip the linux-2.6.10.tar.gz kernel package in the kernel directory and execute the following command:
# cd $PRJROOT/kernel
# tar –xvzf linux-2.6.10.tar.gz
(2) Next, configure and compile the kernel to generate the correct header file. Execute the following command:
# cd linux-2.6.10
# make ARCH=arm CROSS_COMPILE=arm-linux-menuconfig
ARCH=arm indicates that the architecture is arm, and CROSS_COMPILE=arm-linux- indicates that the cross compiler is prefixed with arm-linux-. You can also use config and xconfig instead of menuconfig. It is recommended to use make menuconfig, which is also the configuration method most used by kernel developers. Note that you must select the processor type during configuration. Here, select Samsung's S3C2410 (System Type->ARM System Type->/Samsung S3C2410), as shown in Figure 2.1. After configuration, exit and save. Check whether the include/linux/version.h and include/linux/autoconf.h files in the kernel directory are generated. These are used when compiling glibc. If the version.h and autoconf.h files exist, it means that the correct header files have been generated.
Copy the header file to the directory of the cross-compilation tool chain. First, you need to create the tool header file directory inlcude in the /home/mike/armlinux/tools/arm-linux directory, and then copy the kernel header file to this directory. The specific operations are as follows:
# mkdir –p $TARGET_PREFIX/include
# cp –r $PRJROOT/kernel/linux-2.6.10/include/linux $TARGET_PREFIX/include
# cp –r $PRJROOT/kernel/linux-2.6.10/include/asm-arm $TARGET_PREFIX/include/asm
5. Compile and install boot-trap gcc
The purpose of this step is to build the arm-linux-gcc tool. Note that this gcc does not have the support of the glibc library, so it can only be used to compile programs that do not require C library support, such as the kernel and BootLoader. This compiler will also be used to create the C library later, so creating it is mainly to prepare for creating the C library. If you only want to compile the kernel and BootLoader, then you can end here after installing this. The installation command is as follows:
# cd $PRJROOT/build-tools
# tar –xvzf gcc-3.3.6.tar.gz
# mkdir build-gcc
# cd gcc-3.3.6
# vi gcc/config/arm/t-linux
Since this is the first time to install the ARM cross-compilation tool, there is no header file supporting the libc library. Therefore, in the gcc/config/arm/t-linux file, add the operation parameter option -Dinhibit_libc -D__gthr_posix_h to the variable TARGET_LIBGCC2_CFLAGS to block the use of header files. Otherwise, the /usr/inlcude header file will be used by default.
Change TARGET_LIBGCC2-CFLAGS=-fomit-frame-pointer–fPIC to TARGET_LIBGCC2-CFLAGS=-fomit-frame-pointer–fPIC -Dinhibit_libc -D__gthr_posix_h
After modifying the t-linux file, save it and then execute the configuration operation, as follows:
# cd build-gcc
# ../ build-gcc /configure --target=$TARGET --prefix=$PREFIX --enable-languages=c
--disable-threads --disable-shared
The option --enable-languages=c means that only C language is supported, --disable-threads means that the thread function is removed, which requires the support of glibc. --disable-shared means that only static library compilation is performed, and shared library compilation is not supported.
Next, perform the compilation and installation operations. The commands are as follows:
# make
# make install
After the installation is complete, check under /home/mike/armlinux/tools/bin. If tools such as arm-linux-gcc have been generated, it means that the boot-trap gcc tool has been installed successfully.
6. Build the glibc library
glibc is the GNU C library, which is an important component for compiling Linux system programs. Before installing glibc-2.3.2, it is recommended to install the following tools:
● GNU make 3.79 or later;
● GCC 3.2 or later;
● GNU binutils 2.13 or later.
First, unzip the glibc-2.2.3.tar.gz and glibc-linuxthreads-2.2.3.tar.gz source codes as follows:
# cd $PRJROOT/build-tools
# tar -xvzf glibc-2.2.3.tar.gz
# tar -xzvf glibc-linuxthreads-2.2.3.tar.gz --directory=glibc-2.2.3
Then compile and configure. Before configuring glibc-2.2.3, you must create a new compilation directory. Otherwise, configuration operations are not allowed in the glibc-2.2.3 directory. Here, create a directory named build-glibc in the $PRJROOT/build-tools directory. The configuration operations are as follows:
# cd $PRJROOT/build-tools
# mkdir build-glibc
# cd build-glibc
# CC=arm-linux-gcc ../glibc-2.2.3 /configure --host=$TARGET --prefix="/usr"
--enable-add-ons --with-headers=$TARGET_PREFIX/include
The option CC=arm-linux-gcc sets the CC (Cross Compiler) variable to the newly compiled gcc, and uses it to compile glibc. --prefix="/usr" defines a directory for installing some data files that are not related to the target machine. By default, it is the /usr/local directory. --enable-add-ons tells glibc to use the linuxthreads package, which has been placed in the glibc source code directory above. This option is equivalent to -enable-add-ons=linuxthreads. --with-headers tells glibc the directory location of the linux kernel header files.
After configuration, you can compile and install glibc. The specific operations are as follows:
# make
# make install
Since the first installed gcc does not support cross-glibc, now that glibc has been installed, it needs to be recompiled to support cross-glibc. And the above gcc only supports C language, now it can be made to support both C language and C++ language. The specific operation is as follows:
# cd $PRJROOT/build-tools/gcc-2.3.6
# ./configure --target=arm-linux --enable-languages=c,c++ --prefix=$PREFIX
# make
# make install
After the installation is complete, you will find that there are more files such as arm-linux-g++ and arm-linux-c++ in the $PREFIX/bin directory.
# ls $PREFIX/bin
arm-linux-addr2line arm-linux-g77 arm-linux-gnatbind arm-linux-ranlib
arm-linux-ar arm-linux-gcc arm-linux-jcf-dump arm-linux-readelf
arm-linux-as arm-linux-gcc-3.3.6 arm-linux-jv-scan arm-linux-size
arm-linux-c++ arm-linux-gccbug arm-linux-ld arm-linux-strings
arm-linux-c++filt arm-linux-gcj arm-linux-nm arm-linux-strip
arm-linux-cpp arm-linux-gcjh arm-linux-objcopy grepjar
arm-linux-g++ arm-linux-gcov arm-linux-objdump jar
8. Test the cross-compilation toolchain
So far, we have introduced the step-by-step method to build a cross-compilation tool chain. Now let's test the cross-compilation tool chain we just built with a simple program to see if it works properly. Write a simplest hello.c source file with the following content:
#include
int main( )
{
printf("Hello, world!\n");
return 0;
}
Compile with the following command, and an executable file named hello will be generated after compilation. The file type can be checked with the file command. When the following information is displayed, it means that the cross tool chain is installed normally, and an executable file for the ARM system is generated through compilation. Note that the executable file compiled by this cross-compilation chain can only be executed under the ARM system, and cannot be executed on an ordinary PC based on X86.
# arm-linux-gcc –o hello hello.c
# file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.3,
dynamically linked (uses shared libs), not stripped
Crosstool is a set of script tools that can build and test different versions of gcc and glibc for architectures that support glibc. It is also an open source project, and the download address is http://kegel.com/crosstool. Using Crosstool to build a cross tool chain is much easier than the above step-by-step compilation, and it is also much more convenient. This method is recommended for readers who only need to build a cross-compilation tool chain for work. The resources required to build the Crosstool tool are shown in Table 2.2.
Table 2.2 Required resources
Installation package download address
crosstool-0.42.tar.gz [url]http://kegel.com/crosstool [/url]
linux-2.6.10.tar.gz ftp.kernel.org
binutils-2.15.tar.bz2 ftp.gnu.org
gcc-3.3.6.tar.gz ftp.gnu.org
glibc-2.3.2.tar.gz ftp.gnu.org
glibc-linuxthreads-2.3.2.tar.gz ftp.gnu.org
linux-libc-headers-2.6.12.0.tar.bz2 ftp.gnu.org
1. Prepare resource files
First, download the required resource files linux-2.6.10.tar.gz, binutils-2.15.tar.bz2, gcc-3.3.6.tar.gz, glibc- 2.3.2.tar.gz, glibc-linuxthreads-2.3.2.tar.gz and linux-libc-headers- 2.6.12.0.tar.bz2 from the Internet. Then put these tool package files in the newly created /home/mike/downloads directory, and finally unzip crosstool-0.42.tar.gz in the /home/mike directory. The command is as follows:
# cd /home/mike
# tar –xvzf crosstool-0.42.tar.gz
2. Create a script file
Next, you need to create your own compilation script and name it arm.sh. To simplify writing arm.sh, find a closest script file demo-arm.sh as a template, then copy the contents of the script to arm.sh and modify the arm.sh script. The specific operations are as follows:
# cd crosstool-0.42
# cp demo-arm.sh arm.sh
# vi arm.sh
The modified arm.sh script content is as follows:
#!/bin/sh
set -ex
TARBALLS_DIR=/home/mike/downloads # Defines the location where the toolchain source code is stored.
RESULT_TOP=/opt/crosstool # Define the installation directory of the tool chain
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES="c,c++" # Define support for C, C++ languages
export GCC_LANGUAGES
# Create the /opt/crosstool directory
mkdir -p $RESULT_TOP
# Compile the toolchain. This process may take several hours to complete.
eval 'cat arm.dat gcc-3.3.6-glibc-2.3.2.dat' sh all.sh --notest
echo Done.
3. Create a configuration file
In the arm.sh script file, you need to pay attention to the two files arm.dat and gcc-3.3.6-glibc-2.3.2.dat. These two files are the configuration files for Crosstool compilation. The content of the arm.dat file is as follows, which is mainly used to define the configuration file, define the name of the generated compilation tool chain, and define the compilation options.
KERNELCONFIG='pwd'/arm.config # Kernel configuration
TARGET=arm-linux- # Toolchain name generated by compilation
TARGET_CFLAGS="-O" # Compile options
The contents of the gcc-3.3.6-glibc-2.3.2.dat file are as follows. This file mainly defines the libraries required in the compilation process and the versions it defines. If some libraries are found to be non-existent during the compilation process, Crosstool will automatically download them from the relevant website. This tool is relatively intelligent and very useful in this regard.
BINUTILS_DIR=binutils-2.15
GCC_DIR=gcc-3.3.6
GLIBC_DIR=glibc-2.3.2
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2
LINUX_DIR=linux-2.6.10
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
After preparing the Crosstool script file and configuration file, start executing the arm.sh script to compile the cross-compilation tool. The specific execution command is as follows:
# cd crosstool-0.42
# ./arm.sh
After several hours of long compilation, a new cross-compilation tool will be generated in the /opt/crosstool directory, including the following:
arm-linux-addr2line arm-linux-g++ arm-linux-ld arm-linux-size
arm-linux-ar arm-linux-gcc arm-linux-nm arm-linux-strings
arm-linux-as arm-linux-gcc-3.3.6 arm-linux-objcopy arm-linux-strip
arm-linux-c++ arm-linux-gccbug arm-linux-objdump fix-embedded-paths
arm-linux-c++filt arm-linux-gcov arm-linux-ranlib
arm-linux-cpp arm-linux-gprof arm-linux-readelf
5. Add environment variables
Then add the generated compilation toolchain path to the environment variable PATH. The method of adding it is to add the following line at the end of the system /etc/bashrc file, as shown in Figure 2.2.
Add environment variables to bashrc file using Vi editor
export PATH=/opt/crosstool/gcc-3.3.6-glibc-2.3.2/arm-linux/bin:$PATH
After setting the environment variables, it means that the cross-compilation tool chain has been built. Then you can use the method in Section 2.2.1.8 to test the newly built tool chain. There is no need to go into details here.
Previous article:Establishing ARM-Linux cross-compilation environment under ubuntu8.10
Next article:Guide to making ARM Linux cross-compilation toolchain
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Does anyone have a good thermostat switch?
- Ultra-low power MCU-How to reduce the power consumption of MCU
- [MM32 eMiniBoard Review] Part 4: Questions about multi-channel ADC
- Modbus_RTU (RS485) Fieldbus Remote Inputs/Outputs Modules System Design Based on GD32E231
- Particle Xenon nRF52840 BLE Development Board
- Technical Science: The Essential Differences between DRAM and NAND
- Sugar glider ③ RSL10-SENSE-GEVK light sensor driver is written and shared with everyone
- When using the stc8 series for ADC multi-channel sampling, the sampling data of one channel is sometimes accurate and sometimes wrong.
- STM32F205 series MCU OTP problem
- 《GaN Transistors for Efficient Power Conversion》