樹莓派映象替換核心
1. 為什麼要替換核心
-
樹莓派官方提供的映象中,自帶的核心版本為
6.6.31
-
然而
github
上提供的核心原始碼為6.6.40
,有些微差別 -
此外,後續很有可能進行核心裁剪定製,替換核心是一個無法繞開的工作
2. 獲取核心原始碼
-
github
地址:https://github.com/raspberrypi/linux
-
選擇使用
6.6.y
版本的核心
-
將其複製到
ubuntu
中 -
解壓
$ unzip linux-rpi-6.6.y.zip
-
進入核心原始碼目錄
$ cd linux-rpi-6.6.y
3. 獲取交叉編譯工具鏈
-
我所選用樹莓派映象中的
gcc
版本為12.2.0 -
為了避免出現
glibc
版本不一致的問題,同樣使用12.2.0
版本的交叉編譯工具鏈 -
下載地址:
https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
4. 核心編譯
-
修改頂層
Makefile
,指定目標平臺ARCH
和交叉編譯工具鏈CROSS_COMPILE
-
樹莓派CM4使用的時博通BCM2711的方案,因此使用
bcm2711_defconfig
生成預設配置檔案linux-rpi-6.6.y$ make bcm2711_defconfig
-
menuconfig
配置linux-rpi-6.6.y$ make menuconfig
-
在這裡我需要將
LAN78XX
驅動直接編譯進核心,不作為外部模組
-
開始編譯,核心映象/驅動模組/裝置樹都需要編譯,使用
-j$(nproc)
全核編譯,加快編譯速度linux-rpi-6.6.y$ make Image modules dtbs -j$(nproc)
5. 掛載樹莓派映象到Ubuntu
- 選擇使用使用樹莓派最新的映象
Raspberry Pi OS Lite
,映象下載地址https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_arm64-2024-07-04/2024-07-04-raspios-bookworm-arm64-lite.img.xz
-
解壓,得到
*.img
的映象檔案 -
掛載映象到Ubuntu
# .img映象 jun@ubuntu:$ ls 2024-07-04-raspios-bookworm-arm64-lite.img # 檢視第一個未使用的迴環裝置 jun@ubuntu:$ losetup -f /dev/loop0 # 將.img映象關聯到迴環裝置 jun@ubuntu:$ sudo losetup /dev/loop0 2024-07-04-raspios-bookworm-arm64-lite.img [sudo] password for jun: # 檢視分割槽,檢測到兩個區,其中較小的是系統分割槽,較大的是根檔案系統 jun@ubuntu:$ sudo kpartx -av /dev/loop0 add map loop0p1 (253:0): 0 1048576 linear 7:0 8192 add map loop0p2 (253:1): 0 4481024 linear 7:0 1056768 # 建立系統分割槽掛載目錄 jun@ubuntu:$ mkdir boot # 建立根檔案系統掛載目錄 jun@ubuntu:$ mkdir rootfs # 掛載系統分割槽 jun@ubuntu:$ sudo mount /dev/mapper/loop0p1 ./boot/ # 掛載根檔案系統 jun@ubuntu:$ sudo mount /dev/mapper/loop0p2 ./rootfs/ # 檢視系統分割槽 jun@ubuntu:$ ls ./boot/ bcm2710-rpi-2-b.dtb bcm2710-rpi-zero-2-w.dtb bcm2711-rpi-cm4s.dtb bootcode.bin fixup4db.dat fixup_x.dat kernel8.img start4.elf start_x.elf bcm2710-rpi-3-b.dtb bcm2711-rpi-400.dtb bcm2712d0-rpi-5-b.dtb cmdline.txt fixup4x.dat initramfs_2712 LICENCE.broadcom start4x.elf bcm2710-rpi-3-b-plus.dtb bcm2711-rpi-4-b.dtb bcm2712-rpi-5-b.dtb config.txt fixup_cd.dat initramfs8 overlays start_cd.elf bcm2710-rpi-cm3.dtb bcm2711-rpi-cm4.dtb bcm2712-rpi-cm5-cm4io.dtb fixup4cd.dat fixup.dat issue.txt start4cd.elf start_db.elf bcm2710-rpi-zero-2.dtb bcm2711-rpi-cm4-io.dtb bcm2712-rpi-cm5-cm5io.dtb fixup4.dat fixup_db.dat kernel_2712.img start4db.elf start.elf # 檢視根檔案系統 jun@ubuntu:$ ls ./rootfs/ bin boot dev etc home lib lost+found media mnt opt proc root run sbin srv sys tmp usr var
6. 安裝新核心
-
進入核心原始碼目錄
-
安裝核心模組到根檔案系統
linux-rpi-6.6.y$ sudo env PATH=$PATH make INSTALL_MOD_PATH=../rootfs modules_install
-
安裝標頭檔案到根檔案系統的
usr
目錄linux-rpi-6.6.y$ sudo make headers_install INSTALL_HDR_PATH=../rootfs/usr/
-
安裝
Image
到掛載的boot
分割槽linux-rpi-6.6.y$ sudo cp arch/arm64/boot/Image ../boot/kernel8.img
-
安裝裝置樹檔案
linux-rpi-6.6.y$ sudo cp arch/arm64/boot/dts/broadcom/*.dtb ../boot/ linux-rpi-6.6.y$ sudo cp arch/arm64/boot/dts/overlays/*.dtb* ../boot/overlays/
-
替換
version.h
linux-rpi-6.6.y$ sudo cp include/generated/uapi/linux/version.h ../rootfs/usr/include/linux/version.h
7. 解決核心模組無法載入的問題
-
進入
rootfs
根檔案系統中的驅動存放目錄linux-rpi-6.6.y$ cd ./rootfs/lib/modules/6.6.40-v8/
-
查詢.ko檔案,發現沒有任何核心模組
6.6.40-v8$ find . -name *ko
-
檢查發現,該目錄下有很多
.ko.xz
檔案,原因是make module_install
命令執行時,自動將.ko檔案進行了壓縮,但是這樣會導致核心啟動時無法載入模組,需要將壓縮的.ko檔案進行解壓 -
編寫指令碼
modules_install.sh
用來在系統第一次開機時生成modules.dep
檔案,將該指令碼存放在rootfs/lib/modules/6.6.40-v8/
目錄下,指令碼內容如下#!/bin/bash # modules path MODULES_PATH=/lib/modules/$(uname -r) # 解壓*.ko.xz檔案 module_decompress() { MODULES_XZ_FILES=`find ${MODULES_PATH} -name *ko.xz` for MODULE in ${MODULES_XZ_FILES} do set -x xz -dk ${MODULE} set +x done return 0 } RET=$(cat ${MODULES_PATH}/modules.dep) if [ -z "${RET}" ]; then # modules decompress module_decompress # generate modules.dep depmod # make sure this script executed only once SCRIPT_NAME=$(basename $0) sed -i "/$SCRIPT_NAME/d" /etc/rc.local # reboot reboot else echo "modules already installed!" fi exit 0
-
給指令碼以可執行許可權
6.6.40-v8$ sudo chmod 777 modules_install.sh
-
在根檔案系統下的
etc/rc.local
中新增如下內容,使module_install.sh
指令碼開機自啟動# modules_install /bin/bash /lib/modules/$(uname -r)/modules_install.sh &
8. 選擇核心
- 修改
boot
分割槽下的config.txt
,選擇使用新的核心$ sudo vi ./boot/config.txt
- 在
config.txt
末尾新增如下內容kernel=kernel8.img
9. 取消映象掛載
- 取消
5. 掛載樹莓派映象到Ubuntu
的映象掛載jun@ubuntu:$ ls 2024-07-04-raspios-bookworm-arm64-lite.img boot rootfs jun@ubuntu:$ sudo umount ./boot jun@ubuntu:$ sudo umount ./rootfs jun@ubuntu:$ sudo losetup -d /dev/loop0
10. 映象燒錄
- 參考之前的文章:樹莓派CM4(一):映象燒錄
11. 檢視核心是否替換成功
- 開機,首次開機時系統會自動重啟兩次,屬正常現象
- 進入系統後檢視核心版本,核心版本
6.6.40
,替換成功
# uname -a
Linux IG-210 6.6.40-v8 #2 SMP PREEMPT Tue Aug 27 14:04:24 CST 2024 aarch64 GNU/Linux