当前位置: 首页 > article >正文

Linux内核编译并移植至ARM平台

Linux内核编译并移植至ARM平台

  • Linux系统相关概念
    • 操作系统的启动过程
    • 获取树莓派源码
    • Linux内核源代码目录树结构
  • 树莓派Linux源码配置
  • 树莓派Linux内核编译
  • 移植内核至树莓派

Linux系统相关概念

操作系统的启动过程

  • x86,Intel的启动过程: 电源上电 -> BIOS -> Windows内核 -> C盘,D盘 -> 应用程序启动(QQ等)

  • 嵌入式产品(Linux系统)启动过程: 电源上电 -> BootLoader -> Linux内核 ->文件系统 -> 应用程序

  • 安卓的启动过程: 电源上电 -> fastBoot/Bootloader -> linux内核 -> 文件系统 -> 虚拟机 -> HOME应用程序 -> 通过图标打开某APP

获取树莓派源码

1. 通过指令查看树莓派的内核版本号:

uname -r

内核版本号:

2. 下载树莓派对应内核源码

通过 树莓派官网 下载源码,并将其拷贝到Ubuntu并解压

解压命令:

unzip linux-rpi-4.14.y

Linux内核源代码目录树结构

  • arch: 包含和硬件体系结构相关的代码,每种平台占一个相应的目录。和32位PC相关的代码存放在i386目录下,其中比较重要的包括kernel(内核核心部分)、mm(内存管理)、math-emu(浮点单元仿真)、lib(硬件相关工具函数)、boot(引导程序)、pci(PCI总线)和power(CPU相关状态)。

  • block: 部分块设备驱动程序。

  • crypto: 常用加密和散列算法(如AES、SHA等),还有一些压缩和CRC校验算法。

  • Documentation: 关于内核各部分的通用解释和注释。

  • drivers: 设备驱动程序,每个不同的驱动占用一个子目录。

  • fs: 各种支持的文件系统,如ext、fat、ntfs等。

  • include: 头文件,其中,和系统相关的头文件被放置在linux子目录下。

  • init: 内核初始化代码(注意不是系统引导代码)。

  • ipc: 进程间通信的代码。

  • kernel: 内核的最核心部分,包括进程调度、定时器等,和平台相关的一部分代码放在arch/*/kernel目录下。

  • lib: 库文件代码。

  • mm: 内存管理代码,和平台相关的一部分代码放在arch/*/mm目录下。

  • net: 网络相关代码,实现了各种常见的网络协议。

  • scripts: 用于配置内核文件的脚本文件。

  • security: 主要是一个SELinux的模块。

  • sound: 常用音频设备的驱动程序等。

  • usr: 实现了一个cpio。

树莓派Linux源码配置

  • 当我们工作中要进行驱动代码的编写,编写完以后要进行编译,要进行驱动代码的编译就必须要一个提前编译好的内核,编译内核就必须要先配置。

  • 配置的最终目标会生成 .config文件,该文件指导Makefile去把有用东西组织成内核。 厂家配linux内核源码,比如说买了树莓派,树莓派linux内核源码:使用源码里自带的config。

其中Linux源码配置有三种方式:

  • 方式一:厂家会配linux内核源码,厂家会提供对于芯片的内核源码,拷贝厂家的.cinfig文件进行配置
  • 方式二:make menuconfig 一项项配置 ,通常是基于厂家的config来配置
  • 方式三:完全自己来

其中编译Linux源码需要先安装好arm-linux交叉编译工具链。

其中交叉编译工具链的安装参考以下博文:交叉编译工具链的安装及带wiringPi库的交叉编译实现

方式一:拷贝厂家提供的config文件

执行命令,查看厂家给的配置文件

cd linux-rpi-4.14.y/
find .  -name  *_defconfig
find .  -name  *_defconfig|grep bcm2709

内核配置:

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
  • 指定ARM架构 : ARCH=arm
  • 指定编译器 : CROSS_COMPILE=arm-linux-gnueabihf-
  • 树莓派 : KERNEL=kernel7
  • 主要核心指令 : make bcm2709_defconfig

方式二:make menuconfig

一项项配置,常是基于厂家的config来配置,首先要安装必要的库:

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

安装完后执行以下配置指令:

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


然后根据自己的需要来剪裁内核,按需配置

驱动两种加载方式:

  1. [*] 编译进内核 zImage包含了驱动

  2. [M] 模块方式生成驱动文件xxx.ko 系统启动后,通过命令inmosd xxx.ko 加载
    [ * ] 和< M >是驱动加载的两种方式,可以按空格键进行加载方式的切换。
    [ ] :表示略过的,不参与编译,也就是需要裁剪的东西

方式三:完全自己来: 配置完内核后就可以进行内核的编译了。

树莓派Linux内核编译

编译指令:

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

此过程较慢,大约要20多分钟左右

  • -j4: 指定用多少电脑资源进行编译
  • zImage: 生成内核镜像
  • modules: 要生成驱动模块
  • dtbs: 生成配置文件

编译成功后,看到源码树目录多了vmlinux,失败则无此文件。成功后,目标zImage镜像arch/arm/boot底下

移植内核至树莓派

STEP 1:打包zImage文件

  • 用mkknlimg 工具打包zImage 文件,将生成的zImage打包成树莓派可用的 xxx.img 比如 kernel_new.img
    ./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
    


STEP 2:挂载U盘

  • 插入带有树莓派系统的内存卡的读卡器并挂载到虚拟机,并输入 dmesg 命令后出现sda1和sda2表示连接成功

  • 在根目录新建两个文件夹data1、data2并将U盘里的内容挂载到这两个文件夹中

    mkdir data1 data2
    sudo mount /dev/sdb1 data1   
    sudo mount /dev/sdb2 data2   
    
  • sdb1、sdb2 分别是树莓派SD卡的两个分区

    • sdb1即data1是fat分区,是boot相关的内容,kernel的img文件在此分区
    • sdb2即data2是ext4分区,也就是系统的根目录分区。(cd /进入的就是系统的根目录
  • 通过挂载U盘,data1 和 data2 文件夹内就有了U盘内部的数据

STEP 3 :安装modules:

  • 用于安装设备驱动文件,像无线网卡,IIC等驱动设备,进入树莓派源码树目录键入
    sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=[ext4] modules_install
    
    注意:这里要将【ext4】改为自己具体的绝对路径
    sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=/home/yuanjl/data2 modules_install
    

STEP 4:更新 kernel.img 文件

  • 因为之前用 mkknlimg 工具打包了kernel_new.img文件,只要把它复制到fat分区(data1)并配置使用即可,防止刷机失败,首先备份之前的kernel.img 文件 ,进入挂载fat分区(data1)文件键入下列命令:
    cp kernel7.img kernel7OLD.img
    
  • 将之前在源码树目录生成的kernel_new.img拷贝到fat分区(data1)并替代之前的kernel7.img
    cp kernel_new.img /home/yuanjl/data1/kernel7.img
    
  • 拷贝完成后需要校验md5值,如果两文件的md5值不一样则需要重新拷贝。
    md5sum /home/zh/SYSTEM/linux-rpi-4.14.y/kernel_new.img 
    md5sum kernel7.img
    

STEP 5:在源码树中复制其它配置文件到fat分区(data1)

cp arch/arm/boot/dts/.*dtb* /home/yuanjl/data1
cp arch/arm/boot/dts/overlays/.*dtb* /home/yuanjl/data1/overlays/
cp arch/arm/boot/dts/overlays/README /home/yuanjl/data1/overlays/

STEP 6: 将配置玩的内存卡放入树莓派中键入uname -r查看更换后的内核版

在这里插入图片描述

参考博文:
1. 树莓派Linux内核配置
2. 树莓派-内核开发-说明 下载代码 编译 替换内核
3. Linux内核源代码目录树结构
4. 配置、编译Linux内核适合树莓派相关操作
5. 树莓派——配置Linux内核适合树莓派


http://www.kler.cn/a/305096.html

相关文章:

  • 【Spring】@Autowired与@Resource的区别
  • C++ QT 工具日志异步分批保存
  • 零基础玩转IPC之——海思平台实现P2P远程传输实验(基于TUTK,国科君正全志海思通用)
  • Python 小高考篇(2)字符串
  • 有什么初学算法的书籍推荐?
  • 问:MySQL主从同步的机制梳理?
  • 【数据结构和算法实践-树-LeetCode113-路径总和Ⅱ】
  • 【数据结构】6——图1,概念
  • 【nginx】ngx_http_proxy_connect_module 正向代理
  • 『功能项目』C#拓展 - 优化冗余脚本【36】
  • unity3d入门教程五
  • 【FastAPI】实现服务器向客户端发送SSE(Server-Sent Events)广播
  • [C#][IIS]framework4.0注册到IIS
  • 密码学---常见的其他密码
  • 第十一周:机器学习笔记
  • python 实现euclidean distance欧式距离算法
  • 分享JavaScript中直接调用CSS中的类名
  • 56 - I. 数组中数字出现的次数
  • CAN总线-STM32上CAN外设
  • ansible_find模块
  • 计算机四级数据库原理考试大纲.md
  • 37. MyBatis-Plus是什么?它与MyBatis的主要区别是什么?
  • 音视频开发常见的开源项目汇总
  • 新挂载的磁盘不能创建文件
  • 数据清洗-缺失值填充-随机森林填充
  • 【Django】Django Class-Based Views (CBV) 与 DRF APIView 的区别解析