理论嵌入式Linux需求

4

我来自一个编程背景,使用Java、C#、C ++、Javascript

我买了一台树莓派(型号1 A,没有以太网),并玩了一段时间。我使用了Raspbian和Arch Linux ARM(因为它被称为小巧且可定制)。不幸的是,我没有按照我的意愿进行配置。

我正在尝试构建一个外观漂亮的嵌入式系统,其唯一目标是快速启动(引导)树莓派,并自动启动一个测试应用程序,该应用程序将使用C#(Mono)、C ++(Qt)、Java(Java Runtime)或JavaScript / HTML中的某些内容编写。

由于我无法摆脱所有日志消息(我已经摆脱了大部分),tty登录屏幕,连接到网络的尝试(尽管模型1 A根本没有以太网),所以引导很丑并且需要很长时间(在某些情况下超过1分钟)。

看起来我必须构建一个最小的嵌入式Linux,但我对嵌入式Linux元素以及它们如何配合使用的理论知识有所欠缺。

我的问题:在树莓派上运行Mono、Qt、Java Runtime的嵌入式Linux的理论必需部分是什么?

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

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

但是接下来呢?我的研究停留在“使用发行版”,而这不是我想要的。在内核和启动应用程序之间缺少哪些部分?


1
你有没有查看过 http://www.linuxfromscratch.org/? - DanL
是的,我目前正在努力学习它 :-) 但它非常广泛。我希望能够获得一个简洁的概述,以启动我的进一步研究,并有一些指导方针来检查我是否仍然在正确的轨道上(因为我还没有弄清楚Linuxfromscratch的最终结果是什么)。我也了解了buildroot和yocto项目,但如果没有理论背景知识,我认为构建“某物”是不明智的。谢谢你的提示。 - monty
避免使用发行版,尝试使用Buildroot。它是最容易使用的系统构建工具,并将确保工作根文件系统的依赖关系。要确定所需的最小内容,您可以浏览Buildroot菜单以添加或删除程序/软件包。依赖项会自动选择,并且不会被删除。您必须拥有的一个用户空间程序是Busybox,该程序(以及C运行时库)也可定制。Buildroot将安装所有Busybox组件以完成系统初始化(在内核引导后),并提供登录/ shell提示符。 - sawdust
'内核和启动应用程序之间缺失了哪些部分?'-- 本质上你在询问系统初始化。在嵌入式系统中,最常见的版本是Busybox init。一个更复杂的方案是System V初始化(其中的“V”是罗马数字5),它使用"运行级别"来实现。 - sawdust
1个回答

6
一个嵌入式Linux系统由许多不同的部分组成,这些部分共同致力于使事物高效地工作。理想情况下,这与普通的GNU/Linux系统没有太大差别,但让我们详细看看通用嵌入式系统的构建块。在以下说明中,我假设架构为ARM。下面所写的可能会因实现的不同而略有不同,但通常是商业嵌入式系统的通用轨迹。
GNU/Linux嵌入式系统的构建块如下:
硬件 SoC - 所有处理都发生在SoC中,它是整个系统的主要处理单元,也是唯一具有“智能”的地方。它负责使用其他硬件并运行软件。它由各种异构子块组成: 1.核心+Caches+MMU - “真正的”处理器,例如ARM Cortex-A9。这是您选择SoC时最关注的主要组成部分。还可以辅助例如一个像NEON这样的SIMD协处理器。 2.内部RAM - 通常非常小。在引导序列的第一阶段中使用。 3.各种“外设”-通过某些互连纺织/总线连接到核心。这些可以从简单的ADC到3D图形加速器。此类IP核的示例包括:USB、PCI-E、SGX等。 4.低功率/实时协处理器-某些系统提供一个或多个协处理器,用于帮助主核心处理实时任务(例如工业通信总线)或处理低功耗状态。它们的体系结构可能(也可能不)与核心的一致。
外部RAM - SoC用于在系统引导及其自身期间存储临时数据。这通常是您的嵌入式系统在常规操作期间使用的内存。
非易失性存储器- 可选项。在您的情况下,这是您提到的SD卡。在其他情况下,可能是NAND、NOR或SPI Dataflash存储器(或它们的任何组合)。当存在时,它通常是SoC将读取的数据的常规来源,并且通常存储系统运行所需的所有SW组件。在某些应用程序中可能不是必要/有用。
外部外设- 与上述内容无直接关系的任何内容。可以是MAC ID EEPROM、一些继电器、网络摄像头或您可能想象的任何东西。
  • 软件

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

除了特定/奇异的实现,它基本上总是相同的:

  1. 引导ROM代码 - 一个小型(通常是掩模 - 即工厂印制)存储在SoC中的内存。当SoC上电时,它将执行其中的代码。

    这个代码会根据外部配置引脚 - 一般上是"引导策略"或"引导顺序" - 决定在哪里(以及什么顺序)查找要执行的其他代码。 适合的媒介是不同的:USB存储设备、USB主机、SD卡、NAND、NOR、SPI数据闪存、以太网、UART等。如果上述任何一个都不包含有效内容,引导ROM通常会对SoC进行软复位,如此往复。

    当然,介质中的代码不是直接执行:而是被复制到内部RAM中,然后再执行。

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

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

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

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

    允许更复杂的下一步操作逻辑,并根据复杂程度提供高级功能(文件系统/卷处理、数据复制-移动-解释、液晶输出、交互式控制台、故障安全策略等)。

    大多数情况下,从某些介质将Linux内核(及相关模块)加载到内存中,并向其传递相关信息(例如,如果不是嵌入式,对于较新的内核,DTB物理地址被放入r2寄存器中 - 然后内核读取该寄存器并检索DTB)

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

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

  4. 初始化和rootfs - 初始化是要运行的第一个非内核任务,并具有PID 1。它初始化您使用系统所需的所有内容。在生产嵌入式系统中,它还启动主应用程序。在这些系统中,它可以是BusyBox或定制的应用程序。

更多关于rootfs和发行版

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

包含系统的交互部分,包括用户界面和GNU/Linux系统启动时看到的所有其他内容 - 无论是嵌入式还是非嵌入式。"distro"只是一组特定的用户空间(非内核)程序和库(通常),经过验证可以很好地彼此协作,由特定的人员组合在一起。桌面发行版通常还配有自定义内核和引导加载程序。例如 Fedora、Ubuntu、Debian 等。
就术语的一般意义而言,你没有任何限制来创建自己的distro,这正是每次生产自定义嵌入式系统时会发生的事情:通过像Yocto或Buildroot这样的工具(或手动),实际上可以决定适用于系统目的的软件的特定集合(因此是发行版)。
总之,回答你的问题,你正在寻找的缺失部分是init和挂载rootfs的过程:内核通过其驱动程序和传递/内置参数将给定的卷/分区(你提到的ext4数据分区)挂载到“ /”挂载点。在这个卷/分区中,有一个/sbin/init可执行文件,内核执行它。这是我们GNU/Linux用户空间系统的"Big Bang":一切可见的东西都从这里开始。根据配置脚本(通常位于/etc/init.d下),你提到的"应用程序"要么由init自动运行,要么由用户通过终端/ssh/其他手段启动,而这些方式都是init让你可以使用的。

2
有人能够将一本嵌入式系统教材压缩成一页的论文。解释得很好! - tauseef_CuriousGuy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接