树莓派内核编译

2023-11-12

一、概述

树莓派的github主页:https://github.com/raspberrypi,里面包含了linux源码、交叉编译工具链等内容。

对于我们要用到的有两个仓库:

https://github.com/raspberrypi/linux?内核源码

https://github.com/raspberrypi/tools?交叉编译工具链(仅在交叉编译时用到)

注:

1、树莓派里安装的系统镜像版本要和kernel代码对应。
因为树莓派系统是在不断开发和升级的,如果你的树莓派使用的是某个时间的系统镜像,那么最好也使用当时的kernel代码。

2、关于内核编译方法,官网有很详细的介绍:https://www.raspberrypi.org/documentation/linux/kernel/building.md,这里算是翻译和补充。

3、以下编译过程在树莓派1和树莓派3B上测试ok。

================================================================================================

二、ubuntu里交叉编译

1、获取交叉编译工具和源码
源码:

	git clone git@github.com:raspberrypi/linux

交叉编译工具:

git clone git@github.com:raspberrypi/tools

2、配置编译环境变量

2.1 手动配置环境变量
编译工具下载后,

在64位ubuntu上编译我们需要的编译工具bin文件在:
tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin 
目录下,将此目录添加到环境变量PATH中,添加方法:
PATH=$PATH:/home/nicek/githubProjects/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin

如果是在32位系统中编译则要选择32位的交叉编译工具。

配置完成之后可以用编译工具命令查看到版本号:

arm-linux-gnueabihf-gcc -v

之后,所有的make命令都要指明一些环境变量:

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7

ARCH=arm	指明当前要编译arm,虽然树莓派是64位的,这里仍然选择arm,而不是arm64。
CROSS_COMPILE	指明交叉工具链名称。
KERNEL	指明kernel类型,树莓派1设置为kernel,树莓派2、3设置为kernel7。

每次make都需要指明这些环境变量,如:

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage

2.2 自动配置环境变量

上面这些环境变量每次命令都要写很麻烦,可以通过export一次设置:

export PATH=$PATH:/home/nicek/githubProjects/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7

之后在本终端里执行的所有命令都带有这些环境变量信息。

此 export 命令可以写成一个脚本,然后在编译前在终端里source一下这个脚本即可设置好所有的环境变量。就像android编译前也要先source一下envsetup.sh一样。

1 #!/bin/bash

2 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

3 export PATH="$PATH:$DIR/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/"

4 export ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7

上述命令中的路径可能和你实际不同,注意修改。

export环境变量后,在本终端里的后续命令都可以不用再指明这些环境变量,如:

配置之前的命令:ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig
配置之后的命令:make menuconfig

3、配置config

linux源码中有很多工程:

树莓派1的工程是bcmrpi_defconfig;

树莓派2、3的工程是bcm2709_defconfig。

3.1 使用源码里自带的config

把厂家的config 变成 自己的config:两个命令

命令1:

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig

命令2:(需要ncurse库)

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig

此命令功能是获取bcm2709_defconfig的配置到 .config里。

我们可以直接用工程里的配置,但这样的话可能会丢失原来使用的树莓派的配置,这里提供一个方法可以获取当前正在使用的树莓派的config。


3.2 获取当前树莓派的config

已经开机的树莓派上会有这个节点:/proc/config.gz,从这个节点可以获取本树莓派的config。

如果没有这个节点的话则需要先加载模块:

sudo modprobe configs

把 config.gz 内容复制到要编译的电脑上:

scp pi@[ip]:/proc/config.gz .

解压,保存为.confg文件。

zcat config.gz > .config

注:必须在linux环境下解压,在mac下会乱码。

把此config文件复制到linux源码的根目录。


4、编译

安装必要的库:

sudo apt-get install bc

sudo apt-get install libncurses5-dev libncursesw5-dev

sudo apt-get install zlib1g:i386

sudo apt-get install libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5

1、执行menuconfig

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig

如果没什么改的就不用执行这一步。

2、编译

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs

?2>&1 | tee build.log //这句话是错误处理相关

以n进程编译。不指明几进程的话则默认以单进程编译。

3、打包zImage文件

直接用linux源码包里的工具:

./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img


在本目录生成一个kernel_new.img文件,这个文件就是要放到sd卡中的文件。
注:网上很多地方说的用 tools/mkimage/imagetool-uncompressd.py 的方法不行!!

5、挂载树莓派sd卡,并安装编译出的DIRECTLY 到sd卡

dmesg查看目标SD卡是否载入
sdb:sdb1  sdb2

把树莓派的sd卡插入ubuntu系统电脑,树莓派的sd卡有两个分区:

一个fat分区,是boot相关的内容,kernel的img文件就放在这个分区里;

一个是ext4分区,也就是系统的根目录分区。

可以在linux目录下创建两个文件夹,分别用来挂载树莓派的两个分区

mkdir data1
mkdir data2

挂载:

sudo mount /dev/sdb1 data1
sudo mount /dev/sdb2 data2

我们生成的文件涉及到这两个分区的内容,一般插入ubuntu后会自动挂载,fat分区可以不用root权限操作,ext4分区需要root权限操作。

两个分区具体挂载在什么地方可以自己决定,以下用[fat]表示boot挂载的路径,[ext4]表示ext4挂载的路径。

1、安装modules
-----(替换下文的ext4路径为自己挂载的路径) 在linux-rpi-4.14-y目录下操作

但是再此目录下没有挂载的data1和2 所以要添加data1或者data2的绝对路径
少了这步会出现无限网卡不能用的情况 HDMI wifi io

sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=[ext4] modules_install

操作ext4分区,需要root权限。

2、更新 kernel.img 文件

为防止刷机失败出现树莓派跑不起来,需要现在data1 (也就是boot)中把原来的kernel7.img 文件进行备份

拷贝完成后查看文件是否拷贝损坏:

md5sum kernel_new.img 

md5sum /home/gin/data1/kernel7.img

前面已经用 mkknlimg 工具打包了kernel_new.img文件了,把它复制到boot分区并配置使用即可:

cp kernel_new.img [fat]/

编辑 [fat]/config.txt 文件,在最后加入一行:

kernel=kernel_new.img

3、复制其他相关文件

cp arch/arm/boot/dts/overlays/README [fat]/overlays/
cp arch/arm/boot/dts/.*dtb* [fat]/


cp arch/arm/boot/dts/overlays/.*dtb* [fat]/overlays/


cp arch/arm/boot/dts/overlays/README [fat]/overlays/

更新完成后插回树莓派即可开机,开机后可以用 uname -a 命令查看kernel信息已经改变。

=================================================================================================

三、树莓派本地编译

树莓派上本地编译和上面交叉编译原理基本相同,由于是本地编译,在编译工具和环境变量配置方面还简单一些。
树莓派上编一次内核花了将近2小时。

1、获取源码

git clone git@github.com:raspberrypi/linux

2、配置编译环境

在ubuntu里交叉编译时需要配置的环境变量有:

PATH: 添加交叉工具链的目录

ARCH: 配置成arm

CROSS_COMPILE: 配置成ubuntu上使用的交叉工具链arm-linux-gnueabihf- KERNEL=kernel7
KERNEL: 配置成kernel7

而在树莓派本地编译:

关于交叉工具链,本身的编译工具就可以编译给自己使用,所以不用配置;

只需要配置 KERNEL=kernel7 即可。



和上面相同,可以用 export KERNEL=kernel7,一次设置之后此终端里所有命令都带有此环境变量。
也可以更进一步写成脚本,不过这里这一行命令很简单,不写脚本也可以。

3、配置config
和上面一样,

树莓派1使用的是?bcmrpi_defconfig,

树莓派2、3使用的是?bcm2709_defconfig。

例:KERNEL=kernel7 make bcm2709_defconfig

如果要使用树莓派自带的config的话:

sudo modprobe configs?# 加载模块

zcat config.gz > .config?# 获取配置

4、编译

安装必要的库:

sudo apt-get install bc

sudo apt-get install libncurses5-dev libncursesw5-dev

sudo apt-get install zlib1g

sudo apt-get install libc6

1、执行menuconfig

KERNEL=kernel7 make menuconfig
没什么要改的话就不用执行这一步。

2、编译

KERNEL=kernel7 make -j4 zImage modules dtbs 2>&1 | tee build.log

以n进程编译。不指明几进程的话则默认以单进程编译。

3、打包zImage文件
直接用linux源码包里的工具:

./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img

在本目录生成一个kernel_new.img文件,这个文件就是要放到sd卡中的文件。

5、更新系统

1、安装模块

sudo make modules_install

2、复制dtb文件

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/

3、更新kernel.img文件

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

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

  • 如何在文件夹中的 xml 文件中 grep 一个单词

    我知道我可以使用 grep 在这样的文件夹中的所有文件中查找单词 grep rn core 但我当前的目录有很多子目录 我只想搜索当前目录及其所有子目录中存在的所有 xml 文件 我怎样才能做到这一点 我试过这个 grep rn core
  • 了解 Linux oom-killer 日志

    我的应用程序被 oom killer 杀死了 它是在实时 USB 上运行的 Ubuntu 11 10 无需交换 PC 具有 1 Gig 的 RAM 唯一运行的应用程序 除了所有内置的 Ubuntu 东西 是我的程序 flasherav 请注
  • pthread_self() 返回的线程 ID 与调用 gettid(2) 返回的内核线程 ID 不同

    这句话来自于pthread self 的手册页 http linux die net man 3 pthread self 那么 我应该根据什么来决定是否应该使用pthread self or gettid确定哪个线程正在运行该函数 两者都
  • 如何在linux中使用iptables将http和https流量转发到透明代理[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这个问题似乎不是关于主要由程序员使用的特定编程问题 软件算法或软件工具 help on topic 如果您认为该问题与主题相关另一个 St
  • 如何使用 go1.6.2 构建 linux 32 位

    有没有任何组合GOARCH and GOOS我可以设置哪些值来构建 ELF 32 位二进制文 件 GOOS linux and GOARCH 386 更多示例 架构 32 bit gt GOARCH 386 64 bit gt GOARCH
  • 在嵌入式系统上将内核控制台发送到哪里?

    我正在开发一个嵌入式系统 该系统当前通过串行端口 1 上的控制台输出启动 Linux 使用启动加载程序中的控制台启动参数 然而 最终我们将使用这个串行端口 内核控制台输出的最佳解决方案是什么 dev null 能否以某种方式将其放在 pty
  • 为什么 call_usermodehelper 大多数时候都会失败?

    从内核模块中 我尝试使用 call usermodehelper 函数来执行可执行文件 sha1 该可执行文件将文件作为参数并将文件的 SHA1 哈希和写入另一个文件 名为输出 可执行文件完美运行 int result 1 name hom
  • aarch64 Linux 硬浮点或软浮点

    linux系统有arm64 有arm架构armv8 a 如何知道 Debian 运行的是硬浮动还是软浮动 符合 AAPCS64 GNU GCC for armv8仅提供硬浮动aarch64工具链 这与 armv7 a 的 GCC 不同 后者
  • Apache LOG:子进程 pid xxxx 退出信号分段错误 (11)

    Apache PHP Mysql Linux 注意 子进程 pid 23145 退出信号分段错误 11 tmp 中可能存在 coredump 但 tmp下没有找到任何东西 我怎样才能找到错误 PHP 代码中函数的无限循环导致了此错误
  • Numpy 导入失败

    在 RPi2 上 我使用 pip review 升级了所有软件包 但 numpy 不再工作 我尝试通过 pip 和 apt 卸载并重新安装 numpy 但我没有运气 Apt 安装 numpy 1 12 1 如果我尝试安装它不会通过 pip
  • 如何指定配置脚本的包含目录

    我的工作场所有一个 Linux 系统 其中包含相当旧的软件包 并且没有 root 访问权限 我正在从源代码编译我需要的包 prefix somewhere in homedir 我的问题是我只是不知道如何说服配置在特定目录中查找头文件 源码
  • Linux下单个目录下文件过多会怎样?

    如果一个目录中有大约 1 000 000 个单独的文件 大部分大小为 100k 其中没有其他目录和文件 是否会以任何其他可能的方式降低效率或产生缺点 ARG MAX 会对此提出异议 例如 rm rf 在目录中时 会说 参数太多 想要执行某种
  • 在 vimrc 中切换匹配

    我的 vimrc 文件中有以下几行 hi ExtraWhitespace cterm NONE ctermbg green ctermfg green guibg green guifg green match ExtraWhitespac
  • Linux >2.6.33:可以使用 sendfile() 来实现更快的“猫”吗?

    必须将大量大文件连接成一个更大的单个文件 我们目前使用 cat file1 file2 output file but are wondering whether it could be done faster than with that
  • 命名互斥体的 Mono 替代方案

    在 Windows NET 上 命名的互斥体可用于同步多个进程 不幸的是 Mono 在 Linux 上不太支持这一点 他们的发行说明 http www mono project com Release Notes Mono 2 8 Shar
  • EULA 接受 Bash 脚本

    我有一个尝试安装垃圾箱的脚本 除了 bin 在 more 中打开 EULA 之外 一切正常 在脚本再次开始并自行完成安装之前 您必须手动 ctrl c 退出此 more 实例 因为这更多的是逃离 shell 所以脚本在打开后不知道要运行什么
  • 删除 Python 中某些操作的 root 权限

    在我的 Python 脚本中 我执行了一些需要 root 权限的操作 我还创建并写入文件 我不想由 root 独占所有 而是由运行我的脚本的用户独占所有 通常 我使用以下命令运行脚本sudo 有办法做到上述吗 您可以使用以下方式在 uid
  • 设置 Vim 背景颜色

    当我尝试更改背景颜色时 vimrc或者直接在 Vim 中使用以下命令 set background dark 这根本不影响我的背景 也没有light选项 不过 当我运行 gvim 时 看起来还不错 有没有办法在不更改 Konsole 设置的
  • PHP 日志文件颜色

    我正在编写一个 PHP 日志文件类 但我想为写入文件的行添加颜色 我遇到的问题是颜色也会改变终端的颜色 我想要实现的是仅更改写入日志文件的行的颜色 class logClass extends Singleton private funct
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似

随机推荐

  • 类加载器是否为空

    package com bzu csh 项目名称 Test1 类名称 Test2 类描述 创建人 admin 创建时间 2017年1月7日 下午9 41 36 修改人 admin 修改时间 2017年1月7日 下午9 41 36 修改备注
  • 数据可视化之折线图绘制

    使用python中的matplotlib绘制折线图 环境需求 python 或者anaconda pycharm 和第三方库matplotlib 首次先绘制简单的折线图 其他的参数可以在使用熟练后一点一点的加入 import matplot
  • 计算机网络课程笔记

    学习MOOC华南理工计算机网络课程笔记 第1章 概述 1 1 为什么要学习计算机网络 1 2 互联网发展史 1 3 常用的基本概念 1 4 参考模型 1 5 参考模型相关概念 1 6 本课程的组织 第2章 物理层 2 1 物理层概述 2 2
  • JNI编程—JNI基础

    什么是JNI 怎么使用 JNI Java Native Interface 它是Java平台的一个特性 并不是Android系统特有的 其实主要是定义了一些JNI函数 让开发者可以通过调用这些函数实现Java代码调用C C 的代码 C C
  • python 如何编写一个自己的包

    python 如何编写一个自己的包 先写function 内容 package wadepypk ls init py f1 py f2 py f1 py def show print in pkg f show f2 py def sho
  • unix bsd linux gun   粗略解释

    最早的unix是开放的 很多组织对unix都有修改 期中比较有名的就是伯克利大学的修改版本 叫做bsd 是unix的分支 由于bsd的协议允许你直接使用 修改他的代码 并且可以作为商业用途 所以很多公司的unix都是从bsd衍生过来的 比如
  • mongodb学习笔记一:mongodb安装与介绍

    一 前言 最近开始学习非关系型数据库MongoDB 却在博客园上找不到比较系统的教程 很多资料都要去查阅英文网站 效率比较低下 本人不才 借着自学的机会把心得体会都记录下来 方便感兴趣的童鞋分享讨论 部分资源出自其他博客 旨将零散知识点集中
  • C/C++函数模板template

    1 说明 当函数处理功能相似 函数名相同 但是参数个数或者类型有区别 我们知道实现的方式是依靠函数重载 overload 但是如果仅函数参数或返回数的类型不同 我们想到靠函数模板解决这个问题 不仅节省内存 而且不用复杂声明多个函数 函数模板
  • 为线程池中的每个线程设置UncaughtExceptionHandler

    参考了 java并发编程实战 P134内容 每当线程池需要创建一个线程时 都是通过调用线程工厂方法来完成的 默认的线程工厂方法将创建一个新的 非守护的线程 并且不包好特殊的配置信息 如果你希望在线程运行之前 之后 或者运行中如果发生异常等情
  • Linux 系统 lscpu 命令详解

    文章目录 前言 lscpu 命令详解 命令 1 查看物理 CPU 个数 2 查看每个物理 CPU 核数 3 查看总线程数 4 查看内存信息 5 查看 linux 系统版本 前言 Linux 系统查看系统相关信息方法很多 以下详细介绍 lsc
  • 一颗二叉树代码(图解)

    什么是二叉树 树结构是一种非线性存储结构 存储的是具有一对多关系的数据的集合 而树形结构的一种抽象出来的数据结构往往是二叉树的形式 满足以下两个条件的树就是二叉树 本身是有序树 树中包含的各个节点的度不能超过 2即只能是 0或者1 或者 2
  • 项目时间管理-架构真题(二十四)

    1 霍尔提出了系统方法的三维结构体系 通常称为霍尔三维结构 这就是系统工程方法论的基础 霍尔三维结构以时间堆 堆 知识堆组成的立体结构概括性表示出系统工程在各阶段 各步骤以及所涉及的知识范围 其中时间维是系统的工作进程 对于一个具体的工程项
  • 计算机网络面试八股文攻略(二)—— TCP 与 UDP

    一 基础概念 TCP 与 UDP 是活跃于 运输层 的数据传输协议 TCP 传输控制协议 Transmission Control Protocol 提供面向连接的 可靠的数据传输服务 具体来说就是一种要建立双端连接才能发送数据 能确保传输
  • react拖拽排序、js列表拖拽

    列表拖动排序的解决方案有多种 个人感觉最简单的就是zent 提供的 Sortable 组件了 一 zent Sortable 拖拽排序 推荐 简单明了 zent 官网 https zent contrib gitee io zent zh
  • 1139: 输出最短字符串java

    import java util Scanner public class Main public static void main String args Scanner input new Scanner System in int n
  • Qt第六章 多窗口编程

    一 QMessageBox 消息对话框 掌握 QMessageBox继承自QDialog 是一个Qt内置的用来展示信息或询问用户一个问题的模态对话框 预设了四种类型 像那些已经写好的窗口 这些现成的东西都会有一些特性 就是他们的对象都不需要
  • 基于51单片机的时钟设计

    今天小刚做了一个基于51单片机的时钟 本来想把数码管显示动态扫描放到定时器1的中断里到但是 一按按键 就卡住了 效果不是很理想 所以就放弃了这种方案 不过最后也实现了功能 以下是程序代码 4个按键功能 1 切换 2 时间 3 时间 4 清零
  • [RN] windows7 安装 Realm Studio 后,打开报错 A JavaScript error occurred in the main process...

    windows7 安装 Realm Studio 后 打开报错 报错如下 A JavaScript error occurred in the main process Uncaught Exception Error The specif
  • 为什么说Java只有值传递

    为什么说Java只有值传递 1 值传递概念 2 引用传递概念 3 Java只有值传递 没有引用传递 1 值传递概念 方法调用时 会创建副本 传递的是值的副本 也就是说传递后就不相关了 2 引用传递概念 方法调用时 不会创建副本 传递的是引用
  • 树莓派内核编译

    一 概述 树莓派的github主页 https github com raspberrypi 里面包含了linux源码 交叉编译工具链等内容 对于我们要用到的有两个仓库 https github com raspberrypi linux