Welcome to the Slackware Documentation Project

¡Esta es una revisión vieja del documento!


En proceso de traducción. rramp

Slackware ARM GCC aarch64-linux compilación cruzada para la Raspberry Pi

Prefacio

Estaba pensando en la CPU de 64 bits Cortex-A53 de mi Raspberry Pi 3 y por qué estoy usando principalmente el sistema operativo Slackware ARM de 32 bits en ella. Entonces empecé a preguntarme si sería posible construir un kernel arm64 y módulos para correr con Slackware ARM. Después de leer acerca de cómo se podría lograr esto, parecía claro que se requeriría cierta compilación cruzada. Aunque tengo algo de experiencia en la construcción de núcleos (kernel) Linux, especialmente para la plataforma Raspberry Pi, nunca había hecho ninguna compilación cruzada hasta hace una semana (2016-12-15). Así que, todo este concepto era totalmente nuevo para mí.

Para mi primer intento (y en gran parte basado en la lectura de cómo lo hacían otros usuarios) usé un sistema Ubuntu 16.04.1 LTS (64 bits) para compilar un núcleo arm64 para el Raspberry Pi 3. Sin embargo, los resultados de hacer las cosas por este método fueron un tanto escasos y crearon muchos errores imprevistos. Entonces recordé algo Mozes había publicado el his Slackware ARM FAQ page sobre paquetes que se estaban construyendo de forma nativa. Una investigación más profunda me llevó a darme cuenta de que el éxito asegurado probablemente se encontraría al compilar de forma cruzada en un dispositivo ARM usando Slackware ARM. ¡Eso es exactamente lo que hice! Muy exitosamente, debo añadir. Gracias de nuevo, Mozes. <3

Como han resultado las cosas, no fue tan difícil. Se requirió invertir algún tiempo en la lectura sobre las cadenas de herramientas (toolchains) y cómo construir empleando compiladores cruzados, así como en probar los resultados de la compilación cruzada, pero en general ha sido un proceso relativamente simple. Usar Slackware ARM current para compilar la arquitectura aarch64 fue la clave del éxito aquí. Ahora soy muy consciente de que, en comparación, intentar compilar aarch64 en un sistema Ubuntu x86_64 era menos que productivo.

Notas

Slackware ARM current Slackware ARM current was used on a Raspberry Pi 3 to build and install the GCC aarch64-linux cross-compiler, and build the arm64 Linux kernel, modules, and device tree blob(s). That's not to say Slackware ARM 14.2 won't work too, but I just didn't do any cross-compiling on the soft float port. The same applies to the Raspberry Pi 1 and 2. Even though it should be possible to carry out aarch64 cross-compiler builds on these devices, I didn't do any testing with them. Also bear in mind that configuration options and settings will need to be considered first.

Requerimientos

Como requisito previo, deberías haberlo logrado;

  • Una Raspberry Pi 3 corriendo Slackware ARM con aproximadamente 8GB de espacio libre en tu sistema.
  • gawk, git, bison y flex, ya instalado en tu sistema.
  • Un lector de tarjetas microSD USB para conectar con su Raspberry Pi 3.
  • Una tarjeta microSD (de respuesto) con Slackware current instalada en ella no es esencial, pero se aconseja.

De que se trata

Este tutorial le permitirá;

  • Descargar los paquetes de fuentes requeridos con el objetivo de construir un compilador cruzado de GCC en Slackware ARM.
  • Descargar el kernel de Linux para la Raspberry Pi GitHub y cambie a la rama de desarrollo de 64 bits.
  • configure, e instale, un compilador cruzado GCC aarch64-linux (arm64) sobre tu Raspberry Pi 3.
  • Construir un kernel aarch64 (arm64), módulos, y árbol de dispositivos e instalarlos en su tarjeta microSD actual Slackware ARM (de repuesto).
  • build an aarch64 (arm64) Linux kernel, modules, and device tree blob(s), and install them on your (spare) Slackware ARM current microSD card.
  • arrancar con éxito Slackware ARM actual en su Raspberry Pi 3 ejecutando un kernel aarch64 (arm64).
Para no arriesgarse a estropear el sistema ARM de Slackware que utiliza para la compilación cruzada, se debe utilizar una tarjeta microSD (de repuesto) que contenga un sistema ARM de Slackware que funcione para instalar el núcleo Linux arm64, los módulos y el árbol de dispositivos. Necesitará una versión reciente (es decir, posterior a septiembre de 2016) del Raspberry Pi bootloader/GPU firmware instalada en esta tarjeta microSD (de repuesto) para evitar problemas. Para estar seguro, arranque su RPi3 con él y actualice el firmware. La versión del núcleo de Linux en esta tarjeta microSD (de repuesto) no importa, ya que la sustituirá por el núcleo aarch64 (arm64).

Descarga del código fuente requerido y configuración

Primero de todo, como un usuario normal (es decir, no 'root') cree un directorio de trabajo. Por ejemplo, yo usualmente trabajo en el directorio /tmp:

cd /tmp
mkdir build-dir
cd build-dir

Este es el directorio donde se va a descargar todos los paquetes requeridos y las fuentes de Linux RPi.

Descargue el código fuente del kernel de Linux

Use el siguiente comando 'git' para descargar el kernel Linux para la Raspberry Pi en un directorio llamado 'linux'.

git clone https://github.com/raspberrypi/linux linux

Esto puede tardar un poco, dependiendo de la velocidad de su conexión a Internet y otros factores. Una vez que se haya completado necesita cambiar a la rama de desarrollo del kernel de 64 bits.

cd linux
git checkout rpi-4.8.y

Cuando eso esté hecho, deberías ver un mensaje de que 'origin/rpi-4.8.y' es la rama actual.

Descarga del código fuente

Antes de descargar el código fuente del paquete necesario para construir el compilador cruzado GCC, tenga en cuenta que pueden existir versiones de paquetes más recientes que las que se muestran aquí. Es posible que desee instalar versiones más recientes. Siempre es una buena idea revisar. Para mantener las cosas simples, puede considerar descargar una versión de GCC que coincida con la que tiene instalada actualmente. He leído muchos artículos sobre esto y la mayoría aconseja instalar la última versión de GCC disponible. Sin embargo, si está ejecutando Slackware ARM current tendrá instalado gcc-5.4.0 y esto es adecuado para lo que se necesita.

Así que, primero muévete de vuelta al directorio 'build-dir' y entonces descarga los siguientes paquetes.

cd ../
wget -nc https://ftp.gnu.org/gnu/binutils/binutils-2.27  
wget -nc ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1   
wget -nc https://ftp.gnu.org/gnu/gcc/gcc-5.4.0  
wget -nc https://ftp.gnu.org/gnu/glibc/glibc-2.24  
wget -nc https://ftp.gnu.org/gnu/gmp/gmp-6.1.1  
wget -nc ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.16.1  
wget -nc https://ftp.gnu.org/gnu/mpc/mpfr-3.1.5  
wget -nc https://ftp.gnu.org/gnu/mpfr/mpc-1.0.3

Desempaquetado de los tarballs descargados

Ahora desempaqueta todos los tarballs descargados. Puede hacer esto fácilmente con el comando 'for'.

for t in *.tar*; do tar -xvf $t; done

Una vez que esto se haya completado, puede usar el comando 'ls' para verificar que los directorios están presentes.

Ahora vas a crear algunos enlaces simbólicos en el directorio gcc-5.4.0. Now you are going to create some symbolic links in the gcc-5.4.0 directory. These will point to some of the source directories you have just unpacked, which are dependencies of GCC, and when these symbolic links are present GCC will build them automatically.

cd gcc-5.4.0
ln -sf ../cloog-0.18.1 cloog
ln -sf ../gmp-6.1.1 gmp
ln -sf ../isl-0.16.1 isl
ln -sf ../mpfr-3.1.5 mpc
ln -sf ../mpfr-3.1.5 mpfr

Alternatively, some articles will advise you to use the following command in order to achieve the same thing.

cd gcc-5.4.0
./contrib/download_prerequisites

Personally, I always prefer the manual method because then I know what's being downloaded/installed and what to expect. It's up to you which method you use.

Creating GCC cross-compiler install directory

The next thing to do is create an installation directory. This is the directory where the toolchain will be installed. Again, I like to work in /tmp so the install directory will be created there.

cd /tmp
mkdir gcc-cross

Exporting install directory PATH

You need to export the installation directory's /bin folder to your user's $PATH.

export PATH=/tmp/gcc-cross/bin:$PATH

To check that this has worked, use the following command:

echo $PATH

You should see the first $PATH entry is to your installation directory's /bin folder. It's important that your installation directory's /bin folder appears before any other entry in the $PATH.

/tmp/gcc-cross/bin:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib/kde4/libexec:/usr/lib/qt/bin

Building the GCC aarch64 cross-compiler

Now with all that in place, concentration focuses on building the cross-assembler, cross-disassembler, cross-linker, and other useful tools.

Building binutils

First move back into the 'build-dir' directory and then create a build directory for binutils. You'll notice the various build options but as a quick explanation; '–with-sysroot' basically tells binutils to enable 'sysroot' support in the cross-compiler by pointing it to a default empty directory, '–target=aarch64-linux' is the target system type (arm64), and '–disable-multilib' means that we only want binutils to work with the aarch64 instruction set and nothing else.

cd build-dir
mkdir build-binutils
cd build-binutils
../binutils-2.27/configure --prefix=/tmp/gcc-cross --with-sysroot --target=aarch64-linux --disable-multilib
make -j4 
make install

Installing Linux kernel headers

Here you need to install the Linux kernel headers. Note the 'ARCH=arm64' option for the make process. GCC uses 'aarch64' where the Linux kernel uses 'arm64'. The two separate open source projects identify the same CPU architecture differently.

cd ../linux
make ARCH=arm64 INSTALL_HDR_PATH=/tmp/gcc-cross/aarch64-linux headers_install

Build GCC

First move into the 'build-dir' directory and create a build directory for GCC before building it. Notice that only C and C++ have been specified as build languages. That's all you will need here. Incidentally, the available build language options allow just one, or a selection, or all, of the following '–enable-languages=all,ada,c,c++,fortran,go,jit,lto,objc,obj-c++'.

cd ../
mkdir build-gcc
cd build-gcc
../gcc-5.4.0/configure --prefix=/tmp/gcc-cross --target=aarch64-linux --enable-languages=c,c++ --disable-multilib
make -j4 all-gcc
make install-gcc

Build and install glibc

First move into the 'build-dir' directory and create a 'build-glibc' directory. Then move into the 'build-glibc' directory before building it. '–build=$MACHTYPE' is a predefined environment variable which describes the Raspberry Pi 3 (in this case) and it's required to compile some additional tools which are utilised during the build process. Notice that you're installing the C library startup files to the installation directory (csu/crt1.o, csu/crti.o, and csu/crtn.o) separately because there doesn’t seem to a 'make' rule that does this without creating other problems.

cd ../
mkdir -p build-glibc
cd build-glibc
../glibc-2.24/configure --prefix=/tmp/gcc-cross/aarch64-linux --build=$MACHTYPE --host=aarch64-linux --target=aarch64-linux --with-headers=/tmp/gcc-cross/aarch64-linux/include --disable-multilib libc_cv_forced_unwind=yes    
make install-bootstrap-headers=yes install-headers
make -j4 csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o /tmp/gcc-cross/aarch64-linux/lib
$ARCH_TARGET-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /tmp/gcc-cross/aarch64-linux/lib/libc.so
touch /tmp/gcc-cross/aarch64-linux/include/gnu/stubs.h

Building glibc support library

Now move into the 'build-gcc' directory once again and build the GCC cross-compiler support library.

cd ../build-gcc
make -j4 all-target-libgcc
make install-target-libgcc

Finish building glibc C library

Move into the 'build-glibc' directory to finish building glibc C library and then install it.

cd ../build-glibc
make -j4
make install

Finish building GCC C++ library

Move into the 'build-gcc' directory to finish building GCC C++ library and then install it.

cd ../build-gcc
make -j4
make install

Testing the cross-compiler

To test/check that your GCC aarch64-linux cross-compiler is working properly run the following command.

aarch64-linux-gcc -v

You should get a response similar to the following.

Using built-in specs.
COLLECT_GCC=aarch64-linux-gcc
COLLECT_LTO_WRAPPER=/tmp/gcc-cross/libexec/gcc/aarch64-linux/5.4.0/lto-wrapper
Target: aarch64-linux
Configured with: ../gcc-5.4.0/configure --prefix=/tmp/gcc-cross --target=aarch64-linux --enable-languages=c,c++ --disable-multilib
Thread model: posix
gcc version 5.4.0 (GCC)

Once this process has been completed, export the GCC cross-compiler PATH on your normal user. If/when you're wanting to cross-compile do this each time after you've (re)booted your system so that the GCC cross-compiler can be located via your user's $PATH. You also have the option to add this command to your ~/.profile as a permanent setting. Whether or not you decide to permanently add the GCC cross-compiler PATH to your ~/.profile is entirely up to you. If you are using your Slackware ARM current system for exclusively building aarch64 (arm64) packages then it would make sense to do so.

Example export command:

export PATH=/tmp/gcc-cross/bin:$PATH

The GCC aarch64-linux cross-compiler on your Slackware ARM system is now ready to rock-n-roll!

Building the arm64 kernel, modules, and device tree blob (DTB)

To build the aarch64 kernel, modules and device tree blob(s) is exactly the same method as you would carry it out under normal circumstances. Commands such as 'make bzImage && make modules && make modules_install' may be all too familiar to you. The major difference when cross-compiling is that you'll use certain Makefile options/variables/arguments/switches, commonly known as CFLAGS. In our case, CFLAGS will be used to instruct the GCC cross-compiler to build for the aarch64 (arm64) architecture specifically.

Creating the arm64 kernel .config

First of all, as always, you need to be in the Raspberry Pi Linux kernel source directory which is in the 'build-dir' folder. Then you need to create a kernel .config file, based on Raspberry Pi 3 parameters. To keep it simple you can generate a default .config (defconfig) file. This file holds the Linux kernel configuration for the arm64 kernel you are going to build. To achieve this run the following commands:

cd /tmp/build-dir/linux
make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux- bcmrpi3_defconfig
Make a note here of the CFLAGS which have been specified. They should be self-explanatory by now. Pay special attention to the trailing '-' of 'CROSS_COMPILE=aarch64-linux-' because that's NOT a typo. It needs to be like that!

Building the arm64 kernel

Next up is building the kernel, based on the .config file you have just created. Again, you'll use the same CFLAGS as before. You can even set a 'LOCALVERSION' here which appends whatever you set to the end of the kernel version (e.g. LOCALVERSION=“-arm64” would eventually give you 4.8.13-v8–arm64) once the kernel and modules have been built. Just as an example we'll use it here. Run the following command to start building the arm64 Linux kernel:

make -j4 Image ARCH=arm64 CROSS_COMPILE=aarch64-linux- LOCALVERSION="-arm64"

So, here you 'make' the kernel which will be saved with the name 'Image'. The rest you should be familiar with. This process will take a while. Maybe an hour or so.

Building the arm64 device tree blob(s)

Device tree is a means of describing hardware which is read by the kernel at boot time to tell it what hardware exists on the system. In our case it relates to the Raspberry Pi 3 and is the method by which the systems knows which drivers to load for the hardware. On ARM-based devices the use of device trees has become mandatory for all new SOCs, including the Raspberry Pi. The device tree blobs you will be building are 'bcm2710-rpi-3-b.dtb' and 'bcm2837-rpi-3-b.dtb'

To build the Raspberry Pi device tree blob(s) run the following command:

make -j4 dtbs ARCH=arm64 CROSS_COMPILE=aarch64-linux- LOCALVERSION="-arm64"

It's basically the same as you did to build the kernel, only where 'Image' is substituted for 'dtbs'.

Building the arm64 modules

To build the kernel modules you do it in much the same way as before. Run the following command:

make -j4 modules ARCH=arm64 CROSS_COMPILE=aarch64-linux- LOCALVERSION="-arm64"

Notice how each time the command is the same except when specifying what you're building. If you have set a 'LOCALVERSION' then it must be kept the same for building the kernel and modules. This process will probably take a while longer than building the arm64 kernel.

Installing the arm64 modules

Once the modules have been built, you have to 'make modules_install'. The process will install your kernel modules to '/tmp/lib/modules/4.8.13-v8'.

You could build out-of-tree kernel modules but, to keep things simple, you're going to install them to the usual location. Again, you will use the same CFLAGS as before but without any 'LOCALVERSION' set.

First you need become 'root' user and enter a passwd when prompted. To install the aarch64 modules run the following commands:

su -
make -j4 modules_install ARCH=arm64 CROSS_COMPILE=aarch64-linux-
You need to be 'root' user to install the arm64 modules. A normal user does not have the rights to do so!

So, as I'm a great believer in being thorough, I always verify things at every opportunity. Just to be sure, if nothing else, because it's always a good policy. Make sure the files and directories you have just spent quite a bit of time compiling actually do exist on your system and that they're in the right place. If this is the first time you have installed the GCC cross-compiler on your system and/or built the kernel, modules, and device tree blob(s), then it goes without saying. You could actually do this after each build process, which I often do as well.

ls -lah arch/arm64/boot/Image 
la -lah arch/arm64/boot/dts/broadcom/bcm*-rpi-3-b.dtb
ls -lah /lib/modules/4.8.13-v8*

If you can see that they all exist, then everything has worked as planned.

Copying the arm64 kernel, modules, and device tree blobs (DTB)

Connect the (spare) microSD card containing a working Slackware ARM current system to your Raspberry Pi 3 using a USB microSD card reader. You'll need to mount the partitions first, before copying the arm64 kernel, modules, and device tree blob(s) onto it.

You should still be logged in as 'root' user. If not, type the following command and enter the passwd for the 'root' user when prompted:

su -
You need to be 'root' user to carry out any mount procedures. A normal user does not have the rights to do so!

As 'root' user type the following command:

fdisk -l

This should show you which device the (spare) microSD card is using on your system. In our case it's a 32GB card and has been identified as '/dev/sda', as shown below. This tells us that '/dev/sda1' is our /boot partition and '/dev/sda3' is our root filesystem partition. Yours may be allocated differently so bear that in mind.

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sda1  *        32   195327   195296 95.4M  c W95 FAT32 (LBA)
/dev/sda2       196608   720895   524288  256M 82 Linux swap
/dev/sda3       720896 61145087 60424192 28.8G 83 Linux

In order to mount the partitions you first need to create mount directories. Working in the /tmp directory you can do it like this:

cd /tmp
mkdir rpi-boot
mkdir rpi-root
mount /dev/sda1 rpi-boot
mount /dev/sda3 rpi-root

To check that you've done this correctly, use the 'mount' command. The output from this should give you something similar to the following:

/dev/mmcblk0p3 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
tmpfs on /dev/shm type tmpfs (rw)
/dev/mmcblk0p1 on /boot type vfat (rw,fmask=177,dmask=077)
/dev/sda1 on /tmp/rpi-boot type vfat (rw)
/dev/sda3 on /tmp/rpi-root type ext4 (rw)

The next thing to do is copy the arm64 kernel, modules, and device tree blobs to your newly mounted directories. It's important to get this right. After all the hard work you've done it would be a shame to mess it up at this stage.

To copy these files, run the following commands, as 'root' user:

cp build-dir/linux/arch/arm64/boot/Image rpi-boot/boot/kernel8.img
cp build-dir/linux/arch/arm64/boot/dts/broadcom/bcm*-rpi-3-b.dtb rpi-boot/boot
cp -rv /lib/modules/4.8.13-v8* rpi-root/lib/modules/

Once you have done that, check that the files you have copied are present and in the right place.

ls -lah rpi-boot/boot/kernel*
ls -lah rpi-boot/boot/bcm*-rpi-3-b.dtb 
ls -lah rpi-root/lib/modules/4.8.13-v8*

If it all looks fine and dandy then the next thing you need to do is delete the old armv7 kernel in the rpi-boot/boot directory. This old kernel is named 'kernel7.img' and to avoid any conflicts with the new arm64 'kernel8.img' you should remove it.

rm -rf rpi-boot/kernel7.img 

No changes to the config.txt or cmdline.txt file(s) should be necessary. If you are using a recent blootloader/GPU firmware version (i.e. post-September 2016) then nothing else needs to be changed or deleted. The system should boot using all your existing settings.

Now you can unmount the previously mounted directories.

umount rpi-boot
umount rpi-root

Booting Slackware ARM aarch64

Power off your Raspberry Pi.

poweroff

Remove the USB microSD card reader and swap microSD cards. Power on the Raspberry Pi and boot the microSD card on which you copied the arm64 kernel, modules, and device tree blobs.

The end result

After booting the system with the arm64 kernel, I logged in remotely via SSH as 'root' user. Then I ran the following commands:

login as: root
root@192.168.10.33's password:
Last login: Sat Dec 17 20:32:50 2016 from 192.168.10.10
Linux 4.8.13-v8-arm64.
root@drie:~# cat /proc/version
Linux version 4.8.13-v8-arm64 (exaga@drie) (gcc version 5.4.0 (GCC) ) #2 SMP Fri Dec 16 18:43:38 GMT 2016
root@drie:~# uname -a
Linux drie 4.8.13-v8-arm64 #2 SMP Fri Dec 16 18:43:38 GMT 2016 aarch64 GNU/Linux
root@drie:~# cat /etc/slackware-version
Slackware 14.2
root@drie:~# cat /proc/device-tree/model
Raspberry Pi 3 Model B Rev 1.2
root@drie:~# cat /proc/cmdline | awk -v RS=" " -F= '/serial/ { print $2 }'
0x4135b94e 
root@drie:~#

Although I've already come across a few things which need some work, and attention, it's a start. I hope to find more time to devote towards Slackware arm64 over Christmas and the New Year 2017.

Thanks for being interested. <3

Fuentes

ftp://ftp.arm.slackware.com/slackwarearm/slackwarearm-current/slackware/a/gawk-4.1.4-arm-1.txz # Slackware ARM current - gawk package.
ftp://ftp.arm.slackware.com/slackwarearm/slackwarearm-current/slackware/d/git-2.11.0-arm-1.txz # Slackware ARM current - git package.
ftp://ftp.arm.slackware.com/slackwarearm/slackwarearm-current/slackware/d/bison-3.0.4-arm-1.txz # Slackware ARM current - bison package.
ftp://ftp.arm.slackware.com/slackwarearm/slackwarearm-current/slackware/d/flex-2.6.0-arm-1.txz # Slackware ARM current - flex package.
http://arm.slackware.com/FAQs # Slackware ARM Linux Project Frequently Asked Questions.
http://wiki.osdev.org/GCC_Cross-Compiler # GCC cross-compiler documentation.
https://www.raspberrypi.org/documentation/linux/kernel # Raspberry Pi Linux kernel documentation.
https://www.github.com/raspberrypi/ # Raspberry Pi Foundation GitHub repository Linux kernel, bootloader/GPU firmware.
https://ftp.gnu.org/gnu/ # GCC, binutils, glibc, gmp, mpc, mpfr package source
ftp://gcc.gnu.org/pub/gcc/infrastructure # cloog, isl package source


En otros idiomas
Traducciones de esta página?:
QR Code
QR Code es:howtos:hardware:arm:gcc_aarch64_cross-compiler (generated for current page)