文档章节

[翻译中] 树莓派内核编译

八宝粥
 八宝粥
发布于 2013/06/29 03:30
字数 2867
阅读 1.2W
收藏 18

概述

本文会详细介绍如何编译树莓派的内核镜像. 通过两种方式可以实现:

  1. 直接在树莓派上编译
  2. 在其他Linux系统上进行交叉编译

然而, 我们强烈建议使用交叉编译. 因为树莓派的处理能力较低, 进行本地编译会花费太长时间.

编译步骤

在这一小节中, 我们会手把手告诉你编译所需的每一步. 你可以在本文最上方的目录中快速定位到详细介绍某步骤的章节. 请确保您有浏览文件系统和跨平台移动文件的能力, 并对Linux内核编译, 文件系统, 分区及设备驱动有大致了解.

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. 如果你不清楚如何操作, 很有必要先重烧一下SD卡. 在配置过程中如果没出现问题, 就请接着做下去:

  1. 获得最新的树莓派内核源码 (https://github.com/raspberrypi/linux)
  2. 设置环境变量KERNEL_SRC为源码所在路径 (例如 KERNEL_SRC=/home/me/linux/ )
  3. 获得最新的树莓派编译工具 (git clone https://github.com/raspberrypi/tools)
  4. 设置环境变量CCPREFIX为编译器所在路径 (例如 CCPREFIX=/home/me/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi- )
  5. From the kernel clone location, clean the kernel source with "make mrproper"
  6. Pull the /proc/config.gz from the running Raspbian installation
  7. Prime kernel with the old config by running "ARCH=arm CROSS_COMPILE=${CCPREFIX} make oldconfig"
  8. Modify the kernel config by either modifying the .config file or using "ARCH=arm CROSS_COMPILE=${CCPREFIX} make menuconfig"
  9. 使用命令"ARCH=arm CROSS_COMPILE=${CCPREFIX} make"编译新内核
  10. 设置环境变量MODULES_TEMP源码所在路径 (例如 MODULES_TEMP=/home/me/modules/ )
  11. Set aside the new kernel modules by using "ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=${MODULES_TEMP} make modules_install"
  12. From the tools clone location, in the mkimage directory, run "./imagetool-uncompressed.py ${KERNEL_SRC}/arch/arm/boot/zImage"
  13. 把生成的kernel.img移动到树莓派的/boot/目录
  14. 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
    • ...
  15. 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
  16. Get the latest raspberrypi firmware (git://github.com/raspberrypi/firmware.git)
  17. Transfer the following files from the firmware/boot directory to the Raspberry pi /boot directory:
    • bootcode.bin
    • fixup.dat
    • start.elf
  18. Transfer the firmware/hardfp/opt directory to the Raspberry pi /opt directory
  19. 重启树莓派

现在树莓派应该是使用新内核启动的了.

获得内核源码

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!

截至到本文发稿, three branches of interest are available:

  • rpi-3.2.27 - This is the version of the kernel currently used in Raspbian, but not exactly the same - Raspbian stock kernel image (the one available from the foundation's website) has a 3.2.27+ version marking. Please see this post for more details.
  • rpi-3.6-y - This is a development branch based on the current vanilla kernel( GIT rebased ) . It replaced the 3.2 development branch end marc 2013.

截至到本文发稿, the exact version is 3.6.11.

  • rpi-3.8-y - This is a Alpha development branch based on the current vanilla kernel( GIT rebased) . It will eventually replace the 3.6 branch.

新更新, 有新版本3.8.8 ( 22-04-2013 ).

你可以通过git直接下载源码. 比如下载3.2分支:

git init
git clone --depth 1 git://github.com/raspberrypi/linux.git
git checkout rpi-3.2.27

下载3.6稳定版分支:

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

下载3.8开发版分支:

git init
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

或者从网站下载压缩包: rpi-3.2.27  rpi-3.6.y  rpi-3.8.y

获得编译工具

接下来, 我们需要获得GCC来编译内核.

1. 在树莓派上编译

Raspbian或PiBang

apt-get update
apt-get -y dist-upgrade
apt-get -y install gcc make

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 )
#     
SuSE:  zypper install u-boot-tools sudo gcc automake autoconf bison gettext flex libncurses5 ncurses-devel
Debian / Ubuntu : apt-get install ncurses-base libncurses5 ncurses-bin ncurses-term libncurses5-dev sudo gcc automake autoconf bison gettext flex
                  apt-get install uboot-mkimage uboot-envtools
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 any 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. 在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 the software 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

See Linaro GCC Compilation.

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

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

执行编译

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

移动内核镜像

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 should then be copied into the RPi root directory. 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.

获得固件

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

移动固件

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.

测试

重启树莓派后进行检查:

  • If you have the serial port on the GPIO expander wired up, you should see the kernel booting.
  • 屏幕显示 - 内核启动后出现登录提示界面.
  • 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 runningvcgencmd 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.

© 著作权归作者所有

八宝粥
粉丝 50
博文 24
码字总数 36054
作品 0
程序员
私信 提问
加载中

评论(2)

八宝粥
八宝粥 博主

引用来自“moyanming”的评论

为什么没有标明出处???
好久以前找的文章了。出处已忘,如有侵权,麻烦通知我,我会删掉的。
moyanming
moyanming
为什么没有标明出处???
[翻译完成] 树莓派U-Boot

概述 Das U-Boot, 通常叫做U-Boot, 嵌入式系统的常用bootloader. U-Boot允许使用SD卡上单个指定文件的内容作为额外的启动参数, 为树莓派增加不少灵活性. 本文将详细介绍如何让U-Boot运行在树...

八宝粥
2013/07/02
5K
0
树莓派64位操作系统 - Debian-Pi-Aarch64

树莓派64位操作系统 - OPENFANS开源社区 & 树莓派爱好者社区 - 联合出品 - 这是支持树莓派全系列64位CPU的全新的64位2.0系统 正式版 的说明文档,系统支持树莓派3B、3B+、3A+、4B。 系统介绍...

量子云
2019/10/16
9K
10
玩转树莓派-RaspBerry,操作系统的源码编译

源码编译是玩转树莓派的终极修炼,下面我们开始闯关。 1、获取升级所需源码 1)下载地址: 官方网址: 上面列出了树莓派所有的开源软件: firmware:树莓派的交叉编译好的二进制内核、模块、库...

openthings
2015/03/23
4.9K
0
10 个最值得关注的树莓派博客

如果你正在计划你的下一个树莓派项目,那么这些博客或许有帮助。 网上有很多很棒的树莓派爱好者网站、教程、代码仓库、YouTube 频道和其他资源。以下是我最喜欢的十大树莓派博客,排名不分先...

作者: Ben Nuttall
2018/11/02
0
0
[翻译完成] 树莓派LCD显示器适配器

我们之前发布了一款" 树莓派LCD显示器适配器 " , 你可以用我们的LCD屏(ITDB02-2.4E和ITDB02-2.8)直接连上树莓派使用. 在这里我们为这两款屏幕提供一些demo代码 – demo代码由Henning提供的U...

八宝粥
2013/06/29
3.2K
1

没有更多内容

加载失败,请刷新页面

加载更多

guava中EvictingQueue使用与改进

一、简介 因为业务有一些服务器在国外,网络非常不稳定,执行http请求的时候波动很大。所以我们希望在网络变慢的时候通过http代理切换到其他服务器发送http请求。 如果界定变慢呢? 如果,最...

trayvon
10分钟前
5
0
Python类继承对象 - Python class inherits object

问题: Is there any reason for a class declaration to inherit from object ? 类声明从object继承有什么理由吗? I just found some code that does this and I can't find a good reason......

javail
26分钟前
8
0
查看无线网卡是否支持监听模式

查看无线网卡是否支持监听模式 在实施无线渗透测试时,通常需要将无线网卡设置为监听模式,来监听经过其网卡的所有流量。大学霸IT达人对于很多用户,都不知道如何确定自己的无线网卡是否支持...

大学霸
28分钟前
7
0
windows虚拟主机控制面板哪个比较好用?

相对于Linux发行版本的系统,大多人都比较习惯使用windows系统,同时windows虚拟主机对于 ASP.NET,PHP等热门程序也有了广泛的友好支持。因此,很多新手站长比较倾向于使用windows虚拟主机,...

好么好的_920
32分钟前
14
0
如何使用Elasticsearch中提供的RESTFul风格API? 快来快来,加入小案例需求 不要错过哦~~

前言: 本篇会以小案例需求的方式带你学习Elasticsearch中基于RESTFulApi操作。手敲几遍,想不会也难。加油~ 对了,这里使用的是Kibana和head进行的管理,如果没有接触,推荐看下面的博客,写的挺...

漫路h
51分钟前
23
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部