本文主要参考:
http://blog.csdn.net/hw5226349/article/details/37877945
https://www.raspberrypi.org/documentation/linux/kernel/building.md
http://blog.csdn.net/farsight2009/article/details/52514281
树莓派内核编译主要有两种方法:
1、本地编译
2、交叉编译
本文主要介绍交叉编译,好,交叉编译开始。。。。。。
一、交叉编译链搭建
1、PC机环境:
Ubuntu14.04 amd64 虚拟机环境
2、交叉工具链搭建
1)、下载必要软件
sudo apt-get install build-essential git
2)、clone交叉工具链
在主文件夹下新建一个文件夹raspberry_src并进入文件夹
mkdir raspberry_src
cd raspberry_src
获取交叉工具链
git clone git://github.com/raspberrypi/tools.git
下载完成可以进入工具链文件夹查看
cd tools/arm-bcm2708/
ls
在该文件夹下,一共有5个不同版本的交叉编译工具
arm-bcm2708hardfp-linux-gnueabi
gcc-linaro-arm-linux-gnueabihf-raspbian
arm-bcm2708-linux-gnueabi
gcc-linaro-arm-linux-gnueabihf-raspbian-x64
arm-rpi-4.9.3-linux-gnueabihf
其中arm-rpi-4.9.3-linux-gnueabihf和gcc-linaro-arm-linux-gnueabihf-raspbian-x64是64位机器用的,每一个交叉编译工具的目录下都有bin目录进入,执行./arm-linux-gnueabihf-gcc -v可查看gcc版本。
在这里我们使用的是 gcc-linaro-arm-linux-gnueabihf-raspbian-x64 版本
3)、加入环境变量
在/.bashrc文件中加入gcc交叉工具链目录。
sudo gedit ~/.bashrc
在该文件最后加入交叉工具链所在目录。请注意~符号表示HOME路径,.bashrc为隐藏文件。
【32位系统】
export PATH=$PATH:$HOME/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin(gcc有问题,暂不明)
export PATH=$PATH:$HOME/rpi/tools/arm-bcm2708-linux-gnueabi/bin(使用这个文件中的gcc)
【64位系统】
export PATH=$PATH:$HOME/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
export PATH=$PATH:$HOME/rpi/tools/arm-bcm2708-linux-gnueabi/bin
请注意PATH代表环境变量,:冒号代表追加。
保存并退出文件,接着执行以下指令以便立即更新当前控制台所包含的环境变量。
source .bashrc
4)、简单测试
为了测试交叉工具链是否安装成功,可在控制台中输入
arm-linux-gnueabihf-gcc -v
控制台中最后会输出内容如下,即可证明交叉工具链安装完成且环境变量设置无误。
gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03)
5)、简单例子测试
编写一个测试文件,在PC机上完成编译然后上传到树莓派中并执行。该例子仅测试交叉编译是否成功并简单测试了浮点数功能
新建一个文件夹hello,里面有两个文件hello.c 和 Makefile。
hello.c
#include
int main(void)
{
float pi = 3.14;
printf("Hello World\n");
printf("%.2f\n",2*pi);
}
Makefile
CC=arm-linux-gnueabihf-gcc
hello:hello.o
clean:
rm -rf hello.o hello
在makefile文件中使用了至少两条隐含规则,CC为默认工具链;.o文件由同名的.c文件生成。
在该文件夹下,进行make一下
make
把产生的可执行文件hello上传到树莓派,执行hello可执行文件,可以得到正确结果,说明交叉编译链配置成功
二、内核编译
1、获取内核源码
cd ~/raspberry_src
git clone --depth=1 https://github.com/raspberrypi/linux
2、获取当前树莓派系统的配置文件
这里很有必要说明是,在raspberrypi系统的3.x版本以前,树莓派系统默认存在/proc/config.gz文件,但是更新到4.x版本之后,/proc/config.gz文件默认不存在了,所以我们需要先获取到这个文件。
执行命令:
sudo modprobe configs
执行以上命令之后,会在/proc/目录下生成config.gz文件。然后将此文件从树莓派系统内拷贝到我们的PC平台(有很多种方法,比如U盘,NFS系统文件共享,TCP,samba等等)。
将config.gz拷贝到内核源码的根目录(~/raspberry_src/linux/),然后在需要编译的内核的顶层目录下执行命令:
cd ~/raspberry_src/linux/
zcat config.gz > .config
目的是生成.config配置文件
KERNEL=kernel7
如果上面获取了内核配置文件,下面这句不用执行
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
3、开始编译内核和模块
这句就是真正的编译了,等等完成吧!如果电脑满足要求的话,可以再make的后面加上-j2,-j4,-j6,-j8等等,表示使用多少个线程进行编译,可以提高编译速度,等待成功吧。编译成功后,在路径arch/arm/boot/下会生成zImage镜像文件。我的虚拟机加上-jn,会出错。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
4、直接安装到SD卡
在装有树莓派系统的SD卡插入电脑之前,可以先使用 lsblk 看一下,可以看到如下输出:
sda
├─sda1
├─sda2
└─sda5
插入SD卡,再使用 lsblk 看一下,可以看到新增如下输出:
sdc
├─sdc1
└─sdc2
1)、挂载SD卡
mkdir mnt
mkdir mnt/fat32
mkdir mnt/ext4
sudo mount /dev/sdc1 mnt/fat32
sudo mount /dev/sdc2 mnt/ext4
2)、安装模块
这里交叉编译器最好指定路径,第一次没有指定,导致安装到SD卡的系统启动后,键盘鼠标识别不了,原因是找不到交叉编译器,导致有些库没有装上。
sudo make ARCH=arm CROSS_COMPILE=~/raspberry_src/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/arm-linux-gnueabihf- INSTALL_MOD_PATH=mnt/ext4 modules_install
执行完之后,模块就会安装到/lib目录下。
5、拷贝内核及相关文件到SD卡
拷贝之前,确保备份你的旧内核
sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img
sudo scripts/mkknlimg arch/arm/boot/zImage mnt/fat32/$KERNEL.img//将zImage格式转成树莓派需要的img格式,并复制到SD卡
sudo cp arch/arm/boot/dts/*.dtb mnt/fat32/
sudo cp arch/arm/boot/dts/overlays/*.dtb* mnt/fat32/overlays/
sudo cp arch/arm/boot/dts/overlays/README mnt/fat32/overlays/
sudo umount mnt/fat32
sudo umount mnt/ext4
注意,编译生成的内核zImage是无法给树莓派直接用的,所以必须把它转成.img类型。
采用交叉编译工具里的imagetool-uncompressed.py(~/raspberry_src/tools/mkimage/)转成的.img无法使用。必须使用源码目录下的scripts/mkknlimg。
升级内核的另一个办法是将img文件复制到相同目录下,使用不同的文件名,如 kernel-myconfig.img,然后修改boot目录下的config.txt文件,加入:
kernel=kernel-myconfig.img
最后,将SD卡插入树莓派启动。