RPi Kernel Compilation
Overview
This page explains how to rebuild the kernel image for the RPi. There are two possible routes available:
- Compile on the Raspberry Pi itself
- Cross compile on another Linux system
Both of these routes are covered below, however, you are strongly recommended to follow the cross compilation route. The low processing power of the RPi means that a local compile will take many hours.
Example Checklist/Roadmap
This section serves to hold a new user's hand just a bit more than some of the other more generic information below in the document. To get more information on the steps in the roadmap, search this page for additional details. It assumes you can navigate filesystems, move files across systems, and have a general understanding of compiling linux kernels, filesystems, partitions, and block devices.
This series of steps yielded a successful custom/updated hardfp kernel to a stock Raspbian installation, cross compiled from an amd64 Debian system without regression on any kernel configuration options or requiring modified boot parameters. Be aware that in the worst case, you may need to overlay a stock set of kernel/modules/firmware on the Raspberry Pi if something fails. If you do not know how to do this, then a reimage of the SD card may be necessary. Assuming this is not an issue for your configuration, continue onward:
- Get the latest raspberrypi kernel source (https://github.com/raspberrypi/linux)
- Set an environment variable KERNEL_SRC to point to the location of the source ( e.g. KERNEL_SRC=/home/me/linux/ )
- Get the latest raspberrypi compiler (git clone https://github.com/raspberrypi/tools)
- Set an environment variable CCPREFIX to point to the location of tools ( e.g. CCPREFIX=/home/me/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi- )
- From the kernel clone location, clean the kernel source with "make mrproper"
- Pull the /proc/config.gz from the running Raspbian installation
- Prime kernel with the old config by running "ARCH=arm CROSS_COMPILE=${CCPREFIX} make oldconfig"
- Modify the kernel config by either modifying the .config file or using "ARCH=arm CROSS_COMPILE=${CCPREFIX} make menuconfig"
- Build the new kernel by using "ARCH=arm CROSS_COMPILE=${CCPREFIX} make"
- Set an environment variable MODULES_TEMP to point to the location of the source ( e.g. MODULES_TEMP=/home/me/modules/ )
- Set aside the new kernel modules by using "ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=${MODULES_TEMP} make modules_install"
- From the tools clone location, in the mkimage directory, run "./imagetool-uncompressed.py ${KERNEL_SRC}/arch/arm/boot/zImage"
- Move the resulting kernel.img to the Raspberry Pi's /boot/ directory
- Package up the modules into an archive such that at the top level, the structure looks like this:
- ./firmware
- ./firmware/brcm
- ./firmware/edgeport
- ./firmware/emi26
- ...
- ./modules
- ./modules/3.6.11+
- ./modules/3.6.11+/kernel
- ./modules/3.6.11+/kernel/lib
- ./modules/3.6.11+/kernel/fs
- ...
- Move the modules archive to the Raspberry Pi and extract them such that the aforementioned firmware and modules directories overwrite /lib/firmware and /lib/modules
- Get the latest raspberrypi firmware (git://github.com/raspberrypi/firmware.git)
- Transfer the following files from the firmware/boot directory to the Raspberry pi /boot directory:
- bootcode.bin
- fixup.dat
- start.elf
- Transfer the firmware/hardfp/opt directory to the Raspberry pi /opt directory
- Reboot the Raspberry Pi
The Raspberry Pi should now boot with the newly configured/recompiled kernel.
Get the kernel source
The kernel source should be downloaded from the RPI linux section on GitHub. Although you could just compile the vanilla kernel from Kernel.org, it will not have the necessary drivers and modules for the Broadcom SoC on the RPi. You can however apply patches from the vanilla kernel to the RPi one - be prepared for potential compiler grumbles though!
Jan '14 the current is rpi-3.10.y, you can check this and other available versions by browsing RPI linux section on GitHub
You can download the source directly using git. For the 3.10 branch:
git init
git clone --depth 1 git://github.com/raspberrypi/linux.git
and for the other Stable Code branch change the numbers in the following to suit:
git init
git fetch git://github.com/raspberrypi/linux.git rpi-3.6.y:refs/remotes/origin/rpi-3.6.y
git checkout rpi-3.6.y
Or you can download a tarball from the same website:
Get a compiler
Next, you will need to get a version of GCC in order to build the kernel.
1. On the RPi
Raspbian and PiBang
apt-get update
apt-get -y dist-upgrade
apt-get -y install gcc make bc
Arch Linux
pacman -Syu
pacman -S gcc make
OpenSuSE Linux
Detailed OpenSuSE RPI 12.3 Image 20130407 + 3.8.8 kernel hack tutorial witten ( 22042013 updated ) see: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=87&t=40664&p=331953#p331953 Kernel Compile takes ~22H on RPI Model B due massive module compiles , Include all IP_VS , ARPD , Fuse-zfs , Zram and more :-)
This works as well for Debian , Fedora remix and others ( just package Install command differ )
zypper install u-boot-tools sudo gcc automake autoconf bison gettext flex libncurses5 ncurses-devel
cd /usr/src
mkdir GIT; cd GIT; git init; D=`date +"%m-%d-%Y"`
git fetch git://github.com/raspberrypi/linux.git rpi-3.8.y:refs/remotes/origin/rpi-3.8.y
git checkout rpi-3.8.y
tar cpf rpi-3.8.y.$D.tar rpi-3.8.y cd /usr/src
tar xpf GIT/rpi-3.8.y.$D.tar
rm linux
ln -s linux-rpi-3.8.y linux cd /usr/src/linux
kversion=$(make -s kernelrelease)
cp linux/.config .config_$kversion cd /usr/src/
# get config-3.8.7.ipvs+krb5+arpd.tar.bz2 from the Tutorial:
wget http://www.raspberrypi.org/phpBB3/download/file.php?id=3174
# copy the .config to /usr/src/linux:
tar xpfj config-3.8.7.ipvs+krb5+arpd.tar.bz2 #make the Kernel and go sleep :-)
cd linux
make oldconfig
nohup make zImage dep modules & #Next day .. Install It.
cd /usr/src/linux
kversion=$(make -s kernelrelease)
echo $kversion
mkdir -p /boot/$kversion
make ARCH=arm INSTALL_PATH=/boot/ install
cp System.map /boot/System.map-$kversion
cp System.map-$kversion /boot/System.map
make ARCH=arm modules_install INSTALL_MOD_PATH=/
make ARCH=arm INSTALL_PATH=/boot/ zinstall
cp .config /boot/config-$kversion
cp ./Module.symvers /boot/symvers-$kversion
cp arch/arm/boot/Image /boot/kernel.img
2. Cross compiling from Linux
Please note that when cross-compiling, your compiler may not target the correct ARM processor by default. This will at best reduce performance, or worse, compile for a much newer processor resulting in illegal instructions in your code. The pre-built compiler or a custom-built compiler are recommended because of this. (For example, the latest GCC Linaro binary targets armv7-a by default, whereas the RPi requires armv6kz). It is possible to add extra compiler options to the HOSTCFLAGS line in Makefile. The correct flags are shown on thesoftware page - note that you may also need to add -marm if your compiler produces Thumb code by default.
Use the provided compiler
Download the pre-built bmc2708 compiler from the RPI tools section on GitHub.
git clone git://github.com/raspberrypi/tools.git
or you can download a tarball from the website using this link.
Custom-built Linaro GCC
Ubuntu
apt-get install gcc-arm-linux-gnueabi make ncurses-dev
Gentoo Linux
crossdev -S -v -t arm-unknown-linux-gnueabi
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
yaourt -S arm-linux-gnueabi-gcc
Cross compiling from OSX
Macports
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 Install macports
port install arm-none-eabi-gcc
port install arm-none-eabi-binutils
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
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_ARM_NONE 0
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_MIPS_NONE 0
#define R_MIPS_16 1
#define R_MIPS_32 2
#define R_MIPS_REL32 3
#define R_MIPS_26 4
#define R_MIPS_HI16 5
#define R_MIPS_LO16 6
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
Complete script requires raspberrypi.config to be in the same folder that you execute from
sudo port install arm-none-eabi-gcc
sudo port install arm-none-eabi-binutils
sudo port install libelf && sudo ln -s /opt/local/include/libelf /usr/include/libelf
sudo curl http://opensource.apple.com/source/dtrace/dtrace-48/sys/elftypes.h?txt -o /usr/include/elftypes.h
sudo curl http://opensource.apple.com/source/dtrace/dtrace-48/sys/elf.h?txt -o /usr/include/elf.h
#code to append to elf.h
echo "
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_ARM_NONE 0
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_MIPS_NONE 0
#define R_MIPS_16 1
#define R_MIPS_32 2
#define R_MIPS_REL32 3
#define R_MIPS_26 4
#define R_MIPS_HI16 5
#define R_MIPS_LO16 6" > elf-append.h
sudo -s 'cat elf-append.h >> /usr/include/elf.h' #Make a case sensitive 3gb disk image, raspberrypi-kernel, and attach it
hdiutil create -size 10g -type SPARSEBUNDLE -nospotlight -volname raspberrypi-kernel -fs "Case-sensitive Journaled HFS+" -attach ./raspberrypi-kernel.dmg
cp raspberrypi.config /Volumes/raspberrypi-kernel/
mkdir /Volumes/raspberrypi-kernel/src
cd /Volumes/raspberrypi-kernel/src #get source, either 1. from zip (faster), or 2. from git
#1. from zip
curl https://codeload.github.com/raspberrypi/linux/zip/rpi-3.6.y -o ./rpi-3.6.y.zip
unzip rpi-3.6.y.zip
#2. from git (disabled)
#git init
#git fetch git://github.com/raspberrypi/linux.git rpi-3.6.y:refs/remotes/origin/rpi-3.6.y
#git checkout rpi-3.6.y cpu=$(sysctl hw.ncpu | awk '{print $2}')
cpup1=$((cpu+1)) cd /Volumes/raspberrypi-kernel/src/linux-rpi-3.6.y/
export CCPREFIX=/opt/local/bin/arm-none-eabi-
make mrproper
cp /Volumes/raspberrypi-kernel/raspberrypi.config .config
#answer yes to all config options
#yes "" | make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j$cpup1
#make ARCH=arm CROSS_COMPILE=${CCPREFIX} modules -j$cpup1
Yagarto
Download and install from here.
Perform the compilation
Firstly, ensure your build directory is clean:
make mrproper
Next, in all cases, you will want to get a working kernel configuration to start from. You can get the one running on the RPi by typing the following (on the RPi):
zcat /proc/config.gz > .config
then copy .config into your build directory.
Alternatively, the default configuration is available in the downloaded kernel source in arch/arm/configs/bcmrpi_defconfig. Just copy this to .config in the build directory.
From this point on, if you are cross-compiling, set an environment variable CCPREFIX that points to the prefix of your compiler binary as each compiler will be named slightly differently.
export CCPREFIX=/path/to/your/compiler/binary/prefix-of-binary-
If you are building on the RPi, remove ARCH=arm CROSS_COMPILE=${CCPREFIX} from each command.
Ensure that your configuration file is up-to-date:
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
If any configuration options have been added, you will be asked what set each option to. If you don't know the answer, just press enter to accept the default.
Optionally, if you want to make changes to the configuration, run this next:
make ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig
Now you are ready to build:
make ARCH=arm CROSS_COMPILE=${CCPREFIX}
If you are on a multi-core system, you can make the build faster by appending -j<N> where <N> is the number of cores on your system plus one (i.e. -j3 for 2 cores).
Find something else to get on with while the compilation takes place. On an average PC with the default configuration, this should take about 15 minutes.
The modules will be build with the following command.
make ARCH=arm CROSS_COMPILE=${CCPREFIX} modules
Transfer the build
The fully built kernel will be arch/arm/boot/Image. Copy your new kernel file into the RPi boot partition, though preferably as a new file (such as kernel_new.img) just in case it doesn't work. If you're building on the RPi, just copy the file to /boot. If you use a different filename, edit config.txt change the kernel line:
kernel=kernel_new.img
#kernel=kernel.img
Now you need to transfer the modules. Set an environment variable that points to a temporary module path.
export MODULES_TEMP=~/modules
In the build directory, run the following command:
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=${MODULES_TEMP} modules_install
The contents of this directory, a single
lib
directory, should then be copied into the RPi root directory, merging or overwriting
/lib
. NOTE: If you have rebuilt the new kernel with exactly the same version as the one that's running, you'll need to remove the old modules first. Ideally this should be done offline by mounting the SD card on another system.
Your RPi should now be ready to boot the new kernel. However, at this point it's recommended that you update your GPU firmware and libraries. This is required if you've just moved from 3.2 to 3.6 as the firmware interface has changed.
Get the firmware
The firmware and boot files should be updated at the same time to ensure that your new kernel works properly. Again, two branches are available:
- master - This is the version of firmware currently used in Raspbian (i.e. it works with the 3.2 kernel).
- next - This is a development branch which provides a newer GPU firmware to work with the updated drivers in the 3.6 kernel.
You can either download the source directly using git: You can download the firmware directly using git. For the master branch:
git clone git://github.com/raspberrypi/firmware.git
and for the next branch:
git fetch git://github.com/raspberrypi/firmware.git next:refs/remotes/origin/next
Or you can download a tarball from the website using these links: master next
Transfer the firmware
Firstly, update the required boot files in the RPi boot directory with those you've downloaded. These are:
- bootcode.bin
- fixup.dat
- start.elf
Next, you need to copy the VC libraries over. There are two copies of this: one for hard float and one for soft float. To find the correct one, run the following command:
${CCPREFIX}gcc -v 2>&1 | grep hard
If something prints out, and you can see --with-float=hard, you need the hard float ones. NOTE: The current version of Raspbian uses hard float.
Remove the /opt/vc directory from the RPi root, then:
- For hard float, copy vc from the hardfp/opt directory into /opt in the RPi root directory
- Otherwise copy vc from the top-level opt directory into /opt in the RPi root directory.
Test your build
Power cycle your RPi and check the following:
- If you have the serial port on the GPIO expander wired up, you should see the kernel booting.
- The screen works - the kernel boots and you get a login prompt.
- The VC interface is working - if the 'OK' LED flashes regularly eight or so times every few seconds once the OS has booted, it's not. You can also test this by running vcgencmd measure_temp. If it prints "VCHI initialization failed", you have the a mismatch between the firmware, the VC libraries, and the kernel driver.
- Run uname -a and check that your new kernel is the one that's running.
- Make sure you don't have any odd error messages during boot that may indicate a module isn't working properly. If you see missed completion of cmd 18 regarding DMA transfers to the SD card, you can safely ignore it.
RPi Kernel Compilation的更多相关文章
- Raspberry Pi Kernel Compilation 内核编译官方文档
elinux.org/Raspberry_Pi_Kernel_Compilation#Use_the_provided_compiler Software & Distributions: S ...
- ora-00600笔记
一. ORA-600 概述 Errorsof the form ORA-600 are called internal errors. This section clarifies themisund ...
- oracle-Expdp/impdp命令
建立逻辑路径 create or replace directory dumpdir as 'c:\'; grant read,write on directory dumpdir to scott; ...
- ftrace的使用【转】
转自:http://blog.csdn.net/cybertan/article/details/8258394 This article explains how to set up ftrace ...
- 树莓派linux驱动学习之hello world
最近想学习一下linux驱动,看了一些书和教学视频,大概了解了一下,不过要想深入,肯定需要实践.手上有几块linux的板子,最终选择了树莓派作为我的实验平台,资料比较丰富,接口也比较简单. 程序员的入 ...
- 内核调试神器SystemTap — 更多功能与原理(三)
a linux trace/probe tool. 官网:https://sourceware.org/systemtap/ 用户空间 SystemTap探测用户空间程序需要utrace的支持,3.5 ...
- linux测试工程介绍(Linux Test Project)
http://ltp.sourceforge.net/ Linux Test Project, 后台很硬,由SGI™ 发起, IBM维护,所以质量有保障. 里面介绍了很多工具,对于一般的基准测试应该是 ...
- linux - console/terminal/virtual console/pseudo terminal ...
http://en.wikipedia.org/wiki/System_console System console Knoppix system console showing the boot p ...
- ftrace的使用
This article explains how to set up ftrace and be able to understand how to trace functions. It shou ...
随机推荐
- 不规则递归转换为while,留底
我发现当参数并不太多时,从性能的角度来看,没必要用一个class来保存参数(虽然看起来更加生动形象),直接用最简单的元组就可以了. from hanoi import * # example tree ...
- Xcode7.3.1中通过最新的CocoaPod安装pop动画引擎
CocoaPod是一个用ruby实现,用于方便的管理Xcode中第三方插件的管理器.用它我们可以很方便的安装和升级插件而不用担心破坏原有的项目. 而pop是一个用于实现App中动画的引擎,它是由Fac ...
- HDFS:NameNode、DataNode、SecondaryNameNode
可以一句话描述 HDFS:把客户端的大文件存放在很多节点的数据块中. HDFS设计原则: 1,文件以块(block)方式存储: 2,通过副本机制提高可靠度和读取吞吐量: 3,每个区块至少分到三台Dat ...
- Eclipse打jar包,资源文件的读取
最近的工作中需要将java程序打一个jar包,然后在Linux中供调用.程序中需要读取一个配置文件.遇到了三个问题.第一个是依赖的第三方Jar包打成Jar包后找不到:第二个问题是资源文件所在的文件夹打 ...
- UNIX网络编程——ioctl 函数的用法详解
1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...
- Objc中为何某些类的属性要设置为copy而不是strong?
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 不知道大家是否注意,我们再使用一些第三方类的时候大多数情况下对 ...
- mac OS下在控制台中发送外部邮件
1 首先安装mailx: sudo port install mailx 2 然后设置别名 : alias mailx=/opt/local/bin/mailx alias mail=/opt/loc ...
- 如何使用EasyUI显示表格界面
还记得前面有篇博客叫---使用TT模板+mvc+wcf实现简单查询,这篇博文的末尾,小编贴了一张查询出来的结果图,那么这篇博客的中新来了,如何使用EasyUI显示出表格样式的界面,以前学习CS的时候, ...
- [rrdtool]监控和自动画图,简单的监控.md
现在想要监控服务的流量和并发数,可是又没那么多时间来写系统,其他的运维系统又不熟悉,于是就用现有的rrdtool shell做了个简单的监控界面,临时用下,也算是个小实验把. rrdtool也是刚接触 ...
- UNIX环境高级编程——无名管道和有名管道
一.进程间通信 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2 ...