https://elinux.org/api.php?action=feedcontributions&user=MatthewEveritt&feedformat=atomeLinux.org - User contributions [en]2024-03-28T17:11:50ZUser contributionsMediaWiki 1.31.0https://elinux.org/index.php?title=Raspberry_Pi_Kernel_Compilation&diff=138512Raspberry Pi Kernel Compilation2012-06-08T22:28:23Z<p>MatthewEveritt: </p>
<hr />
<div>{{Template:RPi_Software}}<br />
<br />
<br />
= Overview =<br />
<br />
First, you are going to get and build the linux kernel and its modules using a suitable compiler (a "cross-compiler" if you aren't building it on the same hardware you will be running it on) and then you are going to create a kernel image from the uncompressed kernel (Image) to place on the sd, along with the modules you build alongside it.<br />
<br />
See below for the various guides to get and compile a suitable kernel for your RPi, and then create a kernel.img according to the steps at the end.<br />
<br />
= Raspberry PI kernel compilation =<br />
<br />
You can compile the kernel on the board itself, but because of the limited resources it will take a lot of time. Alternatively you can crosscompile the kernel on another machine running Linux, Windows or OS X.<br />
<br />
== Compiling on the Raspberry pi itself ==<br />
<br />
=== Arch Linux ===<br />
<br />
==== getting the compiler ====<br />
You will need GIT to clone the kernel source tree from GitHub, compiler (gcc) and GNU Make:<br />
pacman -S git gcc make<br />
<br />
(NOTE: git might be omitted if you decide to download sources in compressed format; this is far faster)<br />
<br />
==== getting the sources ====<br />
<br />
create a directory where you can work on the raspberry pi software. I called mine "raspberrypi". Then clone the git repository. <br />
<br />
mkdir raspberrypi<br />
cd raspberrypi <br />
git clone https://github.com/raspberrypi/linux.git<br />
(NOTE: git might fail due to memory constraints; in this case creation of swap file might help. Be warned - this takes ages! To omit the revision history and reduce the download, you can add "--depth 1" to the end of the git clone command.)<br />
<br />
Alternatively, download ZIP or TAR.GZ version of the sources from:<br />
https://github.com/raspberrypi/linux/downloads <br />
unpack and enter the extracted directory (this is your kernel directory - its sources to be precise)<br />
<br />
==== configuring the kernel ====<br />
Next, the kernel options are configured. Either copy the cut down Raspberry Pi .config file from the kernel source configs directory:<br />
cp arch/arm/configs/bcmrpi_cutdown_defconfig .config<br />
<br />
Or alternatively, to use the configuration from a currently running Raspberry Pi image, connect to the target and extract the .config file. Then copy the resultant .config file into the Linux kernel source root directory:<br />
zcat /proc/config.gz > .config<br />
cp .config <path to linux source root directory><br />
<br />
If needed - manual/additional configuration:<br />
make menuconfig<br />
<br />
==== compile the kernel ====<br />
make<br />
<br />
(NOTE: this will take around 6h; You might find GNU Screen useful)<br />
<br />
==== build kernel.img so your RPi can boot from it ====<br />
<br />
Finally you need to build a kernel.img for your Pi to boot from. For this, you need the mkimage tool from the raspberrypi github repository:<br />
<br />
git clone https://github.com/raspberrypi/tools<br />
<br />
Alternatively, download 'imagetool-uncompressed.py' and its dependencies from (this takes far less time and resources):<br />
https://github.com/raspberrypi/tools/tree/master/mkimage<br />
<br />
Before you can use this script you need Python v2 to be installed:<br />
pacman -S python2<br />
<br />
Once all above is set up you should have the following files (checklist):<br />
* in the kernel folder you compiled a file: linux/arch/arm/boot/Image<br />
* python2 executable (it should be located by default in /usr/bin/python2)<br />
* imagetool-uncompressed.py script<br />
<br />
<br />
If this is a case (you have all the above) convert your kernel image with the script:<br />
<br />
python2 imagetool-uncompressed.py path/to/linux/arch/arm/boot/Image<br />
<br />
This will create a file called kernel.img. Transfer this file into /boot directory (make sure the existing kernel.img in /boot directory gets replaced).<br />
<br />
The last thing is to install kernel modules. To do this navigate to your kernel folder and execute:<br />
make modules_install<br />
<br />
This will install all compiled modules into /lib/modules and possibly some additional files into /lib/firmware folders.<br />
<br />
Reboot your RPi and pray :)<br />
reboot <br />
<br />
TODO: verify & consolidate<br />
<br />
== Cross compiling on a foreign machine==<br />
<br />
=== Ubuntu Linux ===<br />
<br />
==== getting the compiler ====<br />
<br />
On Ubuntu Oneiric getting the arm cross compiler can be as easy as: <br />
<br />
sudo apt-get install gcc-4.6-arm-linux-gnueabi<br />
sudo apt-get install git-core #jhauser14905 -- might as well state the obvious, you need git installed! -- it's git-core on ubuntu. --REW<br />
sudo apt-get install ncurses-dev #MatthewEveritt -- Had to install this to use menuconfig.<br />
<br />
<br />
(TODO: Is this the right one? More packages required? I did this a while ago! TODO: Other distributions?)<br />
<br />
==== getting the sources ====<br />
<br />
create a directory where you can work on the raspberry pi software. I called mine "raspberrypi". Then clone the git repository. <br />
<br />
mkdir raspberrypi<br />
cd raspberrypi <br />
git clone https://github.com/raspberrypi/linux.git<br />
cd linux<br />
<br />
jhauser14905: on 2012-01-28, with all package updates applied, i had to add the following symlink in order to get the make commands to work. otherwise they would error out<br />
<br />
sudo ln -s /usr/bin/arm-linux-gnueabi-gcc-4.6 /usr/bin/arm-linux-gnueabi-gcc<br />
<br />
==== compiling ====<br />
<br />
Next, the kernel options are configured. Either copy the cut down Raspberry Pi .config file from the kernel source configs directory:<br />
cp arch/arm/configs/bcmrpi_cutdown_defconfig .config<br />
<br />
Or alternatively, to use the configuration from a currently running Raspberry Pi image, connect to the target and extract the .config file. Then copy the resultant .config file into the Linux kernel source root directory:<br />
zcat /proc/config.gz > .config<br />
cp .config <path to linux source root directory><br />
<br />
Configure the kernel with the copied .config file by running oldconfig:<br />
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig<br />
<br />
If manual/additional configuration of kernel options are needed run menuconfig:<br />
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig<br />
<br />
Then build the kernel:<br />
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k<br />
<br />
You can use the "-j" flag to improve compilation time. If you have a dual core machine you can use "-j 3", for a quad core machine you can use "-j 6", and so on.<br />
<br />
If you get the error messages that arm-linux-gnueabi-gcc cannot be found when running make, run the following command:<br />
<br />
sudo ln -s /usr/bin/arm-linux-gnueabi-gcc-4.6 /usr/bin/arm-linux-gnueabi-gcc<br />
<br />
this creates a symbolic link to the 4.6 gcc binary<br />
<br />
=== Gentoo Linux ===<br />
<br />
==== getting the compiler ====<br />
<br />
Build the cross toolchain:<br />
crossdev -S -v -t arm-unknown-linux-gnueabi<br />
<br />
theBuell: on 2012-05-06, cross -S -v -A gnueabi arm works just fine<br />
<br />
This command should create a cross-toolchain using the latest stable versions of the required packages. If it fails, you can specify exact versions by removing the "-S" flag and adding the "--b", "--g", "--k" and "--l" flags. For the exact usage refer to the crossdev manpage. A good starting point for figuring out the right versions are those which are stable for the arm architecture.<br />
<br />
==== getting the sources ====<br />
<br />
create a directory where you can work on the raspberry pi software. I called mine "raspberrypi". Then clone the git repository. <br />
<br />
mkdir raspberrypi<br />
cd raspberrypi <br />
git clone https://github.com/raspberrypi/linux.git<br />
cd linux<br />
<br />
==== compiling ====<br />
<br />
Next you have to configure the kernel:<br />
cp arch/arm/configs/bcmrpi_cutdown_defconfig .config<br />
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig<br />
<br />
Then building the kernel:<br />
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k<br />
<br />
You can use the "-j" flag to improve compilation time. If you have a dual core machine you can use "-j 3", for a quad core machine you can use "-j 6", and so on.<br />
<br />
=== Arch Linux ===<br />
<br />
==== getting the compiler ====<br />
You will need GIT to clone the kernel source tree from GitHub:<br />
pacman -S git<br />
<br />
Build the cross toolchain:<br />
arm-linux-gnueabi-gcc is on the AUR. If you use yaourt:<br />
<br />
yaourt -S arm-linux-gnueabi-gcc<br />
<br />
Yaourt is recommended as it will build all dependencies.<br />
<br />
==== getting the sources ====<br />
<br />
create a directory where you can work on the raspberry pi software. I called mine "raspberrypi". Then clone the git repository. <br />
<br />
mkdir raspberrypi<br />
cd raspberrypi <br />
git clone https://github.com/raspberrypi/linux.git<br />
cd linux<br />
<br />
==== compiling ====<br />
<br />
Next you have to configure the kernel:<br />
cp arch/arm/configs/bcmrpi_cutdown_defconfig .config<br />
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig<br />
<br />
Then building the kernel:<br />
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k<br />
<br />
You can use the "-j" flag to improve compilation time. If you have a dual core machine you can use "-j 3", for a quad core machine you can use "-j 6", and so on.<br />
<br />
=== Windows ===<br />
<br />
TODO<br />
<br />
=== OS X ===<br />
<br />
==== getting the compiler ====<br />
Ensure latest Xcode and command line tools are installed from [http://developer.apple.com/downloads Apple Developer Connection] then<br />
Downoad and install an GNU ARM toolchain such as [http://www.yagarto.de/#downloadmac yagarto]<br />
<br />
Another option is the MacPorts arm-none-eabi-*:<br />
<br />
port install arm-none-eabi-binutils<br />
<br />
==== getting the sources ====<br />
<br />
create a directory where you can work on the raspberry pi software. I called mine "raspberrypi". Then clone the git repository. <br />
<br />
mkdir raspberrypi<br />
cd raspberrypi <br />
git clone https://github.com/raspberrypi/linux.git<br />
cd linux<br />
<br />
==== compiling ====<br />
<br />
Next you have to configure the kernel: (the running kernel config can be found in <code>/proc/config.gz</code> on your RPi)<br />
cp arch/arm/configs/bcmrpi_cutdown_defconfig .config<br />
make ARCH=arm CROSS_COMPILE=/path/to/yagarto/bin/arm-none-eabi- oldconfig<br />
<br />
or if you used the MacPorts<br />
make ARCH=arm CROSS_COMPILE=/opt/local/bin/arm-none-eabi- oldconfig<br />
<br />
Then building the kernel:<br />
make ARCH=arm CROSS_COMPILE=/path/to/yagarto/bin/arm-none-eabi- -k<br />
<br />
or if you used the MacPorts<br />
make ARCH=arm CROSS_COMPILE=/opt/local/bin/arm-none-eabi- -k<br />
<br />
You can use the "-j" flag to improve compilation time. If you have a dual core machine you can use "-j 3", for a quad core machine you can use "-j 6", and so on. (Don't use these for the oldconfig option because it messes up the input and output).<br />
<br />
'''If you get an error message that elf.h is missing'''<br />
<br />
install [http://guide.macports.org/#installing macports]<br />
install libelf and symlink to /usr/libelf:<br />
sudo port install libelf && sudo ln -s /opt/local/include/libelf /usr/include/libelf<br />
copy [http://opensource.apple.com/source/dtrace/dtrace-48/sys/elf.h?txt elf.h] and [http://opensource.apple.com/source/dtrace/dtrace-48/sys/elftypes.h?txt elftypes.h] to /usr/include<br />
<br />
Edit elf.h and add<br />
#define R_386_NONE 0<br />
#define R_386_32 1<br />
#define R_386_PC32 2<br />
#define R_ARM_NONE 0<br />
#define R_ARM_PC24 1<br />
#define R_ARM_ABS32 2<br />
#define R_MIPS_NONE 0<br />
#define R_MIPS_16 1<br />
#define R_MIPS_32 2<br />
#define R_MIPS_REL32 3<br />
#define R_MIPS_26 4<br />
#define R_MIPS_HI16 5<br />
#define R_MIPS_LO16 6<br />
<br />
= Final step: Making the 'kernel.img' for your Pi =<br />
<br />
Finally you need to build a kernel.img for your Pi to boot from. The next two sections describe how to do this, depending on which firmware/bootloader version you're using.<br />
<br />
== Image Generation For Latest Firmware ==<br />
<br />
With the latest firmware (available from https://github.com/raspberrypi/firmware), you no longer need to create an explicit kernel image; you can directly use Image or zImage from the kernel build process as /boot/kernel.img.<br />
<br />
== Image Generation For Older Firmware ==<br />
<br />
For this, you need the mkimage tool from the raspberrypi github repository:<br />
<br />
git clone https://github.com/raspberrypi/tools<br />
<br />
In tools/mkimage, you'll find a python script called 'imagetool-uncompressed.py':<br />
<br />
usage : imagetool-uncompressed.py <kernel image><br />
<br />
After building your linux kernel, you'll find the kernel image you require in 'arch/arm/boot/Image' of the linux directory. Convert your kernel image with the script:<br />
<br />
python imagetool-uncompressed.py path/to/linux/arch/arm/boot/Image<br />
<br />
= Transferring The Image To The Raspberry Pi =<br />
<br />
Then you have to transfer this img file to the /boot directory and install the compiled modules. Unfortunately the compiled modules are not in a single place, there are two options of installing them.<br />
<br />
Boot your RaspberryPi and mount the <code>linux</code> directory over the network using sshfs:<br />
cd /mnt<br />
mkdir linux<br />
sshfs <user>@<host>:<path/to/linux> linux<br />
cd linux<br />
make modules_install<br />
<br />
If that is not an option, you can also install the modules into a temporary folder:<br />
mkdir /tmp/modules<br />
make ARCH=arm modules_install INSTALL_MOD_PATH=/tmp/modules<br />
<br />
Now you have to copy the contents of that directory to /lib/modules on the SD card.<br />
<br />
Once you've done those two steps, you are ready to put the SD card in and try booting your new system!<br />
<br />
{{Template:Raspberry Pi}}<br />
[[Category: RaspberryPi]]</div>MatthewEveritt