Welcome to the Slackware Documentation Project

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
howtos:hardware:arm:gcc_aarch64_cross-compiler [2016/12/17 16:57 (UTC)]
exaga corrections
howtos:hardware:arm:gcc_aarch64_cross-compiler [2017/08/23 16:56 (UTC)]
exaga [Slackware ARM GCC aarch64-linux cross-compiler for the Raspberry Pi]
Line 3: Line 3:
 === Preface === === Preface ===
  
-I was thinking about the Cortex-A53 64-bit CPU on my Raspberry Pi 3 and why I'm mainly using Slackware ARM 32 bit operating system on it. Then I started to wonder if it would be possible to build an arm64 kernel and modules to run with Slackware ARM. After reading about how this could be achieved it seemed clear that some cross-compiling would be required. Although I have some experience in building Linux kernels, especially for the Raspberry Pi platform, I'd never done any cross-compiling before a week ago. So, this whole concept was brand new to me.+I was thinking about the Cortex-A53 64-bit CPU on my Raspberry Pi 3 and why I'm mainly using Slackware ARM 32 bit operating system on it. Then I started to wonder if it would be possible to build an arm64 kernel and modules to run with Slackware ARM. After reading about how this could be achieved it seemed clear that some cross-compiling would be required. Although I have some experience in building Linux kernels, especially for the Raspberry Pi platform, I'd never done any cross-compiling before a week ago (2016-12-15). So, this whole concept was brand new to me.
  
-For my first attempt (and largely based on reading about how other users were doing it) I used an Ubuntu 16.04.1 LTS (64 bit) system to cross-compile an arm64 kernel for the Raspberry Pi 3. However, the results of doing things by this method were somewhat lacking and created many unforeseen errors. Then I remembered something [[http://​www.slackware.com/​~mozes/​|Mozes]] had published on [[http://arm.slackware.com/​FAQs]] about Slackware ARM packages being built natively. Further investigation lead me to realise that assured success would most likely be found by cross-compiling on an ARM device using Slackware ARM. So, that's exactly what I did! I used Slackware ARM current on a RPi3 to build a GCC aarch64-linux cross-compiler,​ and then used it to build the arm64 Linux kernel, modules, and device tree blob(s). ​Very successfully,​ might I add. Thanks again, Mozes. <3+For my first attempt (and largely based on reading about how other users were doing it) I used an Ubuntu 16.04.1 LTS (64 bit) system to cross-compile an arm64 kernel for the Raspberry Pi 3. However, the results of doing things by this method were somewhat lacking and created many unforeseen errors. Then I remembered something [[http://​www.slackware.com/​~mozes/​|Mozes]] had published on [[https://docs.slackware.com/​slackwarearm:​faq|his Slackware ARM FAQ page]] about packages being built natively. Further investigation lead me to realise that assured success would most likely be found by cross-compiling on an ARM device using Slackware ARM. So, that's exactly what I did! Very successfully,​ might I add. Thanks again, Mozes. <3
  
 As things have turned out, it wasn't //that// difficult. Investing some time into reading about toolchains and how to build cross-compilers was required, as well as testing the results of cross-compiling,​ but on the whole it's been a relatively simple process. Using Slackware ARM current to cross-compile aarch64 architecture was the key to success here. I'm now very aware that, in comparison, trying to cross-compile aarch64 on an Ubuntu x86_64 system was less than productive. ​ As things have turned out, it wasn't //that// difficult. Investing some time into reading about toolchains and how to build cross-compilers was required, as well as testing the results of cross-compiling,​ but on the whole it's been a relatively simple process. Using Slackware ARM current to cross-compile aarch64 architecture was the key to success here. I'm now very aware that, in comparison, trying to cross-compile aarch64 on an Ubuntu x86_64 system was less than productive. ​
Line 29: Line 29:
   * successfully boot Slackware ARM current on your Raspberry Pi 3 running an aarch64 (arm64) kernel.   * successfully boot Slackware ARM current on your Raspberry Pi 3 running an aarch64 (arm64) kernel.
  
-<​note ​important>In order not to risk messing up the Slackware ARM system which you use for cross-compiling,​ a (spare) microSD card containing a working Slackware ARM system should be used to install the arm64 Linux kernel, modules, and device tree blob(s). You'll need a recent (i.e. post-September 2016) version of the [[https://​github.com/​raspberrypi/​firmware|Raspberry Pi bootloader/​GPU firmware]] installed on this (spare) microSD card to avoid any problems. To be sure, boot your RPi3 with it and update the firmware. The Linux kernel version on this (spare) microSD card doesn'​t matter as you'll be replacing it with the aarch64 (arm64) kernel.</​note>​+<​note ​tip>In order not to risk messing up the Slackware ARM system which you use for cross-compiling,​ a (spare) microSD card containing a working Slackware ARM system should be used to install the arm64 Linux kernel, modules, and device tree blob(s). You'll need a recent (i.e. post-September 2016) version of the [[https://​github.com/​raspberrypi/​firmware|Raspberry Pi bootloader/​GPU firmware]] installed on this (spare) microSD card to avoid any problems. To be sure, boot your RPi3 with it and update the firmware. The Linux kernel version on this (spare) microSD card doesn'​t matter as you'll be replacing it with the aarch64 (arm64) kernel.</​note>​
  
 ==== Downloading required source and configuration ==== ==== Downloading required source and configuration ====
Line 37: Line 37:
 <​code>​ <​code>​
 cd /tmp cd /tmp
-mkdir build-gcc +mkdir build-dir 
-cd build-gcc+cd build-dir
 </​code>​ </​code>​
  
Line 64: Line 64:
 Before downloading the package source needed to build the GCC cross-compiler,​ be aware that more recent package versions may exist than the ones shown here. You may wish to install newer versions. It's always a good idea to check. To keep things simple, you might consider downloading a version of GCC which matches the one you currently have installed. I've read lots of articles about this and most advise to install the //latest and greatest// version of GCC available. However, if you're running Slackware ARM current you'll have gcc-5.4.0 installed and this is adequate for what you need. Before downloading the package source needed to build the GCC cross-compiler,​ be aware that more recent package versions may exist than the ones shown here. You may wish to install newer versions. It's always a good idea to check. To keep things simple, you might consider downloading a version of GCC which matches the one you currently have installed. I've read lots of articles about this and most advise to install the //latest and greatest// version of GCC available. However, if you're running Slackware ARM current you'll have gcc-5.4.0 installed and this is adequate for what you need.
  
-So, first move back into the '​build-gcc' directory and then download the packages below.+So, first move back into the '​build-dir' directory and then download the packages below.
  
 <​code>​ <​code>​
Line 115: Line 115:
  
 <​code>​ <​code>​
 +cd /tmp
 mkdir gcc-cross mkdir gcc-cross
 </​code>​ </​code>​
Line 132: Line 133:
 </​code>​ </​code>​
  
-You should see the first $PATH entry is to your installation directory'​s /bin folder.+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.
  
 <​code>​ <​code>​
Line 144: Line 145:
 === Building binutils === === Building binutils ===
  
-First move back up into the '​build-gcc' 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. +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. 
  
 <​code>​ <​code>​
-cd ../+cd build-dir
 mkdir build-binutils mkdir build-binutils
 cd build-binutils cd build-binutils
Line 166: Line 167:
 === Build GCC === === Build GCC ===
  
-First move into the '​build-gcc' 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++'​.+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++'​.
  
 <​code>​ <​code>​
Line 179: Line 180:
 === Build and install glibc === === Build and install glibc ===
  
-First move into the '​build-gcc' 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.+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.
  
 <​code>​ <​code>​
Line 259: Line 260:
 === Creating the arm64 kernel .config === === 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-gcc' folder. Then you need to create a kernel .config file, based on Raspberry Pi 3 hardware default ​parameters. This file holds the Linux kernel configuration for the arm64 kernel you are going to build. ​So, to achieve this run the following commands:+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:
  
 <​code>​ <​code>​
-cd /tmp/build-gcc/linux+cd /tmp/build-dir/linux
 make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux- bcmrpi3_defconfig make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux- bcmrpi3_defconfig
 </​code>​ </​code>​
Line 281: Line 282:
 === Building the arm64 device tree blob(s) === === 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 blob you will be building ​is '​**bcm2710-rpi-3-b.dtb**'​.+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: ​ To build the Raspberry Pi device tree blob(s) run the following command: ​
Line 303: Line 304:
 === Installing the arm64 modules === === Installing the arm64 modules ===
  
-Once the modules have been built, you have to 'make modules_install' ​which installs ​your kernel modules to '/​lib/​modules/​4.8.13-v8'​. You could build  //​out-of-tree//​ kernel modules but, to keep things ​easy and simple, you're going to install them on your current system. Again, you will use the same CFLAGS as before but without any '​LOCALVERSION'​ set.+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: First you need become '​**root**'​ user and enter a passwd when prompted. To install the aarch64 modules run the following commands:
Line 309: Line 312:
 <​code>​ <​code>​
 su - su -
-export PATH=/​tmp/​gcc-cross-compiler/​bin:​$PATH +make -j4 modules_install ARCH=arm64 CROSS_COMPILE=aarch64-linux-
-make -j 4 modules_install ARCH=arm64 CROSS_COMPILE=aarch64-linux-+
 </​code>​ </​code>​
  
Line 319: Line 321:
 <​code>​ <​code>​
 ls -lah arch/​arm64/​boot/​Image ​ ls -lah arch/​arm64/​boot/​Image ​
-la -lah arch/​arm64/​boot/​dts/​broadcom/​bcm2710-rpi-3-b.dtb+la -lah arch/​arm64/​boot/​dts/​broadcom/​bcm*-rpi-3-b.dtb
 ls -lah /​lib/​modules/​4.8.13-v8* ls -lah /​lib/​modules/​4.8.13-v8*
 </​code>​ </​code>​
Line 325: Line 327:
 If you can see that they all exist, then everything has worked as planned. If you can see that they all exist, then everything has worked as planned.
  
-==== Copying the arm64 kernel, modules, and device tree blob (DTB) ====+==== 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.  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. 
Line 374: Line 376:
 </​code>​ </​code>​
  
-The next thing to do is copy the arm64 kernel, modules, and device tree blob to your 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.+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: To copy these files, run the following commands, as '​**root**'​ user:
  
 <​code>​ <​code>​
-cp arch/​arm64/​boot/​Image ​/rpi-boot/​boot/​kernel8.img +cp build-dir/​linux/​arch/​arm64/​boot/​Image rpi-boot/​boot/​kernel8.img 
-cp arch/​arm64/​boot/​dts/​broadcom/​bcm2710-rpi-3-b.dtb ​/rpi-boot/​boot +cp build-dir/​linux/​arch/​arm64/​boot/​dts/​broadcom/​bcm*-rpi-3-b.dtb rpi-boot/​boot 
-cp -arv /​lib/​modules/​4.8.13-v8* ​/rpi-root/​lib/​modules/​+cp -rv /​lib/​modules/​4.8.13-v8* rpi-root/​lib/​modules/​
 </​code>​ </​code>​
  
Line 388: Line 390:
 <​code>​ <​code>​
 ls -lah rpi-boot/​boot/​kernel* ls -lah rpi-boot/​boot/​kernel*
-ls -lah rpi-boot/​boot/​bcm2710-rpi-3-b.dtb ​+ls -lah rpi-boot/​boot/​bcm*-rpi-3-b.dtb ​
 ls -lah rpi-root/​lib/​modules/​4.8.13-v8* ls -lah rpi-root/​lib/​modules/​4.8.13-v8*
 </​code>​ </​code>​
  
-If it all looks fine and dandy then the next thing you need to do is delete the existing ​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. +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. 
 <​code>​ <​code>​
 rm -rf rpi-boot/​kernel7.img ​ rm -rf rpi-boot/​kernel7.img ​
 </​code>​ </​code>​
  
-No changes to the config.txt or cmdline.txt file(s) should be necessary. If you are using a recent blootloader/​GPU firmware (i.e. post-September 2016) then nothing else needs to be changed or deleted.+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. Now you can unmount the previously mounted directories.
Line 413: Line 415:
 </​code>​ </​code>​
  
-Remove the USB microSD card reader and swap microSD cards. Power on the Raspberry Pi.+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: 
 + 
 +<​code>​ 
 +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:​~#​ 
 +</​code>​ 
 + 
 +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
  
 ====== Sources ====== ====== Sources ======

In Other Languages
QR Code
QR Code howtos:hardware:arm:gcc_aarch64_cross-compiler (generated for current page)