4 种用于构建嵌入式 Linux 系统的工具
嵌入式

> 
> 了解 Yocto、Buildroot、 OpenWRT，和改造过的桌面发行版以确定哪种方式最适合你的项目。
> 
> 
> 


![](/data/attachment/album/201807/06/095532wzz9flhboh6anfcw.jpg)


Linux 被部署到比 Linus Torvalds 在他的宿舍里开发时所预期的更广泛的设备。令人震惊的支持了各种芯片，使得Linux 可以应用于大大小小的设备上：从 [IBM 的巨型机](https://en.wikipedia.org/wiki/Linux_on_z_Systems)到不如其连接的端口大的[微型设备](http://www.picotux.com/)，以及各种大小的设备。它被用于大型企业数据中心、互联网基础设施设备和个人的开发系统。它还为消费类电子产品、移动电话和许多物联网设备提供了动力。


在为桌面和企业级设备构建 Linux 软件时，开发者通常在他们的构建机器上使用桌面发行版，如 [Ubuntu](https://www.ubuntu.com/) 以便尽可能与被部署的机器相似。如 [VirtualBox](https://www.virtualbox.org/) 和 [Docker](https://www.docker.com/) 这样的工具使得开发、测试和生产环境更好的保持了一致。


### 什么是嵌入式系统？


维基百科将[嵌入式系统](https://en.wikipedia.org/wiki/Embedded_system)定义为：“在更大的机械或电气系统中具有专用功能的计算机系统，往往伴随着实时计算限制。”


我觉得可以很简单地说，嵌入式系统是大多数人不认为是计算机的计算机。它的主要作用是作为某种设备，而不被视为通用计算平台。


嵌入式系统编程的开发环境通常与测试和生产环境大不相同。它们可能会使用不同的芯片架构、软件堆栈甚至操作系统。开发工作流程对于嵌入式开发人员与桌面和 Web 开发人员来说是非常不同的。通常，其构建后的输出将包含目标设备的整个软件映像，包括内核、设备驱动程序、库和应用程序软件（有时也包括引导加载程序）。


在本文中，我将对构建嵌入式 Linux 系统的四种常用方式进行纵览。我将介绍一下每种产品的工作原理，并提供足够的信息来帮助读者确定使用哪种工具进行设计。我不会教你如何使用它们中的任何一个；一旦缩小了选择范围，就有大量深入的在线学习资源。没有任何选择适用于所有情况，我希望提供足够的细节来指导您的决定。


### Yocto


[Yocto](https://yoctoproject.org/) 项目 [定义](https://www.yoctoproject.org/about/)为“一个开源协作项目，提供模板、工具和方法，帮助您为嵌入式产品创建定制的基于 Linux 的系统，而不管硬件架构如何。”它是用于创建定制的 Linux 运行时映像的配方、配置值和依赖关系的集合，可根据您的特定需求进行定制。


完全公开：我在嵌入式 Linux 中的大部分工作都集中在 Yocto 项目上，而且我对这个系统的认识和偏见可能很明显。


Yocto 使用 [Openembedded](https://www.openembedded.org/) 作为其构建系统。从技术上讲，这两个是独立的项目；然而，在实践中，用户不需要了解区别，项目名称经常可以互换使用。


Yocto 项目的输出大致由三部分组成：


* **目标运行时二进制文件：**这些包括引导加载程序、内核、内核模块、根文件系统映像。以及将 Linux 部署到目标平台所需的任何其他辅助文件。
* **包流：**这是可以安装在目标上的软件包集合。您可以根据需要选择软件包格式（例如，deb、rpm、ipk）。其中一些可能预先安装在目标运行时二进制文件中，但可以构建用于安装到已部署系统的软件包。
* **目标 SDK：**这些是安装在目标平台上的软件的库和头文件的集合。应用程序开发人员在构建代码时使用它们，以确保它们与适当的库链接


#### 优点


Yocto 项目在行业中得到广泛应用，并得到许多有影响力的公司的支持。此外，它还拥有一个庞大且充满活力的开发人员[社区](https://www.yoctoproject.org/community/)和[生态系统](https://www.yoctoproject.org/ecosystem/participants/)。开源爱好者和企业赞助商的结合的方式有助于推动 Yocto 项目。


获得 Yocto 的支持有很多选择。如果您想自己动手，有书籍和其他培训材料。如果您想获得专业知识，有许多有 Yocto 经验的工程师。而且许多商业组织可以为您的设计提供基于 Yocto 的 Turnkey 产品或基于服务的实施和定制。


Yocto 项目很容易通过 [层](https://layers.openembedded.org/layerindex/branch/master/layers/) 进行扩展，层可以独立发布以添加额外的功能，或针对项目发布时尚不可用的平台，或用于保存系统特有定制功能。层可以添加到你的配置中，以添加未特别包含在市面上版本中的独特功能；例如，“[meta-browser](https://layers.openembedded.org/layerindex/branch/master/layer/meta-browser/)” 层包含 Web 浏览器的清单，可以轻松为您的系统进行构建。因为它们是独立维护的，所以层可以按不同的时间发布（根据层的开发速度），而不是跟着标准的 Yocto 版本发布。


Yocto 可以说是本文讨论的任何方式中最广泛的设备支持。由于许多半导体和电路板制造商的支持，Yocto 很可能能够支持您选择的任何目标平台。主版本 Yocto [分支](https://yoctoproject.org/downloads)仅支持少数几块主板（以便达成合理的测试和发布周期），但是，标准工作模式是使用外部主板支持层。


最后，Yocto 非常灵活和可定制。您的特定应用程序的自定义可以存储在一个层进行封装和隔离，通常将要素层特有的自定义项存储为层本身的一部分，这可以将相同的设置同时应用于多个系统配置。Yocto 还提供了一个定义良好的层优先和覆盖功能。这使您可以定义层应用和搜索元数据的顺序。它还使您可以覆盖具有更高优先级的层的设置；例如，现有清单的许多自定义功能都将保留。


#### 缺点


Yocto 项目最大的缺点是学习曲线陡峭。学习该系统并真正理解系统需要花费大量的时间和精力。 根据您的需求，这可能对您的应用程序不重要的技术和能力投入太大。 在这种情况下，与一家商业供应商合作可能是一个不错的选择。


Yocto 项目的开发时间和资源相当高。 需要构建的包（包括工具链，内核和所有目标运行时组件）的数量相当不少。 Yocto 开发人员的开发工作站往往是大型系统。 不建议使用小型笔记本电脑。 这可以通过使用许多提供商提供的基于云的构建服务器来缓解。 另外，Yocto 有一个内置的缓存机制，当它确定用于构建特定包的参数没有改变时，它允许它重新使用先前构建的组件。


#### 建议


为您的下一个嵌入式 Linux 设计使用 Yocto 项目是一个强有力的选择。 在这里介绍的选项中，无论您的目标用例如何，它都是最广泛适用的。 广泛的行业支持，积极的社区和广泛的平台支持使其成为必须设计师的不错选择。


### Buildroot


[Buildroot](https://buildroot.org/) 项目定义为“通过交叉编译生成嵌入式 Linux 系统的简单、高效且易于使用的工具。”它与 Yocto 项目具有许多相同的目标，但它注重简单性和简约性。一般来说，Buildroot 会禁用所有软件包的所有可选编译时设置（有一些值得注意的例外），从而生成尽可能小的系统。系统设计人员需要启用适用于给定设备的设置。


Buildroot 从源代码构建所有组件，但不支持按目标包管理。因此，它有时称为固件生成器，因为镜像在构建时大部分是固定的。应用程序可以更新目标文件系统，但是没有机制将新软件包安装到正在运行的系统中。


Buildroot 输出主要由三部分组成：


* 将 Linux 部署到目标平台所需的根文件系统映像和任何其他辅助文件
* 适用于目标硬件的内核，引导加载程序和内核模块
* 用于构建所有目标二进制文件的工具链。


#### 优点


Buildroot 对简单性的关注意味着，一般来说，它比 Yocto 更容易学习。核心构建系统用 Make 编写，并且足够短以便开发人员了解整个系统，同时可扩展到足以满足嵌入式 Linux 开发人员的需求。 Buildroot 核心通常只处理常见用例，但它可以通过脚本进行扩展。


Buildroot 系统使用普通的 Makefile 和 Kconfig 语言来进行配置。 Kconfig 由 Linux 内核社区开发，广泛用于开源项目，使得许多开发人员都熟悉它。


由于禁用所有可选的构建时设置的设计目标，Buildroot 通常会使用开箱即用的配置生成尽可能最小的镜像。一般来说，构建时间和构建主机资源的规模将比 Yocto 项目的规模更小。


#### 缺点


关注简单性和最小化启用的构建方式意味着您可能需要执行大量的自定义来为应用程序配置 Buildroot 构建。此外，所有配置选项都存储在单个文件中，这意味着如果您有多个硬件平台，则需要为每个平台进行每个定制更改。


对系统配置文件的任何更改都需要全部重新构建所有软件包。与 Yocto 相比，这个问题通过最小的镜像大小和构建时间得到了一定的解决，但在你调整配置时可能会导致构建时间过长。


中间软件包状态缓存默认情况下未启用，并且不像 Yocto 实施那么彻底。这意味着，虽然第一次构建可能比等效的 Yocto 构建短，但后续构建可能需要重建许多组件。


#### 建议


对于大多数应用程序，使用 Buildroot 进行下一个嵌入式 Linux 设计是一个不错的选择。如果您的设计需要多种硬件类型或其他差异，但由于同步多个配置的复杂性，您可能需要重新考虑，但对于由单一设置组成的系统，Buildroot 可能适合您。


### OpenWRT/LEDE


[OpenWRT](https://openwrt.org/) 项目开始为消费类路由器开发定制固件。您当地零售商提供的许多低成本路由器都可以运行 Linux 系统，但可能无法开箱即用。这些路由器的制造商可能无法提供频繁的更新来解决新的威胁，即使他们这样做，安装更新镜像的机制也很困难且容易出错。 OpenWRT 项目为许多已被其制造商放弃的设备生成更新的固件镜像，让这些设备焕发新生。


OpenWRT 项目的主要交付物是可用于大量商业设备的二进制镜像。它有网络可访问的软件包存储库，允许设备最终用户将新软件添加到他们的系统中。 OpenWRT 构建系统是一个通用构建系统，它允许开发人员创建自定义版本以满足他们自己的需求并添加新软件包，但其主要重点是目标二进制文件。


#### 优点


如果您正在为商业设备寻找替代固件，则 OpenWRT 应位于您的选项列表中。它的维护良好，可以保护您免受制造商固件无法解决的问题。您也可以添加额外的功能，使您的设备更有用。


如果您的嵌入式设计专注于网络，则 OpenWRT 是一个不错的选择。网络应用程序是 OpenWRT 的主要用例，您可能会发现许多可用的软件包。


#### 缺点


OpenWRT 对您的设计限制很多（与 Yocto 和 Buildroot 相比）。如果这些决定不符合您的设计目标，则可能需要进行大量的修改。


在部署的设备中允许基于软件包的更新是很难管理的。按照其定义，这会导致与您的 QA 团队测试的软件负载不同。此外，很难保证大多数软件包管理器的原子安装，以及错误的电源循环可能会使您的设备处于不可预知的状态。


#### 建议


OpenWRT 是爱好者项目或商用硬件再利用的不错选择。它也是网络应用程序的不错选择。如果您需要从默认设置进行大量定制，您可能更喜欢 Buildroot 或 Yocto。


### 桌面发行版


设计嵌入式 Linux 系统的一种常见方法是从桌面发行版开始，例如 [Debian](https://www.debian.org/) 或 [Red Hat](https://www.redhat.com/)，并删除不需要的组件，直到安装的镜像符合目标设备的占用空间。这是 [Raspberry Pi](https://www.raspberrypi.org/) 平台流行的 [Raspbian](https://www.raspbian.org/)发行版的方法。


#### 优点


这种方法的主要优点是熟悉。通常，嵌入式 Linux 开发人员也是桌面 Linux 用户，并且精通他们的选择发行版。在目标上使用类似的环境可能会让开发人员更快地入门。根据所选的分布，可以使用 apt 和 yum 等标准封装工具安装许多其他工具。


可以将显示器和键盘连接到目标设备，并直接在那里进行所有的开发。对于不熟悉嵌入式空间的开发人员来说，这可能是一个更为熟悉的环境，无需配置和使用棘手的跨开发平台设置。


大多数桌面发行版可用的软件包数量通常大于前面讨论的嵌入式特定的构建器可用软件包数量。由于较大的用户群和更广泛的用例，您可能能够找到您的应用程序所需的所有运行时包，这些包已经构建并可供使用。


#### 缺点


将目标平台作为您的主要开发环境可能会很慢。运行编译器工具是一项资源密集型操作，根据您构建的代码的多少，这可能会严重妨碍您的性能。


除了一些例外情况，桌面发行版的设计并不适合低资源系统，并且可能难以充分裁剪目标映像。同样，桌面环境中的预设工作流程对于大多数嵌入式设计来说都不理想。以这种方式获得可再现的环境很困难。手动添加和删除软件包很容易出错。这可以使用特定于发行版的工具进行脚本化，例如基于 Debian 系统的 [debootstrap](https://wiki.debian.org/Debootstrap)。为了进一步提高[可再现性](https://wiki.debian.org/Debootstrap)，您可以使用配置管理工具，如 [CFEngine](https://cfengine.com/)（我的雇主 [Mender.io](http://Mender.io) 完整披露了 这一工具）。但是，您仍然受发行版提供商的支配，他们将更新软件包以满足他们的需求，而不是您的需求。


#### 建议


对于您打算推向市场的产品，请谨慎使用此方法。这对于爱好者应用程序来说是一个很好的模型；但是，对于需要支持的产品，这种方法很可能会遇到麻烦。虽然您可能能够获得更快的起步，但从长远来看，您可能会花费您的时间和精力。


### 其他考虑


这个讨论集中在构建系统的功能上，但通常有非功能性需求可能会影响您的决定。如果您已经选择了片上系统（SoC）或电路板，则您的选择很可能由供应商决定。如果您的供应商为特定系统提供板级支持包（BSP），使用它通常会节省相当多的时间，但请研究 BSP 的质量以避免在开发周期后期发生问题。


如果您的预算允许，您可能需要考虑为目标操作系统使用商业供应商。有些公司会为这里讨论的许多选项提供经过验证和支持的配置，除非您拥有嵌入式 Linux 构建系统方面的专业知识，否则这是一个不错的选择，可以让您专注于核心能力。


作为替代，您可以考虑为您的开发人员进行商业培训。这可能比商业操作系统供应商便宜，并且可以让你更加自给自足。这是快速找到您选择的构建系统基础知识的学习曲线。


最后，您可能已经有一些开发人员拥有一个或多个系统的经验。如果你的工程师有倾向性，当你做出决定时，肯定值得考虑。


### 总结


构建嵌入式 Linux 系统有多种选择，每种都有优点和缺点。将这部分设计放在优先位置至关重要，因为在以后的过程中切换系统的成本非常高。除了这些选择之外，还有新的系统在开发中。希望这次讨论能够为评估新的系统（以及这里提到的系统）提供一些背景，并帮助您为下一个项目做出坚实的决定。




---


via: <https://opensource.com/article/18/6/embedded-linux-build-tools>


作者：[Drew Moseley](https://opensource.com/users/drewmoseley) 选题：[lujun9972](https://github.com/lujun9972) 译者：[LHRChina](https://github.com/LHRChina) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Linux is being deployed into a much wider array of devices than Linus Torvalds anticipated when he was working on it in his dorm room. The variety of supported chip architectures is astounding and has led to Linux in devices large and small; from [huge IBM mainframes](https://en.wikipedia.org/wiki/Linux_on_z_Systems) to [tiny devices](http://www.picotux.com/) no bigger than their connection ports and everything in between. It is used in large enterprise data centers, internet infrastructure devices, and personal development systems. It also powers consumer electronics, mobile phones, and many Internet of Things devices.

When building Linux software for desktop and enterprise-class devices, developers typically use a desktop distribution such as [Ubuntu](https://www.ubuntu.com/) on their build machines to have an environment as close as possible to the one where the software will be deployed. Tools such as [VirtualBox](https://www.virtualbox.org/) and [Docker](https://www.docker.com/) allow even better alignment between development, testing, and productions environments.

## What is an embedded system?

Wikipedia defines an [embedded system](https://en.wikipedia.org/wiki/Embedded_system) as: "A computer system with a dedicated function within a larger mechanical or electrical system, often with real-time computing constraints."

I find it simple enough to say that an embedded system is a computer that most people don't think of as a computer. Its primary role is to serve as an appliance of some sort, and it is not considered a general-purpose computing platform.


The development environment in embedded systems programming is usually very different from the testing and production environments. They may use different chip architectures, software stacks, and even operating systems. Development workflows are very different for embedded developers vs. desktop and web developers. Typically, the build output will consist of an entire software image for the target device, including the kernel, device drivers, libraries, and application software (and sometimes the bootloader).

In this article, I will present a survey of four commonly available options for building embedded Linux systems. I will give a flavor for what it's like to work with each and provide enough information to help readers decide which tool to use for their design. I won't teach you how to use any of them; there are plenty of in-depth online learning resources once you have narrowed your choices. No option is right for all use cases, and I hope to present enough details to direct your decision.

## Yocto

The [Yocto](https://yoctoproject.org/) project is [defined](https://www.yoctoproject.org/about/) as "an open source collaboration project that provides templates, tools, and methods to help you create custom Linux-based systems for embedded products regardless of the hardware architecture." It is a collection of recipes, configuration values, and dependencies used to create a custom Linux runtime image tailored to your specific needs.

Full disclosure: most of my work in embedded Linux has focused on the Yocto project, and my knowledge and bias to this system will likely be evident.

Yocto uses [Openembedded](https://www.openembedded.org/) as its build system. Technically the two are separate projects; in practice, however, users do not need to understand the distinction, and the project names are frequently used interchangeably.

The output of a Yocto project build consists broadly of three components:

**Target run-time binaries:**These include the bootloader, kernel, kernel modules, root filesystem image. and any other auxiliary files needed to deploy Linux to the target platform.**Package feed:**This is the collection of software packages available to be installed on your target. You can select the package format (e.g., deb, rpm, ipk) based on your needs. Some of them may be preinstalled in the target runtime binaries, however, it is possible to build packages for installation into a deployed system.**Target SDK:**These are the collection of libraries and header files representing the software installed on your target. They are used by application developers when building their code to ensure they are linked with the appropriate libraries

### Advantages

The Yocto project is widely used in the industry and has backing from many influential companies. Additionally, it has a large and vibrant developer [community](https://www.yoctoproject.org/community/) and [ecosystem](https://www.yoctoproject.org/ecosystem/participants/) contributing to it. The combination of open source enthusiasts and corporate sponsors helps drive the Yocto project.

There are many options for getting support with Yocto. There are books and other training materials if you wish to do-it-yourself. Many engineers with experience in Yocto are available if you want to hire expertise. And many commercial organizations provide turnkey Yocto-based products or services-based implementation and customization for your design.

The Yocto project is easily expanded through [layers](https://layers.openembedded.org/layerindex/branch/master/layers/), which can be published independently to add additional functionality, to target platforms not available in the project releases, or to store customizations unique to your system. Layers can be added to your configuration to add unique features that are not specifically included in the stock releases; for example, the "[meta-browser](https://layers.openembedded.org/layerindex/branch/master/layer/meta-browser/)" layer contains recipes for web browsers, which can be easily built for your system. Because they are independently maintained, layers can be on a different release schedule (tuned to the layers' development velocity) than the standard Yocto releases.

Yocto has arguably the widest device support of any of the options discussed in this article. Due to support from many semiconductor and board manufacturers, it's likely Yocto will support any target platform you choose. The direct Yocto [releases](https://yoctoproject.org/downloads) support only a few boards (to allow for proper testing and release cycles), however, a standard working model is to use external board support layers.

Finally, Yocto is extremely flexible and customizable. Customizations for your specific application can be stored in a layer for encapsulation and isolation. Customizations unique to a feature layer are generally stored as part of the layer itself, which allows the same settings to be applied simultaneously to multiple system configurations. Yocto also provides a well-defined layer priority and override capability. This allows you to define the order in which layers are applied and searched for metadata. It also enables you to override settings in layers with higher priority; for instance, many customizations to existing recipes will be added in your private layers, with the order precisely controlled by the priorities.

### Disadvantages

The biggest disadvantage with the Yocto project is the learning curve. It takes significant time and effort to learn the system and truly understand it. Depending on your needs, this may be too large of an investment in technologies and competence that are not central to your application. In such cases, working with one of the commercial vendors may be a good option.

Development build times and resources are fairly high for Yocto project builds. The number of packages that need to be built, including the toolchain, kernel, and all target runtime components, is significant. Development workstations for Yocto developers tend to be large systems. Using a compact notebook is not recommended. This can be mitigated by using cloud-based build servers available from many providers. Additionally, Yocto has a built-in caching mechanism that allows it to reuse previously built components when it determines that the parameters for building a particular package have not changed.

### Recommendation

Using the Yocto project for your next embedded Linux design is a strong choice. Of the options presented here, it is the most broadly applicable regardless of your target use case. The broad industry support, active community, and wide platform support make this a good choice for must designers.

## Buildroot

The [Buildroot](https://buildroot.org/) project is defined as "a simple, efficient, and easy-to-use tool to generate embedded Linux systems through cross-compilation." It shares many of the same objectives as the Yocto project, however it is focused on simplicity and minimalism. In general, Buildroot will disable all optional compile-time settings for all packages (with a few notable exceptions), resulting in the smallest possible system. It will be up to the system designer to enable the settings that are appropriate for a given device.

Buildroot builds all components from source but does not support on-target package management. As such, it is sometimes called a firmware generator since the images are largely fixed at build time. Applications can update the target filesystem, but there is no mechanism to install new packages into a running system.

The Buildroot output consists broadly of three components:

- The root filesystem image and any other auxiliary files needed to deploy Linux to the target platform
- The kernel, boot-loader, and kernel modules appropriate for the target hardware
- The toolchain used to build all the target binaries.

### Advantages

Buildroot's focus on simplicity means that, in general, it is easier to learn than Yocto. The core build system is written in Make and is short enough to allow a developer to understand the entire system while being expandable enough to meet the needs of embedded Linux developers. The Buildroot core generally only handles common use cases, but it is expandable via scripting.

The Buildroot system uses normal Makefiles and the Kconfig language for its configuration. Kconfig was developed by the Linux kernel community and is widely used in open source projects, making it familiar to many developers.

Due to the design goal of disabling all optional build-time settings, Buildroot will generally produce the smallest possible images using the out-of-the-box configuration. The build times and build host resources will likewise be smaller, in general, than those of the Yocto project.

### Disadvantages

The focus on simplicity and minimal enabled build options imply that you may need to do significant customization to configure a Buildroot build for your application. Additionally, all configuration options are stored in a single file, which means if you have multiple hardware platforms, you will need to make each of your customization changes for each platform.

Any change to the system configuration file requires a full rebuild of all packages. This is somewhat mitigated by the minimal image sizes and build times compared with Yocto, but it can result in long builds while you are tweaking your configuration.

Intermediate package state caching is not enabled by default and is not as thorough as the Yocto implementation. This means that, while the first build may be shorter than an equivalent Yocto build, subsequent builds may require rebuilding of many components.

### Recommendation

Using Buildroot for your next embedded Linux design is a good choice for most applications. If your design requires multiple hardware types or other differences, you may want to reconsider due to the complexity of synchronizing multiple configurations, however, for a system consisting of a single setup, Buildroot will likely work well for you.

## OpenWRT/LEDE

The [OpenWRT](https://openwrt.org/) project was started to develop custom firmware for consumer routers. Many of the low-cost routers available at your local retailer are capable of running a Linux system, but maybe not out of the box. The manufacturers of these routers may not provide frequent updates to address new threats, and even if they do, the mechanisms to install updated images are difficult and error-prone. The OpenWRT project produces updated firmware images for many devices that have been abandoned by their manufacturers and gives these devices a new lease on life.

The OpenWRT project's primary deliverables are binary images for a large number of commercial devices. There are network-accessible package repositories that allow device end users to add new software to their systems. The OpenWRT build system is a general-purpose build system, which allows developers to create custom versions to meet their own requirements and add new packages, but its primary focus is target binaries.

### Advantages

If you are looking for replacement firmware for a commercial device, OpenWRT should be on your list of options. It is well-maintained and may protect you from issues that the manufacturer's firmware cannot. You can add extra functionality as well, making your devices more useful.

If your embedded design is networking-focused, OpenWRT is a good choice. Networking applications are the primary use case for OpenWRT, and you will likely find many of those software packages available in it.

### Disadvantages

OpenWRT imposes significant policy decisions on your design (vs. Yocto and Buildroot). If these decisions don't meet your design goals, you may have to do non-trivial modifications.

Allowing package-based updates in a fleet of deployed devices is difficult to manage. This, by definition, results in a different software load than what your QA team tested. Additionally, it is difficult to guarantee atomic installs with most package managers, and an ill-timed power cycle can leave your device in an unpredictable state.

### Recommendation

OpenWRT is a good choice for hobbyist projects or for reusing commercial hardware. It is also a good choice for networking applications. If you need significant customization from the default setup, you may prefer Buildroot or Yocto.

## Desktop distros

A common approach to designing embedded Linux systems is to start with a desktop distribution, such as [Debian](https://www.debian.org/) or [Red Hat](https://www.redhat.com/), and remove unneeded components until the installed image fits into the footprint of your target device. This is the approach taken for the popular [Raspbian](https://www.raspbian.org/) distribution for the [Raspberry Pi](https://www.raspberrypi.org/) platform.

### Advantages

The primary advantage of this approach is familiarity. Often, embedded Linux developers are also desktop Linux users and are well-versed in their distro of choice. Using a similar environment on the target may allow developers to get started more quickly. Depending on the chosen distribution, many additional tools can be installed using standard packaging tools such as apt and yum.

It may be possible to attach a display and keyboard to your target device and do all your development directly there. For developers new to the embedded space, this is likely to be a more familiar environment and removes the need to configure and use a tricky cross-development setup.

The number of packages available for most desktop distributions is generally greater than that available for the embedded-specific builders discussed previously. Due to the larger user base and wider variety of use cases, you may be able to find all the runtime packages you need for your application already built and ready for use.

### Disadvantages

Using the target as your primary development environment is likely to be slow. Running compiler tools is a resource-intensive operation and, depending on how much code you are building, may hinder your performance.

With some exceptions, desktop distributions are not designed to accommodate low-resource systems, and it may be difficult to adequately trim your target images. Similarly, the expected workflow in a desktop environment is not ideal for most embedded designs. Getting a reproducible environment in this fashion is difficult. Manually adding and deleting packages is error-prone. This can be scripted using distribution-specific tools, such as [debootstrap](https://wiki.debian.org/Debootstrap) for Debian-based systems. To further improve [reproducibility](https://wiki.debian.org/Debootstrap), you can use a configuration management tool, such as [CFEngine](https://cfengine.com/) (which, full disclosure, is made by my employer, [Mender.io](http://Mender.io)). However, you are still at the mercy of the distribution provider, who will update packages to meet their needs, not yours.

### Recommendation

Be wary of this approach for a product you plan to take to market. This is a fine model for hobbyist applications; however, for products that need support, this approach is likely going to be trouble. While you may be able to get a faster start, it may cost you time and effort in the long run.

## Other considerations

This discussion has focused on build systems' functionality, but there are usually non-functional requirements that may affect your decision. If you have already selected your system-on-chip (SoC) or board, your choice will likely be dictated by the vendor. If your vendor provides a board support package (BSP) for a given system, using it will normally save quite a bit of time, but please research the BSP's quality to avoid issues later in your development cycle.

If your budget allows, you may want to consider using a commercial vendor for your target OS. There are companies that will provide a validated and supported configuration of many of the options discussed here, and, unless you have expertise in embedded Linux build systems, this is a good choice and will allow you to focus on your core competency.

As an alternative, you may consider commercial training for your development staff. This is likely to be cheaper than a commercial OS provider and will allow you to be more self-sufficient. This is a quick way to get over the learning curve for the basics of the build system you choose.

Finally, you may already have some developers with experience with one or more of the systems. If you have engineers who have a preference, it is certainly worth taking that into consideration as you make your decision.

## Summary

There are many choices available for building embedded Linux systems, each with advantages and disadvantages. It is crucial to prioritize this part of your design, as it is extremely costly to switch systems later in the process. In addition to these options, new systems are being developed all the time. Hopefully, this discussion will provide some context for reviewing new systems (and the ones mentioned here) and help you make a solid decision for your next project.

## 1 Comment