Difference between revisions of "RPi Upstream Kernel Compilation"

From eLinux.org
Jump to: navigation, search
(Moving all of the "Upstreaming Kernel Compilation" info to the page of the same name.)
(Use mainline U-Boot not swarren's personal unstable work-in-progress branch. Mainline U-Boot has supported the Pi for eons now, and is stable.)
 
(8 intermediate revisions by 3 users not shown)
Line 3: Line 3:
 
== Building an Upstream Kernel for you 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.
+
'''First word of advice:''' Have you visited the [[RPi_Kernel_Compilation]] page? If you did not, read at least the Checklist/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.
  
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.)
+
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), though a standard one will work nicely. Not all USB devices will work (it may depend on the type of transfer, kernel support, interrupt/control/bulk, the device uses, etc.), though the bulk of general use (Wifi, network, storage) will work nicely.
  
If something in this page doesn't make sense to you, pay a visit to [[RPi_Kernel_Compilation]], [[RPi_Upstream_Kernel_Compilation]] and [[RPi_U-Boot]] articles.
+
If something in this page doesn't make sense to you, pay a visit to [[RPi_Kernel_Compilation]] and [[RPi_U-Boot]] articles.
  
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.
+
As a quickstart, this procedure will build a monolithic kernel, without modules, and good for a start. Build a successful image first, and then start your adventures with your crafted kernel.
  
 
=== Preparing the environment ===
 
=== Preparing the environment ===
Line 19: Line 19:
 
  $ git clone git://github.com/raspberrypi/tools.git --depth=1
 
  $ git clone git://github.com/raspberrypi/tools.git --depth=1
  
Also, fetch Stephen Warren's u-boot branch (we will need it, because the default bootloader won't be of help):
+
Also, fetch mainline U-Boot (we will need it, because the default bootloader won't be of help):
  
  $ git clone git://github.com/swarren/u-boot.git --depth=1
+
  $ git clone git://git.denx.de/u-boot.git --depth=1
  
 
And now, get the mainline source:
 
And now, get the mainline source:
Line 29: Line 29:
 
Define the following environment variable:
 
Define the following environment variable:
  
  $ export KERNEL_SRC=/usr/src/linux-3.17-rc5
+
  $ export KERNEL_SRC=/usr/src/linux
 
  $ export CCPREFIX=/usr/src/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-
 
  $ export CCPREFIX=/usr/src/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-
 
  $ export MODULES_TEMP=/usr/src/modules
 
  $ export MODULES_TEMP=/usr/src/modules
  
 
=== Building your kernel ===
 
=== Building your kernel ===
'''Pro tip:''' 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.
+
'''Pro tip:''' 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 <tt>make clean</tt> and start over.
 
And now, let's prepare the Linux build recipe:
 
And now, let's prepare the Linux build recipe:
  
Line 48: Line 48:
 
Leave the menuconfig, save the new <tt>.config</tt> and then build the kernel:
 
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
+
  $ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make -j `grep -c ^processor /proc/cpuinfo`
  
 
Your build was sucessful? Great. Leve it alone for a while.
 
Your build was sucessful? Great. Leve it alone for a while.
Line 56: Line 56:
  
 
  $ cd ../u-boot
 
  $ cd ../u-boot
  $ git checkout -b rpi_dev origin/rpi_dev
+
# If you have a Raspberry Pi 0 or 1:
  $ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make rpi_b_config
+
  $ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make rpi_config
  $ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make -j 8
+
# If you have a Raspberry Pi 2:
 +
  $ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make rpi_2_config
 +
  $ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make -j `grep -c ^processor /proc/cpuinfo`
  
 
Right, leave it alone. And now, let's setup the cmdline boot.
 
Right, leave it alone. And now, let's setup the cmdline boot.
Line 64: Line 66:
 
  $ cd tools
 
  $ cd tools
  
And create the file <tt>boot.scr</tt> with the following content:
+
And create the file <tt>boot.scr</tt> with the following content for Model B:
  
 
  mmc dev 0
 
  mmc dev 0
 +
setenv fdtfile bcm2835-rpi-b.dtb
 +
setenv bootargs earlyprintk console=tty0 console=ttyAMA0 root=/dev/mmcblk0p2 rootwait
 
  fatload mmc 0:1 ${kernel_addr_r} zImage
 
  fatload mmc 0:1 ${kernel_addr_r} zImage
 
  fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}
 
  fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}
  setenv fdtfile bcm2835-rpi-b.dtb
+
bootz ${kernel_addr_r} - ${fdt_addr_r}
 +
 
 +
Use the following for Model B+
 +
 
 +
mmc dev 0
 +
  setenv fdtfile bcm2835-rpi-b-plus.dtb
 
  setenv bootargs earlyprintk console=tty0 console=ttyAMA0 root=/dev/mmcblk0p2 rootwait
 
  setenv bootargs earlyprintk console=tty0 console=ttyAMA0 root=/dev/mmcblk0p2 rootwait
 +
fatload mmc 0:1 ${kernel_addr_r} zImage
 +
fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}
 
  bootz ${kernel_addr_r} - ${fdt_addr_r}
 
  bootz ${kernel_addr_r} - ${fdt_addr_r}
 +
 +
Note: There are many other DT files in mainline now. Make sure you copy the right one. Eventually, someone should fix the scripts above to use the board-identification variables that U-Boot sets, so that one script will work on all boards.
  
 
'''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.
 
'''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.
Line 78: Line 91:
  
 
  $ ./mkimage -A arm -O linux -T script -C none -n boot.scr -d boot.scr boot.scr.uimg
 
  $ ./mkimage -A arm -O linux -T script -C none -n boot.scr -d boot.scr boot.scr.uimg
 +
 +
Note: Best practice for U-Boot is to use extlinux.conf not boot.scr. One day perhaps I (swarren) will update this wiki with instructions for that...
  
 
=== Putting it all together ===
 
=== Putting it all together ===
Line 90: Line 105:
 
That's right, keep it empty. And now, let's populate with the fresh stuff.
 
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 <tt>$SD</tt>
+
Fetch start.elf and bootcode.bin from https://github.com/raspberrypi/firmware/tree/master/boot and save it to your <tt>$SD</tt>
  
And finally:
+
And finally - for Model B:
  
 
  $ cd /usr/src
 
  $ cd /usr/src
 
  $ cp u-boot/u-boot.bin $SD/kernel.img
 
  $ 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
+
  $ cp linux/arch/arm/boot/zImage linux/arch/arm/boot/dts/bcm2835-rpi-b.dtb u-boot/tools/boot.scr.uimg $SD
 +
 
 +
for Model B+
 +
 
 +
$ cd /usr/src
 +
$ cp u-boot/u-boot.bin media/boot/kernel.img
 +
$ cp linux/arch/arm/boot/zImage $SD
 +
$ cp linux/arch/arm/boot/dts/bcm2835-rpi-b-plus.dtb $SD
 +
$ cp u-boot/tools/boot.scr.uimg $SD
 +
 
  
 
And you are done. Good luck!
 
And you are done. Good luck!

Latest revision as of 16:02, 7 March 2016

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 Checklist/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), though a standard one will work nicely. Not all USB devices will work (it may depend on the type of transfer, kernel support, interrupt/control/bulk, the device uses, etc.), though the bulk of general use (Wifi, network, storage) will work nicely.

If something in this page doesn't make sense to you, pay a visit to RPi_Kernel_Compilation and RPi_U-Boot articles.

As a quickstart, this procedure will build a monolithic kernel, without modules, and good for a start. Build a successful 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 mainline U-Boot (we will need it, because the default bootloader won't be of help):

$ git clone git://git.denx.de/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-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-
$ export MODULES_TEMP=/usr/src/modules

Building your kernel

Pro tip: 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 `grep -c ^processor /proc/cpuinfo`

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 Stephen Warren's das u-Boot. Let's build it:

$ cd ../u-boot
# If you have a Raspberry Pi 0 or 1:
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make rpi_config
# If you have a Raspberry Pi 2:
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make rpi_2_config
$ ARCH=arm CROSS_COMPILE=${CCPREFIX} chrt -i 0 make -j `grep -c ^processor /proc/cpuinfo`

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

$ cd tools

And create the file boot.scr with the following content for Model B:

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

Use the following for Model B+

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

Note: There are many other DT files in mainline now. Make sure you copy the right one. Eventually, someone should fix the scripts above to use the board-identification variables that U-Boot sets, so that one script will work on all boards.

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

Note: Best practice for U-Boot is to use extlinux.conf not boot.scr. One day perhaps I (swarren) will update this wiki with instructions for that...

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, let's save the current content to a backup directory (and empty the root 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 start.elf and bootcode.bin from https://github.com/raspberrypi/firmware/tree/master/boot and save it to your $SD

And finally - for Model B:

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

for Model B+

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


And you are done. Good luck!