树莓派镜像替换内核

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. 获取交叉编译工具链

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

  • 解压,得到*.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
  • 在文件末尾添加如下内容,表示使用新的内核启动
    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. 镜像烧录

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

树莓派CM4(四):树莓派镜像替换内核的更多相关文章

  1. 【树莓派】使用树莓派制作img镜像(一)

    最近一直在折腾树莓派,前几天装了10台设备,最近又来了15台开发板子.基本每台设备都需要进行如下操作: 1.安装树莓派OS,并配置键盘.时区.语言编码格式等: 2.新增组.用户.配置静态IP地址: 3 ...

  2. 【树莓派】制作树莓派最小镜像:img裁剪瘦身

    制作树莓派镜像,可以参考这篇文章:http://blog.csdn.net/talkxin/article/details/50456282 摘录部分要点内容如下(如果作者不允许转载,请联系即删除): ...

  3. 【树莓派】制作树莓派所使用的img镜像(一)

    最近一直在折腾树莓派,前几天装了10台设备,最近又来了15台开发板子.基本每台设备都需要进行如下操作: 1.安装树莓派OS,并配置键盘.时区.语言编码格式等: 2.新增组.用户.配置静态IP地址: 3 ...

  4. [原创]树莓派CM4配置GPIO复用为i2c

    1.简介 项目中需要控制各种外设的电源,正常应该是通过GPIO进行控制,但是树莓派CM4的GPIO管脚有限,因此需要使用i2c扩展IO 查阅CM4-datesheet发现GPIO22和GPIO23可以 ...

  5. 树莓派3B/3B+ 清华镜像系统和安装中文输入法Fcitx及Google拼音输入法

    你还在为树莓派无法安装中文输入法而到处找教程吗? 你还在为树莓派每次下载都要远隔重洋获取资源,龟速下载而烦恼吗? 为了解决这个问题,在这篇树莓派教程中,我将手把手叫你怎样安装 清华镜像系统和中文输入法 ...

  6. fastboot烧录镜像--VTS&GSI镜像替换

    fastboot简介 Android提供的原生工具,主要用于替换镜像. 源码在SDK工程中,/system/core/fastboot目录下 安卓分区&镜像 见链接分区和映像--google官 ...

  7. 建立树莓派raspberry交叉编译环境以及编译内核

    最近买了一个树莓派,玩了几天,虽然已经有很多人玩了,现在玩好像有点晚了,但是他确实是个好东西,学好它,对嵌入式的整个开发流程也就会熟悉很多.虽然性能不是很强和现在的BB-BLACK比有点慢了,但是它便 ...

  8. 树莓派CM4 wifi频繁断开连接

    CM4核心板上自带的wifi模块连接上华为/小米的路由器5G热点以后,会频繁断开连接,断开连接前使用 iw dev 查看wifi信息如下: phy#0 Unnamed/non-netdev inter ...

  9. 【树莓派】使用树莓派制作img镜像(二)

    树莓派制作的镜像,需要如何使用,这里直接引用目前树莓派官方的文章,不再重复描述: 参考:http://shumeipai.nxez.com/2013/08/31/usb-image-tool.html ...

  10. 【树莓派】制作树莓派所使用的img镜像(二)

    树莓派制作的镜像,需要如何使用,这里直接引用目前树莓派官方的文章,不再重复描述: 参考:http://shumeipai.nxez.com/2013/08/31/usb-image-tool.html ...

随机推荐

  1. 【Error】mysql的error.log中ranges: 268 max_threads: 4 split: 268 depth: 2是什么意思?

    2021-12-08T09:36:39.612332+08:00 44213799 [Note] [MY-011825] [InnoDB] Parallel scan: 4 2021-12-08T09 ...

  2. package-lock.json 文件

    今天有同事找到我说,本地js 编译不过,编译不过的代码如下 const host = window?.location?.host || 'localhost'; 是option chaining, ...

  3. 防火防盗防CDN流量盗刷

    没想到自己的小破站也逃不掉被攻击的命,分分钟就给我刷欠费了. 本来不想写这篇文章的,但看到好多大佬(小林coding. JavaGuide)近期cdn都被盗刷了. 还是来提醒下大家,防火防盗防cdn流 ...

  4. .NET周刊【7月第1期 2024-07-07】

    国内文章 学习.NET 8 MiniApis入门 https://www.cnblogs.com/hejiale010426/p/18280441 MiniApis是ASP.NET Core中的轻量级 ...

  5. 探索Nuxt.js的useFetch:高效数据获取与处理指南

    title: 探索Nuxt.js的useFetch:高效数据获取与处理指南 date: 2024/7/15 updated: 2024/7/15 author: cmdragon excerpt: 摘 ...

  6. Curve 进入 CNCF Sandbox,完善统一云原生开源存储拼图

    2022 年 6 月 15 日,云原生计算基金会 (CNCF) 宣布,分布式存储系统 Curve 被正式接纳为 CNCF 沙箱(Sandbox)项目.Curve 由网易数帆开源,提供块存储和文件存储能 ...

  7. git 怎么将某个开发分支最近几次的提交合并成一次提交

    1. 切换到开发分支: git checkout dev 2. 运行交互式 rebase 命令,并指定要合并的提交数量(在这个例子中是最近的3次提交): git rebase -i HEAD~3 3. ...

  8. oeasy教您玩转vim - 50 - # 命令行效率

    ​ 命令行效率 回忆上节课内容 总结 我们上次研究的是范围命令执行方法 批量控制缩进 :20,40> 批量执行普通模式下的命令 :4,10normal A; 直接切换到全屏命令模式 ex-mod ...

  9. C# WinForm遍历窗体控件的3种方法

    1.循环遍历 private void GetControls(Control fatherControl) { Control.ControlCollection sonControls = fat ...

  10. Odoo 基于Win10搭建基于Win10搭建odoo14开发环境搭建

    实践环境 win10 Python 3.6.2 odoo_14.0.latest.tar.gz 下载地址: https://download.odoocdn.com/download/14/src?p ...