【树莓派】Linux内核编译

【树莓派】Linux内核编译

树莓派的Linux内核编译有两种方法: 一种是在树莓派上直接编译,另一种是利用交叉编译的方法。一般我们都推荐采用交叉编译的方式进行编译,这是因为通常交叉编译Pi内核的速度比Pi本身编译快得多(性能因素)。下面就讲下如下利用这两种方式来编译Pi内核。

第一种方法:Pi本地编译

前提条件

准备一张16G以上TF卡(需要事先进行扩容和增加SWap分区操作,可参考公众号里文章)。
如果上述没有该条件,可以利用NFS挂载方式,将源码目录挂载到主机上,利用主机的空间来存储代码,但会影响到编译速度。 比如我将虚拟机的nfs目录挂载到Pi的/mnt目录下,并在该目录下存储代码,如下:

pi@raspberrypi:~ $ mount | grep mnt
192.168.1.133:/nfs/ on /mnt type nfs (rw,relatime,vers=3,rsize=524288,wsize=524288,namlen=255,hard,nolock,proto=tcp,port=2049,timeo=70,retrans=3,sec=sys,local_lock=all,addr=192.168.1.133)
pi@raspberrypi:~ $ ls /mnt/
linux
pi@raspberrypi:~ $

编译前准备

首先,配置好树莓派的网络(用推荐用有线网络,否则下载会非常慢)和树莓派的源(推荐使用阿里源,将"raspbian.raspberrypi.org”替换为“mirrors.aliyun.com/raspbian"字段),正常souces.list前后替换后差异内容大致如下:

安装git和树莓派内核编译所需的依赖库,如下所示:

 $ sudo apt install git bc bison flex libssl-dev make

下载内核源码

利用git获取当前git仓库默认Pi的内核源码,如下所示:

$ git clone --depth=1 https://github.com/raspberrypi/linux

当然,你也可以选择下载自己所需的内核源码版本,如需要下载4.14.y,可利用branch参数下载,如下:

$ git clone --depth=1 https://github.com/raspberrypi/linux --branch rpi-4.14.y

配置内核

根据当前你使用的Raspberry Pi的实际型号,通过运行以下具体命令进行准备默认配置:
如果是Raspberry Pi 2, Pi 3, Pi 3+系列,默认配置如下:

pi@raspberrypi:/mnt $ cd linux
pi@raspberrypi:/mnt/linux $ KERNEL=kernel7
pi@raspberrypi:/mnt/linux $ make bcm2709_defconfig

Raspberry Pi 4的默认配置如下:

pi@raspberrypi:/mnt $ cd linux
pi@raspberrypi:/mnt/linux $ KERNEL=kernel7l
pi@raspberrypi:/mnt/linux $ make bcm2711_defconfig


Raspberry Pi 1、Pi Zero、Pi Zero W系列的默认采用配置如下:

pi@raspberrypi:/mnt $ cd linux
pi@raspberrypi:/mnt/linux $ KERNEL=kernel
pi@raspberrypi:/mnt/linux $ make bcmrpi_defconfig
 

如果需要额外对内核进行配置,则可以利用如下命令实现:

pi@raspberrypi:/mnt/linux $ make menuconfig

编译和安装

最后进行编译安装内核、驱动模块、设备树配置操作,这个过程会比较漫长,需要耐心等待,命令如下:

pi@raspberrypi:/mnt/linux $ make -j4 zImage modules dtbs
pi@raspberrypi:/mnt/linux $ sudo make modules_install
pi@raspberrypi:/mnt/linux $ sudo cp arch/arm/boot/dts/*.dtb /boot/
pi@raspberrypi:/mnt/linux $ sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
pi@raspberrypi:/mnt/linux $ sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
pi@raspberrypi:/mnt/linux $ sudo cp arch/arm/boot/zImage /boot/$KERNEL.img
pi@raspberrypi:/mnt/linux $  sudo reboot -f

第二、交叉编译内核

首先,需要准备一台Linux交叉编译主机,比如Ubuntu 18.04(可以安装实体机或者VMware或VirtualBox里)。

编译前准备

首先在交叉编译Linux主机上安装所需的依赖和交叉编译工具,如下:

sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev

如果Pi安装的是32的内核,则安装32位的交叉编译工具链:

(注:通过在Pi里运行“file /sbin/busybox” 或其他可执行程序可查看当前内核是32位还是64位的。如果是32位的,会显示如下32-bit 字段,否则为64位的)

$ sudo apt install crossbuild-essential-armhf

否则,如果Pi使用的是64的内核,则安装64位的交叉编译工具链:

$ sudo apt install crossbuild-essential-arm64

获取源码

利用git获取当前git仓库默认Pi的内核源码,如下所示:

$ git clone --depth=1 https://github.com/raspberrypi/linux

当然,你也可以选择下载自己所需的内核源码版本,如需要下载4.14.y,可利用branch参数下载,如下:

$ git clone --depth=1 https://github.com/raspberrypi/linux --branch rpi-4.14.y

配置内核

针对32位系统:

如果是Pi 2, Pi 3, Pi 3+, 和3系列树莓派,运行如下命令:

linux@ubuntu:~$ cd linux
linux@ubuntu:~/linux$ KERNEL=kernel7
linux@ubuntu:~/linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig

如果是Raspberry Pi 4,运行如下命令:

linux@ubuntu:~$ cd linux
linux@ubuntu:~/linux$ KERNEL=kernel7l
linux@ubuntu:~/linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig

如果是Pi 1, Pi Zero, Pi Zero W,运行如下命令:

linux@ubuntu:~$ cd linux
linux@ubuntu:~/linux$ KERNEL=kernel
linux@ubuntu:~/linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcmrpi_defconfig

针对64位系统:

如果是Pi 2, Pi 3, Pi 3+, 和3系列树莓派,运行如下命令:

linux@ubuntu:~$ cd linux
linux@ubuntu:~/linux$ KERNEL=kernel8
linux@ubuntu:~/linux$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig

如果是Raspberry Pi 4,运行如下命令:

linux@ubuntu:~$ cd linux
linux@ubuntu:~/linux$ KERNEL=kernel8
linux@ubuntu:~/linux$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig

编译内核

针对32位内核

运行如下命令:

make -j4  ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs

针对64位内核

运行如下命令:

make -j4  ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs

内核安装到TF卡

将TF卡接到Linux交叉编译主机上(如果是VMwar虚拟机,则需要将"设置->硬件->USB控制机->USB兼容性(C)”调成“USB 1.1”)
运行lsblk命令查看识别到的TF卡设备节点,如下:

linux@ubuntu:~/linux$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   20G  0 disk 
└─sda1   8:1    0   20G  0 part /
sdb      8:16   1 14.6G  0 disk 
├─sdb1   8:17   1  256M  0 part /media/linux/boot
└─sdb2   8:18   1  3.3G  0 part /media/linux/rootfs


正常TF卡设备会自动挂载到/media/${当前用户目录}/下的boot和rootfs目录下,如果没有自动挂载,则根据识别到实际TF卡的设备节点,将设备挂载到主机上,如下:

sudo mkdir /media/linux/rootfs -p
sudo mkdir /media/linux/boot -p
sudo mount /dev/sdb1 /media/linux/boot
sudo mount /dev/sdb2 /media/linux/rootfs
 

然后将内核模块安装到SD中:

针对32位内核

运行如下命令:

sudo env PATH=$PATH make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=/media/linux/rootfs modules_install

针对64位内核

运行如下命令:

sudo env PATH=$PATH make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/media/linux/rootfs modules_install

备份旧内核

最后备份原理SD卡中的旧内核, 并将新内核和设备树配置文件到SD卡中:

针对32位内核

运行如下命令:

sudo cp /media/linux/boot/$KERNEL.img /media/linux/boot/$KERNEL-backup.img
sudo cp arch/arm/boot/zImage /media/linux/boot/$KERNEL.img
sudo cp arch/arm/boot/dts/*.dtb /media/linux/boot
sudo cp arch/arm/boot/dts/overlays/*.dtb* /media/linux/boot/overlays/
sudo cp arch/arm/boot/dts/overlays/README /media/linux/boot/overlays/
sudo umount /media/linux/boot
sudo umount /media/linux/rootfs

针对64位内核

运行如下命令:

sudo cp /media/linux/boot/$KERNEL.img /media/linux/boot/$KERNEL-backup.img
sudo cp arch/arm64/boot/Image /media/linux/boot/$KERNEL.img
sudo cp arch/arm64/boot/dts/broadcom/*.dtb /media/linux/boot/
sudo cp arch/arm64/boot/dts/overlays/*.dtb* /media/linux/boot/overlays/
sudo cp arch/arm64/boot/dts/overlays/README /media/linux/boot/overlays/
sudo umount /media/linux/boot/
sudo umount /media/linux/rootfs


当然,你也可以不备份旧的内核,而是通过重命令编译出来的内核名称,如将编译出来的img改为kernel-new.img,然后修改config.txt的配置文件种的kernel字段,如下:

kernel=kernel-new.img

这么做的好处是保证原有的内核不被破坏,如果新的内核无法启动,只需要将config.txt的kernel字段改回来即可。

最后,将TF卡插回Pi上,然后启动Pi即可。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值