嵌入式linux的理论要求

mon*_*nty 4 theory embedded-linux raspberry-pi

我来自使用 Java、C#、C++、Javascript 的程序员背景

我给自己买了一个树莓派(Model 1 A,没有以太网的那个)并玩了一段时间。我使用了 Raspbian 和 Arch Linux ARM(因为有人说它小巧且可定制)。不幸的是,我没有按照我想要的方式配置它们。

我正在尝试构建一个漂亮的(嵌入式)系统,其唯一目标是快速启动(启动)Raspberry Pi 并自动启动一个测试应用程序,该应用程序将使用 C#(Mono)、C++(Qt)、Java(Java 运行时)编写或 JavaScript/HTML 中的东西。

由于我无法删除所有日志消息(我删除了大部分)、tty 登录屏幕、连接到网络的尝试(尽管 Model 1 A 根本没有以太网)启动是丑陋的并且花了很长时间(在某些情况下 +1 分钟)。

似乎我必须构建一个最小的嵌入式 linux,但我缺乏嵌入式 linux 元素的理论以及它们如何组合在一起。

我的问题:在树莓派上支持 mono、qt、java 运行时的嵌入式 linux 理论上需要哪些部分?

到目前为止,我知道以下部分:

  • 硬件(树莓派型号 1 A)+ SD 卡
  • SD卡有2个分区,1个引导分区(fat32),1个数据分区(ext4)
  • 引导加载程序
  • 一个 linux 内核(可以根据 raspi 的需要进行优化)

但是呢?我的研究在“使用发行版”中迷失了我不想要的东西。内核和启动应用程序之间缺少哪些部分?

Fra*_*cia 5

嵌入式 Linux 系统由许多不同的部分组成,这些部分协同工作以实现使事情高效工作的同一目标。

理想情况下,这与常规 GNU/Linux 系统没有太大区别,但让我们详细了解通用嵌入式系统的构建块。

对于以下解释,我假设为架构 ARM。下面所写的内容可能因实现的不同而略有不同,但通常是商业嵌入式系统的通用轨道。

GNU/Linux 嵌入式系统的块

  • 硬件

系统级芯片

SoC是所有处理发生的地方,它是整个系统的主要处理单元,也是唯一拥有“智能”的地方。它负责使用其他硬件并运行您的软件。

它由各种异构的子块组成:

  1. 核心 + 缓存 + MMU - “真正的”处理器,例如ARM Cortex-A9。这是您在选择 SoC 时会注意到的主要事情。可以由例如像 NEON 的 SIMD 协处理器共同调整。
  2. 内部 RAM - 通常非常小。用于引导序列的第一阶段。
  3. 各种“外设” ——通过一些互连结构/总线连接到核心。这些可以从简单的 ADC 到 3D 图形加速器。此类 IP 核的示例包括:USB、PCI-E、SGX 等。
  4. 低功耗/实时协处理器- 一些系统提供一个或多个协处理器,旨在帮助主内核处理实时任务(例如工业通信总线)或处理低功耗状态。它/他们的架构可能(或不是)是 Core 的一个亲戚。

外部 RAM

SoC 使用它在系统引导后和引导过程中存储临时数据。它通常是您的嵌入式系统在常规操作期间使用的内存。

非易失性存储器 - 可选

可能存在也可能不存在。在您的情况下,它是您提到的 SD 卡。在其他情况下,可能是 NAND、NOR 或 SPI Dataflash 存储器(或它们的任意组合)。

当存在时,它通常是 SoC 将读取的常规数据源,并且通常存储系统工作所需的所有软件组件。在某些类型的应用程序中可能没有必要/有用。

外设

任何与上述不严格相关的东西。可以是 MAC ID EEPROM、一些继电器、网络摄像头或任何你能想象到的东西。

  • 软件

    首先,我们介绍了所谓的bootchain,它是当您启动 SoC 并以某种方式告诉它开始运行时会发生的事情。在下面的列表中,引导链是点 1 到点 4 的后续调用。

除了特定/异国情调的实现,它或多或少总是相同的:

  1. 启动 ROM 代码- 包含在 SoC 中的一个小(通常被屏蔽 - 又名工厂印象)内存。SoC 通电后要做的第一件事就是执行其中的代码。该代码将——通常根据外部配置引脚——决定所谓的“引导策略”或“引导顺序”,即在何处(以及以何种顺序)寻找要执行的附加代码。

    合适的介质是不同的:USB 存储设备、USB 主机、SD 卡、NAND、NOR、SPI 数据闪存、以太网、UART 等。 , 等等。

    当然,介质中的代码不是就地执行:它被复制到内部 RAM 中然后执行。

[以下两个包含在我们称之为引导加载程序介质中]

  1. 第一阶段引导加载程序- 它刚刚被引导 ROM 复制到 SoC 的内部 RAM 中。必须足够小以适合该内存(通常远低于 100kB)。它是必需的,因为 Boot ROM 不够大,并且不知道 SoC 连接到哪种外部 RAM。

    具有初始化外部 RAM 和 SoC 的外部存储器接口以及其他可能感兴趣的外设(例如禁用看门狗定时器)的主要重要功能。完成后,它将下一个阶段复制到外部 RAM 并执行它。根据上下文,可以称为 MLO、SPL 或其他。

  2. 第二阶段引导加载程序- “主”引导加载程序。比第一阶段更大(可能是 x10),完成相关外围设备(例如以太网、附加存储介质、LCD 显示器)的初始化。

    允许为下一步做什么提供更复杂的逻辑,并根据复杂程度提供高级设施(文件系统/卷处理、数据复制-移动-解释、LCD 输出、交互式控制台、故障安全策略)。

    大多数情况下,将 Linux 内核(和相关的)从某种介质加载到内存中,并将相关信息传递给它(例如,如果没有嵌入,对于较新的内核,DTB 物理地址放在 r2 寄存器中 - 内核然后读取寄存器并检索 DTB)

  3. Linux Kernel - 操作系统的核心。根据硬件平台可能是也可能不是主线(“官方”)版本。

    通常由内置或可加载(来自外部源 - 免费或非免费)模块完成。根据硬编码配置和 DT 初始化整个系统工作所需的所有硬件 - 启用 MMU,协调整个系统并独占访问硬件。根据引导参数(cmdline - 通常由前一阶段传递)和/或编译选项,内核尝试挂载根文件系统。它将尝试从 rootfs 加载一个 init(即 /sbin/init - 其中 / 是刚刚安装的 rootfs)。

  4. Init 和 rootfs - init 是第一个要运行的非内核任务,PID 为 1。它实际上初始化了您使用系统所需的一切。在生产嵌入式系统中,它也启动了主要应用程序。在这样的系统中是 BusyBox 或定制的应用程序。

有关 rootfs 和发行版的更多信息

Rootfs 包含所有非内核的 GNU/Linux 系统(除了 /lib/modules 和其他位)。
它包含管理以太网、WiFi 或外部 UMTS 调制解调器等外围设备的所有应用程序。

包含系统的交互部分,包含用户界面,以及您在启动 GNU/Linux 系统时看到的所有其他内容 - 嵌入式或非嵌入式。

“发行版”只是一组特定的用户空间(非内核)程序和库(通常)经过验证可以相互配合工作,由特定的人群组合在一起。桌面发行版通常还附带定制的内核和引导加载程序。例如 Fedora、Ubuntu、Debian 等。

从这个术语的一般意义上讲,没有什么能阻止您创建自己的发行版,这就是每次定制嵌入式系统投入生产时都会发生的情况:通过 Yocto 或 Buildroot 等工具(或手动),实际上,您可以决定适合系统用途的非常特殊的软件集合(因此是发行版、分发版)。

总结并准确回答您的问题您正在寻找的缺失部分是 init 和挂载 rootfs 的过程:内核挂载 - 也就是呈现给它自己 - 通过其驱动程序和传递/内置参数 - 给定的卷/partition(您提到的 ext4 数据分区)到“/”挂载点。

在这个卷/分区中有一个 /sbin/init 可执行文件,内核会执行它。

这是我们的 GNU/Linux 用户空间系统的“大爆炸”:一切可见的开始的地方。根据配置脚本(通常位于 /etc/init.d 下),您提到的“应用程序”要么由 init 自动运行,要么由用户通过终端/ssh/无论什么 - 再次 - init 使您可以使用。

  • 有人能够将嵌入式系统教科书压缩成一篇论文。很好的解释! (2认同)