Difference between revisions of "RPi Upstream Kernel Compilation"

From eLinux.org
Jump to: navigation, search
(Detailed build instructions)
Line 1: Line 1:
 +
{{Template:RPi_Software}}
 +
 +
== Building an Upstream Kernel for you Raspberry Pi ==
 +
 +
'''First word of advice:''' Have you visited the [[RPi_Kernel_Compilation]] page? If you did not, read at least the Roadmap section.
 +
 
This page describes how to compile an upstream or mainline kernel for the Raspberry Pi. It is mainly useful for upstream kernel maintainers/developers, or distribution kernel package maintainers.
 
This page describes how to compile an upstream or mainline kernel for the Raspberry Pi. It is mainly useful for upstream kernel maintainers/developers, or distribution kernel package maintainers.
  
Line 5: Line 11:
 
This page is kept deliberately terse, so as not to duplicate [[RPi_Kernel_Compilation]], which describes how to compile the Raspberry Pi Foundation's downstream kernel. Read that page for some background if this page doesn't make sense to you.
 
This page is kept deliberately terse, so as not to duplicate [[RPi_Kernel_Compilation]], which describes how to compile the Raspberry Pi Foundation's downstream kernel. Read that page for some background if this page doesn't make sense to you.
  
Get the mainline source:
+
As a quickstart, this procedure will build a monolithic kernel, without modules, and good for a start. Build a sucessful image first, and then start your adventures with your crafted kernel.
 +
 
 +
=== Preparing the environment ===
 +
First of all, get the toolchain for cross compile your kernel:
 +
 
 +
$ cd /usr/src
 +
$ git clone git://github.com/raspberrypi/tools.git --depth=1
 +
 
 +
Also, fetch Steven Warren's u-boot branch (we will need it, because the default bootloader won't be of help):
 +
 
 +
$ git clone git://github.com/swarren/u-boot.git --depth=1
 +
 
 +
And now, get the mainline source:
 +
 
 +
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --depth=1
 +
 
 +
Define the following environment variable:
 +
 
 +
$ export KERNEL_SRC=/usr/src/linux ; export CCPREFIX=/usr/src/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
 +
 
 +
=== Building your kernel ===
 +
'''A word of advice''': Don't forget to prefix the make commands with the <tt>ARCH</tt> and <tt>CROSS_COMPILE</tt> prefixes. If you forget to use it and start a make command, it will probably result on a build failure. If you forgot and ran a make, do a make clean and start over.
 +
And now, let's prepare the Linux build recipe:
 +
 
 +
$ cd linux
 +
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make bcm2835_defconfig
 +
 
 +
If you are building a Linux version which does not contains [http://lists.infradead.org/pipermail/linux-rpi-kernel/2014-September/000960.html this patch] (which is true at least up to 3.17), then you will have to manually select the USB controller, otherwise the USB ports (and networking!) will not work. Here is how to fix it. Enter the menuconfig
 +
 
 +
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make menuconfig
 +
 
 +
And then navigate to <tt>Device Drivers  --->  USB support  ---> DesignWare USB2 DRD Core Support</tt> and check both <tt>Host only mode</tt> '''and''' <tt>DWC2 Platform</tt>.
 +
 
 +
Leave the menuconfig, save the new <tt>.config</tt> and then build the kernel:
 +
 
 +
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make -j 8
 +
 
 +
Your build was sucessful? Great. Leve it alone for a while.
 +
 
 +
=== Building your bootloader ===
 +
As of 20140918, a upstream kernel image can't be booted using the default bootloader. And that's why we need the Steven Warren's das u-Boot. Let's build it:
 +
 
 +
$ cd ../u-boot
 +
$ git checkout -b rpi_dev origin/rpi_dev
 +
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make rpi_b_config
 +
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make -j 8
 +
 
 +
Right, leave it alone. And now, let's setup the cmdline boot.
 +
 
 +
$ cd tools
 +
 
 +
And create the file <tt>boot.scr</tt> with the following content:
 +
 
 +
mmc dev 0
 +
fatload mmc 0:1 ${kernel_addr_r} zImage
 +
fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}
 +
setenv fdtfile bcm2835-rpi-b.dtb
 +
setenv bootargs earlyprintk console=tty0 console=ttyAMA0 root=/dev/mmcblk0p2 rootwait
 +
bootz ${kernel_addr_r} - ${fdt_addr_r}
 +
 
 +
'''Pro tip:''' I've found that u-boot doesn't play nicely with long cmdlines. Avoid cluttering it. Otherwise it will print a quick setenv failure and your boot will fail.
 +
 
 +
And now, compile your cmdline:
 +
 
 +
$ ./mkimage -A arm -O linux -T script -C none -n boot.scr -d boot.scr boot.scr.uimg
 +
 
 +
=== Putting it all together ===
 +
And now, it's time to set up your SD card. This procedure assumes that your SD card is at <tt>/media/boot</tt>.
 +
 
 +
First, move your current SD card to a backup directory:
  
  git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+
  $ export SD=/media/boot
cd linux
+
$ mkdir $SD/backup
 +
$ mv $SD/* $SD/backup
  
Compile:
+
That's right, keep it empty. And now, let's populate with the fresh stuff.
  
export CROSS_COMPILE=/path/to/cross_compiler-
+
Fetch a new firmware set from https://github.com/raspberrypi/firmware/tree/master/boot and save it to your <tt>$SD</tt>
make ARCH=arm bcm2835_defconfig
 
make -s ARCH=arm zImage -j8 -s && make -s ARCH=arm dtbs
 
  
Copy to SD card: Copy <tt>arch/arm/boot/zImage</tt> (renamed to <tt>kernel.img</tt>) and <tt>arch/arm/boot/dts/bcm2835-rpi-b.dtb</tt>.
+
And finally:
  
The file <tt>config.txt</tt> is not needed when using U-Boot. I suggest deleting it, or rather, renaming it to disable it, but still keep it around if you need to go back.
+
$ cd /usr/src
 +
$ cp u-boot/u-boot.bin $SD/kernel.img
 +
$ cp kernel/arch/arm/boot/zImage kernel/arch/arm/boot/dts/bcm2835-rpi-b.dtb u-boot/tools/boot.scr.uimg $SD
  
You'll likely want to use upstream U-Boot to boot the upstream kernel. See [[RPi_U-Boot]]. U-Boot has known-working support for Device Tree. I'm not sure what state the binary firmware has for DT.
+
And you are done. Good luck!
  
 
{{Template:Raspberry Pi}}
 
{{Template:Raspberry Pi}}
 
[[Category:RaspberryPi]]
 
[[Category:RaspberryPi]]
 
[[Category:Linux-kernel]]
 
[[Category:Linux-kernel]]

Revision as of 08:27, 18 September 2014

Back to the Hub.


Software & Distributions:

Software - an overview.

Distributions - operating systems and development environments for the Raspberry Pi.

Kernel Compilation - advice on compiling a kernel.

Performance - measures of the Raspberry Pi's performance.

Programming - programming languages that might be used on the Raspberry Pi.

Building an Upstream Kernel for you Raspberry Pi

First word of advice: Have you visited the RPi_Kernel_Compilation page? If you did not, read at least the Roadmap section.

This page describes how to compile an upstream or mainline kernel for the Raspberry Pi. It is mainly useful for upstream kernel maintainers/developers, or distribution kernel package maintainers.

As of 20140211, all of UART (serial), SD card, HDMI (via simple-framebuffer), and USB should work. Not all SD cards will work (it may depend on the transfer modes the card supports, and timing tolerances). Not all USB devices will work (it may depend on the type of transfer, interrupt/control/bulk, the device uses, etc.)

This page is kept deliberately terse, so as not to duplicate RPi_Kernel_Compilation, which describes how to compile the Raspberry Pi Foundation's downstream kernel. Read that page for some background if this page doesn't make sense to you.

As a quickstart, this procedure will build a monolithic kernel, without modules, and good for a start. Build a sucessful image first, and then start your adventures with your crafted kernel.

Preparing the environment

First of all, get the toolchain for cross compile your kernel:

$ cd /usr/src
$ git clone git://github.com/raspberrypi/tools.git --depth=1

Also, fetch Steven Warren's u-boot branch (we will need it, because the default bootloader won't be of help):

$ git clone git://github.com/swarren/u-boot.git --depth=1

And now, get the mainline source:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git --depth=1

Define the following environment variable:

$ export KERNEL_SRC=/usr/src/linux ; export CCPREFIX=/usr/src/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-

Building your kernel

A word of advice: Don't forget to prefix the make commands with the ARCH and CROSS_COMPILE prefixes. If you forget to use it and start a make command, it will probably result on a build failure. If you forgot and ran a make, do a make clean and start over. And now, let's prepare the Linux build recipe:

$ cd linux
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make bcm2835_defconfig

If you are building a Linux version which does not contains this patch (which is true at least up to 3.17), then you will have to manually select the USB controller, otherwise the USB ports (and networking!) will not work. Here is how to fix it. Enter the menuconfig

$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make menuconfig

And then navigate to Device Drivers ---> USB support ---> DesignWare USB2 DRD Core Support and check both Host only mode and DWC2 Platform.

Leave the menuconfig, save the new .config and then build the kernel:

$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make -j 8

Your build was sucessful? Great. Leve it alone for a while.

Building your bootloader

As of 20140918, a upstream kernel image can't be booted using the default bootloader. And that's why we need the Steven Warren's das u-Boot. Let's build it:

$ cd ../u-boot
$ git checkout -b rpi_dev origin/rpi_dev
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make rpi_b_config
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make -j 8

Right, leave it alone. And now, let's setup the cmdline boot.

$ cd tools

And create the file boot.scr with the following content:

mmc dev 0
fatload mmc 0:1 ${kernel_addr_r} zImage
fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}
setenv fdtfile bcm2835-rpi-b.dtb
setenv bootargs earlyprintk console=tty0 console=ttyAMA0 root=/dev/mmcblk0p2 rootwait
bootz ${kernel_addr_r} - ${fdt_addr_r}

Pro tip: I've found that u-boot doesn't play nicely with long cmdlines. Avoid cluttering it. Otherwise it will print a quick setenv failure and your boot will fail.

And now, compile your cmdline:

$ ./mkimage -A arm -O linux -T script -C none -n boot.scr -d boot.scr boot.scr.uimg

Putting it all together

And now, it's time to set up your SD card. This procedure assumes that your SD card is at /media/boot.

First, move your current SD card to a backup directory:

$ export SD=/media/boot
$ mkdir $SD/backup
$ mv $SD/* $SD/backup

That's right, keep it empty. And now, let's populate with the fresh stuff.

Fetch a new firmware set from https://github.com/raspberrypi/firmware/tree/master/boot and save it to your $SD

And finally:

$ cd /usr/src
$ cp u-boot/u-boot.bin $SD/kernel.img
$ cp kernel/arch/arm/boot/zImage kernel/arch/arm/boot/dts/bcm2835-rpi-b.dtb u-boot/tools/boot.scr.uimg $SD

And you are done. Good luck!