目录
准备交叉编译环境
以Ubuntu x86-64位的编译机(实际上用的是WSL,WSL真香)为例,需要安装交叉编译工具:
# armhf工具链, 适用pi1/pi2, pi3/pi4的32位系统
sudo apt-get install gcc-arm-linux-gnueabihf
# arm64工具链,适用pi3/pi4的64位系统
sudo apt-get install gcc-aarch64-linux-gnu
安装内核编译依赖:
sudo apt-get install git make build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison libc6-dev libncurses5-dev
下载内核代码
armhf - 树莓派官方提供:(官方的raspbian用的就是这个内核)
https://github.com/raspberrypi/linux
arm64 - Ubuntu官方提供:(官网第三方的Ubuntu系统用的就是这个内核)
https://launchpad.net/ubuntu/+source/linux-raspi
用的什么系统就选什么内核。
另外使用第二个链接的源码需要注意,launchpad.net下载的内核代码不是单个压缩包的形式,是orig+diff的形式,加上dsc文件,一共3个文件。使用方法是,3个文件放在同一个目录,使用:
dpkg-source -x dsc_file_name.dsc
命令来生成代码文件夹。
但是我在使用的时候存在一个问题,diff文件里写进脚本的"ln -sf"和"rm -f"操作,不知道是没执行,还是操作权限不够,最终并没有反应到代码上,所以导致很多编译错误。我这里通过把diff文件里的上述两种操作手动操作了一遍,解决了编译问题,亲测换上去使用也是正常的。
内核代码编译
生成/更新.config
生成.config文件的命令如下:
# armhf
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig
# arm64
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
其中最后一个预配置文件需要根据芯片型号选择,此处使用树莓派4B,芯片型号是BCM2711,故选择bcm2711_defconfig。
更新.config文件的命令如下:
# armhf
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
# arm64
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
此命令调用menuconfig对.config中的配置进行修改更新。
另外,arm64的内核,若想实现与系统原先一致的版本号显示方式,在执行完上边两条命令之后编译之前,需要手动打开内核根目录的Makefile,把开头四行版本号的值改成:
VERSION = 5
PATCHLEVEL = 4
SUBLEVEL = 0
EXTTRAVERSION = -1042-raspi
搞定.config文件还有一种方法,从树莓派的 /boot 目录下获得config文件,文件名称为 config-$(uname -r) ,将其更名为 .config ,放在新代码的根目录下。这么做如果代码版本和系统当前内核版本一样的话,就不需要执行上边两个命令了。
编译
编译都是用make,区别是arm64版本不需要指定编译对象,armhf需要指定一下:
# armhf
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j32 zImage modules dtbs
# arm64
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j32
安装
在x86环境编译完成后,如果x86环境安装了samba,可以选择samba共享的方式把内核目录挂载到树莓派,树莓派侧不需要特殊配置,挂载命令:
mount //x.x.x.x/path/to/kernel/ /local/path -o username=x,password=x
然后就可以cd到/local/path内,执行安装操作,把编译机上的编译结果安装在树莓派。
对于armhf,官方似乎没实现它的make install功能,官方提供出来的是手动拷贝命令,所有的命令:
# 安装头文件
sudo make headers_install
# 安装模块
sudo make modules_install
# 安装镜像
sudo cp arch/arm/boot/dts/*.dtb /boot/
sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
sudo cp arch/arm/boot/zImage /boot/kernel7l.img
arm64就比较常规了,所有的命令都是支持的:
# 安装头文件
sudo make headers_install
# 安装模块
sudo make modules_install
# 安装镜像
sudo make install
另外在安装的时候可能会出现img镜像过大,把/boot空间占满而导致失败的情况,如果出现这种情况,只需要在make modules_install命令后边加上INSTALL_MOD_STRIP=1这条参数即可,img镜像会大幅缩小精简。
安装完重启,uname -a,如果显示的内核编译时间和自己编内核的时间一致,就是安装成功了。