Raspberry Pi Kernel Compilation

= Overview = 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. = From the Raspberry pi =

Firmware
Install git first, as below in Kernel compilation. cd /opt git clone --depth 1 git://github.com/raspberrypi/firmware.git cd firmware/boot cp arm128_start.elf arm192_start.elf arm224_start.elf bootcode.bin loader.bin start.elf /boot/ cd /opt rm -r firmware

Debian pre-build
apt-get update apt-get -y dist-upgrade apt-get -y install git gcc make tmux

Arch Linux pre-build
pacman -Syu pacman -S git gcc make tmux

Common
cd /opt mkdir raspberrypi cd raspberrypi git clone --depth 1 git://github.com/raspberrypi/linux.git cd linux zcat /proc/config.gz > .config tmux new -s make nice make; nice make modules [Ctrl]+[B],[D] tmux a -t m [Ctrl]+[D] cp arch/arm/boot/Image /boot/kernel.img make ARCH=arm modules_install INSTALL_MOD_PATH=/ cd /opt rm -r raspberrypi shutdown -r now;
 * 1) optional#make menuconfig # i.e. if you want to alter the configuration. You'll need to first run # apt-get install libncurses5-dev
 * 1) … 5 to 11 hours later…

= From a foreign machine =

Firmware
cd /opt git clone git://github.com/raspberrypi/firmware.git cd firmware/boot scp arm128_start.elf arm192_start.elf arm224_start.elf bootcode.bin loader.bin start.elf @ :/boot/ After the first time: cd /opt/firmware git pull cd boot scp arm128_start.elf arm192_start.elf arm224_start.elf bootcode.bin loader.bin start.elf @ :/boot/

Kernel cross compilation
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. Also if your trying to rebuild an existing kernel, the proper .config file can be obtained from the raspberry pi using zcat /proc/config.gz > .config

Ubuntu
apt-get install git gcc-arm-linux-gnueabi make ncurses-dev cd /opt mkdir raspberrypi cd raspberrypi git clone git://github.com/raspberrypi/linux.git cd linux cp arch/arm/configs/bcmrpi_cutdown_defconfig .config make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k
 * 1) optional#make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig

Gentoo Linux
crossdev -S -v -t arm-unknown-linux-gnueabi mkdir raspberrypi cd raspberrypi git clone git://github.com/raspberrypi/linux.git cd linux cp arch/arm/configs/bcmrpi_cutdown_defconfig .config make ARCH=arm CROSS_COMPILE=/usr/bin/arm-unknown-linux-gnueabi- oldconfig make ARCH=arm CROSS_COMPILE=/usr/bin/arm-unknown-linux-gnueabi- -k
 * 1) optional#make ARCH=arm CROSS_COMPILE=/usr/bin/arm-unknown-linux-gnueabi- menuconfig

crossdev 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.

On 2012-05-06, cross -S -v -A gnueabi arm works just fine

Arch Linux
pacman -S git yaourt -S arm-linux-gnueabi-gcc cd /opt mkdir raspberrypi cd raspberrypi git clone git://github.com/raspberrypi/linux.git cd linux cp arch/arm/configs/bcmrpi_cutdown_defconfig .config make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- oldconfig make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k
 * 1) optional#make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig

OS X
The Kernel source requires a case-sensitive filesystem. If you do not have a HFS+ Case-sensitive partition that can be used, create a disk image with the appropriate format. Ensure latest Xcode and command line tools are installed from Apple Developer Connection

Macports
Install macports port install arm-none-eabi-gcc port install arm-none-eabi-binutils cd /opt mkdir raspberrypi cd raspberrypi git clone git://github.com/raspberrypi/linux.git cd linux cp arch/arm/configs/bcmrpi_cutdown_defconfig .config make ARCH=arm CROSS_COMPILE=/opt/local/bin/arm-none-eabi- oldconfig make ARCH=arm CROSS_COMPILE=/opt/local/bin/arm-none-eabi- -k If you get an error message that elf.h is missing sudo port install libelf && sudo ln -s /opt/local/include/libelf /usr/include/libelf From opensource.apple.com, download and copy elf.h and elftypes.h to /usr/include

Edit elf.h and add If you get a "SEGMENT_SIZE is undeclared" error open the Makefile and change the line: NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) to NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) -Dlinux
 * 1) define R_386_NONE       0
 * 2) define R_386_32         1
 * 3) define R_386_PC32       2
 * 4) define R_ARM_NONE       0
 * 5) define R_ARM_PC24       1
 * 6) define R_ARM_ABS32      2
 * 7) define R_MIPS_NONE      0
 * 8) define R_MIPS_16        1
 * 9) define R_MIPS_32        2
 * 10) define R_MIPS_REL32     3
 * 11) define R_MIPS_26        4
 * 12) define R_MIPS_HI16      5
 * 13) define R_MIPS_LO16      6

Yagarto
Downoad and install an GNU ARM toolchain such as yagarto. cd /opt mkdir raspberrypi cd raspberrypi git clone git://github.com/raspberrypi/linux.git cd linux cp arch/arm/configs/bcmrpi_cutdown_defconfig .config make ARCH=arm CROSS_COMPILE=/path/to/yagarto/bin/arm-none-eabi- oldconfig make ARCH=arm CROSS_COMPILE=/path/to/yagarto/bin/arm-none-eabi- -k

Transferring The Build
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.

Boot your RaspberryPi and mount the  directory over the network using sshfs: cd /mnt mkdir linux sshfs @ : linux cd linux make modules_install If you got "Permission denied" when doing, try: sudo sh -c "cd linux ; make modules_install" If that is not an option, you can also install the modules into a temporary folder: mkdir /tmp/modules make ARCH=arm modules_install INSTALL_MOD_PATH=/tmp/modules Now you have to copy the contents of that directory to /lib/modules on the SD card. scp linux/arch/arm/boot/Image @ :/boot/kernel.img scp -r /tmp/modules/* @ ://lib/modules/ Once you've done those two steps, you are ready to put the SD card in and try booting your new system!

Note: if /tmp/modules contains symlinks they will be followed and if they are recursive this is a problem. A safer way to copy is to use tar: cd /tmp/modules/lib/modules; tar cJf - * | ssh @ '(cd /lib/modules; tar xJf -)'

=References=