【树莓派】Linux内核编译

2023-11-13

【树莓派】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即可。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【树莓派】Linux内核编译 的相关文章

  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a
  • 快速像素绘图库

    我的应用程序以每像素的方式生成 动画 因此我需要有效地绘制它们 我尝试过不同的策略 库 但结果并不令人满意 尤其是在更高分辨率的情况下 这是我尝试过的 SDL 好的 但是慢 OpenGL 像素操作效率低下 xlib 更好 但仍然太慢 svg
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost
  • 如何构建任务“gems:install”

    我正在将 Rails 应用程序部署到 Linux 服务器 并且缺少一些 rake 任务 包括 rake gems install 和 rake db 我正在运行来自 GEM 的 Rails 2 3 4 为什么是这样 我该如何解决 我可以以某
  • 在 Mac OSX 上交叉编译 x86_64-unknown-linux-gnu 失败

    我尝试将我的 Rust 项目之一编译到 x86 64 unknown linux gnu 目标 cargo build target x86 64 unknown linux gnu Compiling deployer v0 1 0 fi
  • 警告:请求的映像平台 (linux/amd64) 与检测到的主机平台 (linux/arm64/v8) 不匹配

    警告 请求的映像平台 linux amd64 与检测到的主机平台 linux arm64 v8 不匹配 并且未请求特定平台 docker 来自守护程序的错误响应 无法选择具有功能的设备驱动程序 gpu 我在 mac 上尝试运行此命令时遇到此
  • 后台分叉无法正常工作[重复]

    这个问题在这里已经有答案了 我运行这个程序 在前景和背景中 int main int pid printf App Start pid d n getpid while 1 pid fork if pid 0 printf Child n
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • 在 Ubuntu 中找不到 X11/Xlib.h

    我试图在 Linux 上使用 open gl 编写一个相当简单的程序 但在编译时它说 编译拇指 egl 我对 GL 完全陌生 不知道出了什么问题 快速搜索使用 apt search Xlib h 打开 libx11 dev 包 但纯 Ope
  • 如何将后台作业的输出分配给 bash 变量?

    我想在 bash 中运行后台作业并将其结果分配给一个变量 我不喜欢使用临时文件 并且希望同时运行多个类似的后台任务 root root var echo hello world root root echo var hello world
  • 配置:错误:无法运行C编译的程序

    我正在尝试使用 Debian Wheezy 操作系统在我的 Raspberry Pi 上安装不同的软件 当我运行尝试配置软件时 我尝试安装我得到此输出 checking for C compiler default output file
  • 如何访问 mmaped /dev/mem 而不导致 Linux 内核崩溃?

    我有一个简单的程序 尝试访问用户空间中的物理内存 其中内核存储第一个结构页 在 64 位机器上 该地址是 内核虚拟地址 ffffea0000000000 物理地址 0000620000000000 我正在尝试通过用户空间中的 mmap 访问
  • dlopen 或 dlclose 未调用信号处理程序

    我在随机时间内收到分段错误 我注册了信号 但发生分段错误时未调用信号处理程序 include
  • 找出 Linux 上的默认语言

    有没有办法从C语言中找出Linux系统的默认语言 有 POSIX API 可以实现这个功能吗 例如 我想要一个人类可读格式的字符串 即德语系统上的 German 或 Deutsch 法语系统上的 French 或 Francais 等 有类
  • 从 Python 访问 802.11 无线管理帧

    我想从 Linux 上的 Python 嗅探 802 11 管理 探测请求 帧 这可以从 Scapy 中实现 如下所示 coding utf 8 from scapy all import def proc p if p haslayer
  • 从 php/linux 获取 pdf 的布局模式(横向或纵向)

    给定一个 PDF 如何使用 PHP lib 或 Linux 命令行工具获取 PDF 的布局模式 或相对宽度 高度 Using http www tecnick com public code cp dpage php aiocp dp tc
  • 未找到 Gem 命令

    我已经在 Ubuntu 10 10 32 位上安装了 gem apt get install gem y 但当我尝试跑步时 gem install something gem 我收到未找到命令的错误 bash gem command not
  • 如何从 Linux 内核模块获取使用计数?

    我对正在开发的内核模块的使用计数有疑问 我想打印它以进行调试 如何从模块代码中获取它 有问题的内核版本 Linux 2 6 32 module refcount http lxr linux no linux v2 6 34 1 inclu
  • 如何重命名 .tar.gz 文件而不提取内容并在 UBUNTU 中创建新的 .tar.gz 文件?

    我有一个命令将创建一个新的 tar gz现有文件中的文件 sudo tar zcvf Existing tar gz New tar gz 该命令将创建一个新的New tar gz从现有的文件Existing tar gz file 谁能告
  • XAMPP Windows 上的 Php Cron 作业

    嗯 我是这个词的新手CRON 据我所知 这是一个Unix安排特定操作在定义的时间间隔后执行的概念 我需要运行一个php文件 每小时更新一次数据库 但我的困惑在于安排执行 我在用XAMPP用于 Windows 7 上的本地开发测试 我发现了什

随机推荐

  • jdbc mysql 重连_mysql重连的问题

    应用在长时间不连mysql后会与mysql断开 再次链接mysql时会报无法连接数据库的异常 所以连接的配置需要稍微改一下 factory org apache naming factory BeanFactory driverClass
  • LABVIEW连接MySQL进行读写更新查询操作并仿真

    相关软件的准备 欢迎访问我的小站 我的软件环境是LabVIEW 2018 32位 的 这个很重要 因为不同位数的labview需要安装不同位数的Connector odbc 还需要安装visio的运行环境 这个需要提前准备 Mysql的安装
  • 华为数字化转型之道 平台篇 第十三章 变革治理体系

    第十三章 变革治理体系 约翰 科特在 领导变革 一书中说 变革的领导团队既需要管理能力 也需要领导能力 他们必须结合起来 前面我们也谈到 数字化转型不仅是技术的创新 更是一项系统工程和企业真正的变革 企业要转型成功 既需要各个组织的积极参与
  • python---matplotlib详细教程(完结)

    文章每个图都带有案例 欢迎访问 目录 如何选择合适的图表 绘制简单的折线图 图表常用设置 颜色设置 线条样式和标记样式 画布设置 设置坐标轴标题 plt rcParams font sans serif SimHei 解决缺失字体 设置坐标
  • 【三】springboot整合token(超详细)

    springboot篇章整体栏目 一 springboot整合swagger 超详细 二 springboot整合swagger 自定义 超详细 三 springboot整合token 超详细 四 springboot整合mybatis p
  • 【华为OD机试真题 python】组装新的数组【2023 Q1

    题目描述 组装新的数组 给你一个整数M和数组N N中的元素为连续整数 要求根据N中的元素组装成新的数组R 组装规则 1 R中元素总和加起来等于M 2 R中的元素可以从N中重复选取 3 R中的元素最多只能有1个不在N中 且比N中的数字都要小
  • python格式化输出,format,数据类型转换。

    输出 计算机给用户输出的内容 是一个由里到外的一个过程 例如python语言中的print函数 输入 则相反 例如input函数 一 输出有普通的输出 也有格式化输出 普通输出 类似于 print hello word 这样直接打印 格式化
  • 为高尔夫比赛砍树

    为高尔夫比赛砍树 你被请来给一个要举办高尔夫比赛的树林砍树 树林由一个 m x n 的矩阵表示 在这个矩阵中 0 表示障碍 无法触碰 1 表示地面 可以行走 比 1 大的数 表示有树的单元格 可以行走 数值表示树的高度 每一步 你都可以向上
  • 系统篇: squashfs 文件系统

    一 squashfs简介 Squashfs是一套基于Linux内核使用的压缩只读文件系统 该文件系统能够压缩系统内的文档 inode以及目录 文件最大支持2 64字节 特点 数据 data 节点 inode 和目录 directories
  • 虚幻C++ http请求

    直接上代码 Fill out your copyright notice in the Description page of Project Settings pragma once include CoreMinimal h inclu
  • 测试岗?从功能测试进阶自动化测试开发,测试之路不迷茫...

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • Mock框架应用(四)-Mock 重定向请求

    例一 先新建json配置文件重定向到www baidu com 启动mock服务 description 实现重定向的请求 request uri redirect redirectTo https www baidu com respon
  • Go并发(goroutine)及并发常用模型的实现

    前言 Go 语言最吸引人的地方是它内建的并发支持 作为天然支持高并发的语言 写并发比java和python要简单方便的多 在并发编程中 对共享资源的正确访问需要精确的控制 在目前的绝大多数语言中 都是通过加锁等线程同步方案来解决这一困难问题
  • 疯壳-MTK智能电话手表开发整板测试

    目录 内容简介 3 第一节 开机 4 第二节 绑定 5 第三节 功能测试 9 3 1 屏幕测试 9 3 2 SIM通信测试 11 3 3 SIM 测试 12 3 4 GPS测试 14 3 5 手表对时 18 官网地址 https www f
  • 1449 砝码称重 51NOD

    1449 砝码称重 题目来源 CodeForces 基准时间限制 1 秒 空间限制 131072 KB 分值 40 难度 4级算法题 现在有好多种砝码 他们的重量是 w0 w1 w2 每种各一个 问用这些砝码能不能表示一个重量为m的东西 样
  • flink中idea配置pom.xml

  • JS之预解析

    javascript 的预解析 个人理解 就是js代码在执行之前 会在相应的执行环境中 预先把 一些东西解析到内存 如果理解错误 请多多指正 一 那究竟预先解析哪些东西那 答 预先解析 function 和 var 二 还有就是预解析的顺序
  • 分布式一致算法

    一 拜占庭将军问题 拜占庭将军问题 拜占庭派多支军队去围攻一个敌人 将军不确定军队中是否有叛徒 叛徒可能擅自变更进攻决定 至少一半以上的军队同时进攻才可以取胜 在这种状态下 拜占庭将军们能否找到一种分布式的协议来让他们能够远程协商 从而就进
  • go 进阶 go-zero相关: 二. 服务启动与路由,中间件注册,请求接收底层原理

    目录 一 问题概述 二 底层源码分析 涉及到的一些结构体简介 初始化 中间件的预设置 路由注册与中间件的处理 启动服务到触发net http 接收请求的处理 三 总结 一 问题概述 了解go zero底层也是基于net http标准库实现h
  • 【树莓派】Linux内核编译

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