操作系统基础 | 2.3 初试linux内核实验

注意:本教学实验因为使用较早版本的树莓派Linux内核,内核源码的symlink仅适配Linux系统,请使用Linux平台主机进行交叉编译,若要使用window主机编译请更换使用的内核

1. 下载适用于树莓派的内核源码

一般项目可以直接去 kernel.org 下载 Linux 源码,但本课程针对树莓派,需要用树莓派官方维护的内核版本(在 https://github.com/raspberrypi)。 在你的工程目录下,新建 linux_source 文件夹用于存放源码和编译文件:

1
2
mkdir linux_source
cd linux_source
下载指定版本的树莓派内核源码(此过程可能需要20-30分钟):
1
wget https://github.com/raspberrypi/linux/archive/raspberrypi-kernel_1.20210527-1.tar.gz
解压源码包:
1
tar -xzf raspberrypi-kernel_1.20210527-1.tar.gz
解压后会得到一个新目录,建议用 mv 命令重命名为 linux,便于后续操作。解压完成后请删除 .tar.gz 文件以节省空间。

进入 linux 目录,运行以下命令查看内核版本:

1
make kernelversion
并用文本编辑器(如 emacs、vim、nano)打开 Makefile,查看前几行定义的内核版本常量,记录 NAME 常量的值。

2. 针对树莓派 4/4B 的设备树修改

如果你使用的是 Raspberry Pi 4 或 4B,需要修改设备树文件 arch/arm/boot/dts/bcm2711.dtsi,找到 arm-pmu 条目,将 compatible 行改为:

1
compatible = "arm,cortex-a72-pmu", "arm,cortex-a15-pmu", "arm,armv8-pmuv3";

3. 配置交叉编译环境

添加交叉编译器和新版 gcc 到 PATH(并将以下两行添加到 ~/.bashrc 文件末尾,确保下次登录自动生效):

1
2
3
4
# 将交叉编译工具链添加到PATH
module add arm-rpi
# 将c编译器添加到PATH
module add gcc-8.3.0

注意:如果使用wsl2等,linux并不自带environment-modules的情况,需要手动安装编译工具并添加PATH: 更新包列表 sudo apt update 安装依赖,如果出现包依赖版本问题,请参照本站wsl2分类下的文章“在wsl2安装ros2遇到的一些坑”解决 sudo apt install bc bison flex libssl-dev make libc6-dev libncurses5-dev 安装32位工具链 sudo apt install crossbuild-essential-armhf 检查是否已添加到PATH arm-linux-gnueabihf-gcc --version

4. 配置内核

对于 Raspberry Pi 3B+,运行:

1
make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig

对于 Raspberry Pi 4/4B,运行:

1
make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig
这会生成树莓派的默认内核配置。

5. 自定义内核配置

进入菜单配置界面:

1
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
  • 在 "General setup" -> "Local version" 里,添加你的唯一标识(如 -v7-v7l 后面加你的名字,无空格)。
  • 修改 "Preemption Model" 选项为 "Preemptible Kernel (Low-Latency Desktop)",以获得更低延迟的抢占模型。
  • 启用 ARM 性能监控单元驱动("Kernel Performance Events and Counters"),并确保 "Profiling support" 也已启用。
  • 任选一个有趣的选项,按 H 键查看简介,记录该选项的名称、简介和符号(symbol),并简述为何选择 "Preemptible Kernel (Low-Latency Desktop)"(提示:该模式适合需要低延迟响应的场景,如桌面或实时应用)。

保存并退出配置。


6. 编译内核

记录编译开始和结束时间

1
date>>time.txt; make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs; date>>time.txt

注意:如果使用wsl2出现类似以下错误 Error: selected processor does not support 'dmb ish' in ARM mode 请尝试指定编译环境变量(编译参数会报错冲突):

1
2
3
4
sudo su
export KCFLAGS="-march=armv7-a -mfpu=vfpv3"
make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
unset KCFLAGS

编译完成后,创建用于存放模块的目录:

1
mkdir ../modules

安装内核模块:

1
make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=../modules modules_install

7. 回答与说明

  • cat time.txt 查看编译所用时间。
  • 说明为何要用交叉编译器:因为 linuxlab 服务器的架构与树莓派不同,必须用交叉编译器生成适用于 ARM 架构的内核和模块。