理论嵌入式 linux 要求

Theoretical embedded linux requirements

我有使用 Java、C#、C++、Javascript

的程序员背景

我给自己买了一台 Raspberry Pi(Model 1 A,没有以太网的那个)并用它玩了一会儿。我使用 Raspbian 和 Arch Linux ARM(因为据说它很小且可定制)。不幸的是,我没有按照我想要的方式配置它们。

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

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

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

我的问题:嵌入式 linux 在 raspberry pi 上持有单声道、qt、java 运行时的理论上需要的部分是什么?

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

但是然后呢?我的研究迷失在 "use a distro" 我不想要的地方。内核和启动应用程序之间缺少哪些部分?

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

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

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

GNU/Linux 嵌入式系统的块

  • 硬件

SoC

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

它由各种不同的子块组成:

  1. Core + Caches + MMU - “real”处理器,例如ARM Cortex-A9。这是您在选择 SoC 时会注意到的主要事项。 可以通过例如 coaduvated像 NEON 这样的 SIMD 协处理器。
  2. 内部 RAM - 通常很小。用于引导序列的第一阶段。
  3. 各种 "Peripherals" - 通过一些互连连接 fabric/bus 到核心。这些可以从简单的 ADC 到 3D 图形加速器。此类IP核的例子有:USB、PCI-E、SGX等
  4. 一个低 power/real 时间协处理器 - 一些系统提供一个或多个协处理器来帮助主内核处理实时任务(例如工业通信总线)或处理 低​​功耗 状态。 Its/their 架构可能(或不是)与核心架构相关。

外部内存

SoC 使用它在系统 bootstrapped 之后和 bootstrap 本身期间存储临时数据。它通常是您的嵌入式系统在正常运行期间使用的内存。

非易失性存储器 - 可选

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

如果存在,它通常是 SoC 将从中读取的常规数据源,并且通常存储系统工作所需的所有软件组件。 在某些应用程序中不能 necessary/useful。

外设

与上述内容没有严格关系的任何内容。 可以是 MAC ID EEPROM、一些继电器、网络摄像头或任何您能想到的东西。

  • 软件

    首先,我们介绍所谓的 bootchain,这是在您为 SoC 加电并以某种方式告诉它启动 运行ning 时立即发生的事情。在下面的列表中,bootchain就是点1到点4的后续调用。

除了 specific/exotic 实现之外,它或多或少总是相同的:

  1. 引导 ROM 代码 - SoC 中包含的小型(通常被屏蔽 - 又名工厂印象)内存。 SoC 上电后要做的第一件事就是执行其中的代码。 此代码通常根据外部配置引脚决定所谓的 "boot strategy" 或 "boot order",即在何处(以及以何种顺序)查找要执行的附加代码。

    适用的介质多种多样:USB 存储设备、USB 主机、SD 卡、NAND、NOR、SPI 数据闪存、以太网、UART 等。 如果上面的 none 包含有效的内容,Boot ROM 通常会发出 SoC 的软重置,等等。

    媒体中的代码当然不会就地执行:它被复制到内部 RAM 中然后执行。

[以下两个包含在我们所说的引导加载程序介质中]

  1. 1st stage bootloader - 它刚刚被 Boot ROM 复制到 SoC 的内部 RAM。必须足够小以适合该内存 (通常远低于 100kB)。它是必需的,因为引导 ROM 不是 足够大,不知道 SoC 是哪种外部 RAM 附于。

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

  2. 第二阶段引导加载程序 - "main" 引导加载程序。比第一阶段更大(可能是 x10),完成了 相关外围设备(例如以太网、附加存储介质、LCD displays).

    允许更复杂的下一步操作逻辑 并提供 - 取决于复杂程度 - 高水平 设施(filesystem/volume 处理、数据 复制移动解释、LCD 输出、交互式控制台、故障保护 policies).

    大多数时候加载 Linux 内核(及相关)到 来自某种媒介的记忆并将相关信息传递给它(例如 如果没有嵌入,对于较新的内核,DTB 物理地址被放置 在 r2 寄存器中 - 内核然后读取寄存器并 检索 DTB)

  3. Linux Kernel - 操作系统的核心。取决于 硬件平台可能是也可能不是主线 ("official") 版本。

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

  4. Init 和 rootfs - init 是第一个非内核任务 运行,并且 有 PID 1。它实际上初始化了你需要使用你的一切 系统。在生产嵌入式系统中,它还启动主 应用。在这样的系统中,要么是 BusyBox,要么是定制的 申请.

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

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

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

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

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

总结并准确回答你的问题你要找的缺失部分是init和挂载rootfs的过程:内核挂载 - 也就是通过它的驱动程序和 passed/builtin 参数呈现给它自己 - 给定的 volume/partition (你提到的 ext4 数据分区)到“/”挂载点。

在这个 volume/partition 中有一个 /sbin/init 可执行文件,由内核执行。

这是我们 GNU/Linux 用户空间系统的“大爆炸”:可见的一切开始的地方。根据配置脚本(通常位于 /etc/init.d 下),您提到的 "application" 是由 init 自动 运行 或由用户通过 terminal/ssh/whatever 再次 - init 让你可以使用。