Translated by qhwdw

This commit is contained in:
qhwdw 2018-02-08 18:06:49 +08:00
parent b0147c2856
commit 72f8f7b715
2 changed files with 132 additions and 134 deletions

View File

@ -1,134 +0,0 @@
Translating by qhwdw
Custom Embedded Linux Distributions
======
### Why Go Custom?
In the past, many embedded projects used off-the-shelf distributions and stripped them down to bare essentials for a number of reasons. First, removing unused packages reduced storage requirements. Embedded systems are typically shy of large amounts of storage at boot time, and the storage available, in non-volatile memory, can require copying large amounts of the OS to memory to run. Second, removing unused packages reduced possible attack vectors. There is no sense hanging on to potentially vulnerable packages if you don't need them. Finally, removing unused packages reduced distribution management overhead. Having dependencies between packages means keeping them in sync if any one package requires an update from the upstream distribution. That can be a validation nightmare.
Yet, starting with an existing distribution and removing packages isn't as easy as it sounds. Removing one package might break dependencies held by a variety of other packages, and dependencies can change in the upstream distribution management. Additionally, some packages simply cannot be removed without great pain due to their integrated nature within the boot or runtime process. All of this takes control of the platform outside the project and can lead to unexpected delays in development.
A popular alternative is to build a custom distribution using build tools available from an upstream distribution provider. Both Gentoo and Debian provide options for this type of bottom-up build. The most popular of these is probably the Debian debootstrap utility. It retrieves prebuilt core components and allows users to cherry-pick the packages of interest in building their platforms. But, debootstrap originally was only for x86 platforms. Although there are ARM (and possibly other) options now, debootstrap and Gentoo's catalyst still take dependency management away from the local project.
Some people will argue that letting someone else manage the platform software (like Android) is much easier than doing it yourself. But, those distributions are general-purpose, and when you're sitting on a lightweight, resource-limited IoT device, you may think twice about any any advantage that is taken out of your hands.
### System Bring-Up Primer
A custom Linux distribution requires a number of software components. The first is the toolchain. A toolchain is a collection of tools for compiling software, including (but not limited to) a compiler, linker, binary manipulation tools and standard C library. Toolchains are built specifically for a target hardware device. A toolchain built on an x86 system that is intended for use with a Raspberry Pi is called a cross-toolchain. When working with small embedded devices with limited memory and storage, it's always best to use a cross-toolchain. Note that even applications written for a specific purpose in a scripted language like JavaScript will need to run on a software platform that needs to be compiled with a cross-toolchain.
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12278f1.png)
Figure 1\. Compile Dependencies and Boot Order
The cross-toolchain is used to build software components for the target hardware. The first component needed is a bootloader. When power is applied to a board, the processor (depending on design) attempts to jump to a specific memory location to start running software. That memory location is where a bootloader is stored. Hardware can have a built-in bootloader that can be run directly from its storage location or it may be copied into memory first before it is run. There also can be multiple bootloaders. A first-stage bootloader would reside on the hardware in NAND or NOR flash, for example. Its sole purpose would be to set up the hardware so a second-stage bootloader, such as one stored on an SD card, can be loaded and run.
Bootloaders have enough knowledge to get the hardware to the point where it can load Linux into memory and jump to it, effectively handing control over to Linux. Linux is an operating system. This means that, by design, it doesn't actually do anything other than monitor the hardware and provide services to higher layer software—aka applications. The [Linux kernel][1] often is accompanied by a variety of firmware blobs. These are software objects that have been precompiled, often containing proprietary IP (intellectual property) for devices used with the hardware platform. When building a custom distribution, it may be necessary to acquire any firmware blobs not provided by the Linux kernel source tree before beginning compilation of the kernel.
Applications are stored in the root filesystem. The root filesystem is constructed by compiling and collecting a variety of software libraries, tools, scripts and configuration files. Collectively, these all provide the services, such as network configuration and USB device mounting, required by applications the project will run.
In summary, a complete system build requires the following components:
1. A cross-toolchain.
2. One or more bootloaders.
3. The Linux kernel and associated firmware blobs.
4. A root filesystem populated with libraries, tools and utilities.
5. Custom applications.
### Start with the Right Tools
The components of the cross-toolchain can be built manually, but it's a complex process. Fortunately, tools exist that make this process easier. The best of them is probably [Crosstool-NG][2]. This project utilizes the same kconfig menu system used by the Linux kernel to configure the bits and pieces of the toolchain. The key to using this tool is finding the correct configuration items for the target platform. This typically includes the following items:
1. The target architecture, such as ARM or x86.
2. Endianness: little (typically Intel) or big (typically ARM or others).
3. CPU type as it's known to the compiler, such as GCC's use of either -mcpu or --with-cpu.
4. The floating point type supported, if any, by the CPU, such as GCC's use of either -mfpu or --with-fpu.
5. Specific version information for the binutils package, the C library and the C compiler.
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12278f2.png)
Figure 2. Crosstool-NG Configuration Menu
The first four are typically available from the processor maker's documentation. It can be hard to find these for relatively new processors, but for the Raspberry Pi or BeagleBoards (and their offspring and off-shoots), you can find the information online at places like the [Embedded Linux Wiki][3].
The versions of the binutils, C library and C compiler are what will separate the toolchain from any others that might be provided from third parties. First, there are multiple providers of each of these things. Linaro provides bleeding-edge versions for newer processor types, while working to merge support into upstream projects like the GNU C Library. Although you can use a variety of providers, you may want to stick to the stock GNU toolchain or the Linaro versions of the same.
Another important selection in Crosstool-NG is the version of the Linux kernel. This selection gets headers for use with various toolchain components, but it is does not have to be the same as the Linux kernel you will boot on the target hardware. It's important to choose a kernel that is not newer than the target hardware's kernel. When possible, pick a long-term support kernel that is older than the kernel that will be used on the target hardware.
For most developers new to custom distribution builds, the toolchain build is the most complex process. Fortunately, binary toolchains are available for many target hardware platforms. If building a custom toolchain becomes problematic, search online at places like the [Embedded Linux Wiki][4] for links to prebuilt toolchains.
### Booting Options
The next component to focus on after the toolchain is the bootloader. A bootloader sets up hardware so it can be used by ever more complex software. A first-stage bootloader is often provided by the target platform maker, burned into on-hardware storage like an EEPROM or NOR flash. The first-stage bootloader will make it possible to boot from, for example, an SD card. The Raspberry Pi has such a bootloader, which makes creating a custom bootloader unnecessary.
Despite that, many projects add a secondary bootloader to perform a variety of tasks. One such task could be to provide a splash animation without using the Linux kernel or userspace tools like plymouth. A more common secondary bootloader task is to make network-based boot or PCI-connected disks available. In those cases, a tertiary bootloader, such as GRUB, may be necessary to get the system running.
Most important, bootloaders load the Linux kernel and start it running. If the first-stage bootloader doesn't provide a mechanism for passing kernel arguments at boot time, a second-stage bootloader may be necessary.
A number of open-source bootloaders are available. The [U-Boot project][5] often is used for ARM platforms like the Raspberry Pi. CoreBoot typically is used for x86 platform like the Chromebook. Bootloaders can be very specific to target hardware. The choice of bootloader will depend on overall project requirements and target hardware (search for lists of open-source bootloaders be online).
### Now Bring the Penguin
The bootloader will load the Linux kernel into memory and start it running. Linux is like an extended bootloader: it continues hardware setup and prepares to load higher-level software. The core of the kernel will set up and prepare memory for sharing between applications and hardware, prepare task management to allow multiple applications to run at the same time, initialize hardware components that were not configured by the bootloader or were configured incompletely and begin interfaces for human interaction. The kernel may not be configured to do this on its own, however. It may include an embedded lightweight filesystem, known as the initramfs or initrd, that can be created separately from the kernel to assist in hardware setup.
Another thing the kernel handles is downloading binary blobs, known generically as firmware, to hardware devices. Firmware is pre-compiled object files in formats specific to a particular device that is used to initialize hardware in places that the bootloader and kernel cannot access. Many such firmware objects are available from the Linux kernel source repositories, but many others are available only from specific hardware vendors. Examples of devices that often provide their own firmware include digital TV tuners or WiFi network cards.
Firmware may be loaded from the initramfs or may be loaded after the kernel starts the init process from the root filesystem. However, creating the kernel often will be the process where obtaining firmware will occur when creating a custom Linux distribution.
### Lightweight Core Platforms
The last thing the Linux kernel does is to attempt to run a specific program called the init process. This can be named init or linuxrc or the name of the program can be passed to the kernel by the bootloader. The init process is stored in a file system that the kernel can access. In the case of the initramfs, the file system is stored in memory (either by the kernel itself or by the bootloader placing it there). But the initramfs is not typically complete enough to run more complex applications. So another file system, known as the root file system, is required.
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12278f3.png)
Figure 3\. Buildroot Configuration Menu
The initramfs filesystem can be built using the Linux kernel itself, but more commonly, it is created using a project called [BusyBox][6]. BusyBox combines a collection of GNU utilities, such as grep or awk, into a single binary in order to reduce the size of the filesystem itself. BusyBox often is used to jump-start the root filesystem's creation.
But, BusyBox is purposely lightweight. It isn't intended to provide every tool that a target platform will need, and even those it does provide can be feature-reduced. BusyBox has a sister project known as [Buildroot][7], which can be used to get a complete root filesystem, providing a variety of libraries, utilities and scripting languages. Like Crosstool-NG and the Linux kernel, both BusyBox and Buildroot allow custom configuration using the kconfig menu system. More important, the Buildroot system handles dependencies automatically, so selection of a given utility will guarantee that any software it requires also will be built and installed in the root filesystem.
Buildroot can generate a root filesystem archive in a variety of formats. However, it is important to note that the filesystem only is archived. Individual utilities and libraries are not packaged in either Debian or RPM formats. Using Buildroot will generate a root filesystem image, but its contents are not managed packages. Despite this, Buildroot does provide support for both the opkg and rpm package managers. This means custom applications that will be installed on the root filesystem can be package-managed, even if the root filesystem itself is not.
### Cross-Compiling and Scripting
One of Buildroot's features is the ability to generate a staging tree. This directory contains libraries and utilities that can be used to cross-compile other applications. With a staging tree and the cross toolchain, it becomes possible to compile additional applications outside Buildroot on the host system instead of on the target platform. Using rpm or opkg, those applications then can be installed to the root filesystem on the target at runtime using package management software.
Most custom systems are built around the idea of building applications with scripting languages. If scripting is required on the target platform, a variety of choices are available from Buildroot, including Python, PHP, Lua and JavaScript via Node.js. Support also exists for applications requiring encryption using OpenSSL.
### What's Next
The Linux kernel and bootloaders are compiled like most applications. Their build systems are designed to build a specific bit of software. Crosstool-NG and Buildroot are metabuilds. A metabuild is a wrapper build system around a collection of software, each with their own build systems. Alternatives to these include [Yocto][8] and [OpenEmbedded][9]. The benefit of Buildroot is the ease with which it can be wrapped by an even higher-level metabuild to automate customized Linux distribution builds. Doing this opens the option of pointing Buildroot to project-specific cache repositories. Using cache repositories can speed development and offers snapshot builds without worrying about changes to upstream repositories.
An example implementation of a higher-level build system is [PiBox][10]. PiBox is a metabuild wrapped around all of the tools discussed in this article. Its purpose is to add a common GNU Make target construction around all the tools in order to produce a core platform on which additional software can be built and distributed. The PiBox Media Center and kiosk projects are implementations of application-layer software installed on top of the core platform to produce a purpose-built platform. The [Iron Man project][11] is intended to extend these applications for home automation, integrated with voice control and IoT management.
But PiBox is nothing without these core software tools and could never run without an in-depth understanding of a complete custom distribution build process. And, PiBox could not exist without the long-term dedication of the teams of developers for these projects who have made custom-distribution-building a task for the masses.
--------------------------------------------------------------------------------
via: http://www.linuxjournal.com/content/custom-embedded-linux-distributions
作者:[Michael J.Hammel][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxjournal.com/user/1000879
[1]:https://www.kernel.org
[2]:http://crosstool-ng.github.io
[3]:https://elinux.org/Main_Page
[4]:https://elinux.org/Main_Page
[5]:https://www.denx.de/wiki/U-Boot
[6]:https://busybox.net
[7]:https://buildroot.org
[8]:https://www.yoctoproject.org
[9]:https://www.openembedded.org/wiki/Main_Page
[10]:https://www.piboxproject.com
[11]:http://redmine.graphics-muse.org/projects/ironman/wiki/Getting_Started

View File

@ -0,0 +1,132 @@
定制嵌入式 Linux 发行版
======
### 为什么要定制?
以前,许多嵌入式项目都使用现成的发行版,然后出于种种原因,再将它们剥离到只剩下基本的必需的东西。首先,移除不需要的包以减少占用的存储空间。在启动时,嵌入式系统一般不需要大量的存储空间以及可用存储空间。在嵌入式系统运行时,可能从非易失性内存中拷贝大量的操作系统文件到内存中。第二,移除用不到的包可以降低可能的攻击面。如果你不需要它们就没有必要把这些可能有漏洞的包挂在上面。最后,移除用不到包可以降低发行管理的开销。如果在包之间有依赖关系,意味着任何一个包请求从上游更新,那么它们都必须保持同步。那样可能就会出现验证噩梦。
然而,从现在的发行版开始去移除包并不像说的那样容易。移除一个包可能会打破与其它包保持的各种依赖关系,以及可能在上游的发行管理中改变依赖。另外,由于在引导或者运行时进程中的集成特性,一些包并不能轻易地简单地移除。所有这些都是项目之外的平台的管理,并且有可能会导致意外的开发延迟。
一个普通的选择是从上游发行版供应商处使用有效的构建工具去构建一个定制的发行版。无论是 Gentoo 还是 Debian 都提供这种自下而上的构建方式。这些构建工具中最为流行的可能是 Debian 的 debootstrap 实用程序。它取出预构建的核心组件并允许用户去精选出它们感兴趣的包来构建用户自己的平台。但是debootstrap 最初仅在 x86 平台上可用,虽然,现在有了 ARM也有可能会有其它的平台选项。debootstrap 和 Gentoo 的 catalyst 仍然从本地项目中将依赖管理移除。
一些人认为让别人去管理平台软件(像 Android 一样)要比自己亲自管理容易的多。但是,那些发行版都是多用途的,当你在一个轻量级的、资源有限的物联网设备上使用它时,你可能会再三考虑从你手中被拿走的任何益处。
### 系统 Bring-Up Primer
一个定制的 Linux 发行版要求许多软件组件。其中第一个就是工具链。一个工具链是编译软件的一个工具集合。包括(但不限于)一个编译器、链接器、二进制操作工具以及标准的 C 库。工具链是为一个特定的目标硬件设备专门构建的。如果一个构建在 x86 系统上的工具链想要使用在树莓派上,那么这个工具链就被称为交叉编译工具链。当在内存和存储都十分有限的小型嵌入式设备上工作时,最好是使用一个交叉编译工具链。需要注意的是,即便是使用像 JavaScript 这样的脚本语言编写的应用程序,也需要使用交叉编译工具链编译的一个软件平台上去运行。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12278f1.png)
图 1\. 编译依赖和引导顺序
交叉编译工具链用于为目标硬件构建软件组件。需要的第一个组件是引导加载程序。当计算机主板加电之后,处理器(可能有差异,取决于设计)尝试去跳转到一个特定的内存位置去开始运行软件。那个内存位置就是保存引导加载程序的地方。硬件可能有内置的引导加载程序,它可能直接从它的存储位置或者它可能拷贝到内存中它首次运行的位置。那里也可能会有多个引导加载程序。例如,一个第一阶段的引导加载程序可能位于硬件的 NAND 或者 NOR 闪存中。它唯一的功能是设置硬件以便于执行第二阶段的引导加载程序,比如,存储在 SD 卡中的可以被加载并运行的引导加载程序。
引导加载程序能够从硬件中取得足够的信息,将 Linux 加载到内存中并跳转到正确的位置,将控制权有效地移交到 LinuxLinux 是一个操作系统。这意味着,在这种设计中,它除了监控硬件和向上层软件(也就是应用程序)提供服务外,它实际上什么都不做。[Linux 内核][1] 中通常是各种各样的固件块。那些预编译的软件对象,通常包含硬件平台使用的设备的专用 IP知识资产当构建一个定制发行版时在开始编译内核之前它可能会要求获得一些 Linux 内核源树没有提供的必需的固件块。
应用程序保存在 root 文件系统中,这个 root 文件系统是通过编译构建的,它集合了各种软件库、工具、脚本以及配置文件。总的来说,它们都提供服务,比如,网络配置和 USB 驱动加载,这些都是将要运行的项目应用程序所需要的。
总的来说,一个完整的系统构建要求下列的组件:
1. 一个交叉编译工具链
2. 一个或多个引导加载程序
3. Linux 内核和相关的固件块
4. 一个包含库、工具以及实用程序的 root 文件系统
5. 定制的应用程序
### 使用适当的工具开始构建
交叉编译工具链的组件可以手工构建,但这是一个很复杂的过程。幸运的是,现有的工具可以很容易地完成这一过程。构建交叉编译工具链的最好工具可能是 [Crosstool-NG][2],这个工具使用了与 Linux 内核相同的 kconfig 菜单系统来构建工具链的位和片断。使用这个芽的关键是,为目标平台找到正确的配置项。配置项通常包含下列内容:
1. 目标架构,比如,是 ARM 还是 x86。
2. 字节顺序小字节顺序一般情况下Intel 采用这种顺序还是大字节顺序一般情况下ARM 或者其它的平台采用这种顺序)。
3. 编译器已知的 CPU 类型比如GCC 既可以使用 -mcpu 也可以使用 --with-cpu。
4. 支持的浮点类型如果有的话比如GCC 既可以使用 -mfpu 也可以使用 --with-fpu。
5. 二进制工具包、C 库以及 C 编译器的特定版本信息。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12278f2.png)
图 2. Crosstool-NG 配置菜单
前四个一般情况下可以从处理器制造商的文档中获得。对于较新的处理器,它们可能不容易找到,但是,像树莓派或者 BeagleBoards以及它们的后代和分支你可以在像 [嵌入式 Linux Wiki][3] 这样的地方找到相关信息。
二进制实用工具、C 库、以及 C 编译器的版本将与任何第三方提供的其它工具链分开。首先它们中的每一个都有多个提供者。Linaro 为最新的处理器类型提供了最先进的版本,同时致力于将支持合并到像 GNU C 库这样的上游项目中。尽管你可以使用各种提供者的工具,你可能想去使用现成的 GNU 工具链或者相同版本的 Linaro。
在 Crosstool-NG 中的另外的重要选择是 Linux 内核的版本。这个选择将得到用于各种工具链组件的头,但是它没有必要一定与你在目标硬件上将要引导的 Linux 内核相同。选择一个不比目标硬件的内核更新的 Linux 内核是很重要的。如果可能的话,尽量选择一个比目标硬件使用的内核更老的长周期支持的内核。
对于大多数不熟悉构建定制发行版的开发者来说,工具链的构建是最为复杂的过程。幸运的是,大多数硬件平台的二进制工具链都可以想办法得到。如果构建一个定制的工具链有问题,可以去在线搜索像 [嵌入式 Linux Wiki][4] 这样的地方去查找预构建工具链。
### 引导选项
在构建完工具链之后,接下来的工作是引导加载程序。引导加载程序用于设置硬件,以便于越来越复杂的软件能够使用这些硬件。第一阶段的引导加载程序通常由目标平台制造商提供,它通常被烧录到类似于 EEPROM 或者 NOR 闪存这类的在硬件上的存储中。第一阶段的引导加载程序将使设备从这里开始引导,比如,一个 SD 存储卡。树莓派的引导加载程序就是这样的,它样做也就没有必要再去创建一个定制引导加载程序。
尽管如此,许多项目还是增加了第二阶段的引导加载程序,以便于去执行一个多样化的任务。在无需使用 Linux 内核或者像 plymouth 这样的用户空间工具的情况下提供一个启动动画,就是其中一个这样的任务。一个更常见的第二阶段引导加载程序的任务是去提供基于网络的引导或者使连接到 PCI 上的磁盘可用。在那种情况下,一个第三阶段的引导加载程序,比如 GRUB可能才是让系统运行起来所必需的。
最重要的是,引导加载程序加载 Linux 内核并使它开始运行。如果第一阶段引导加载程序没有提供一个在启动时传递内核参数的机制,那么,在第二阶段的引导加载程序中就必须要提供。
有许多的开源引导加载程序可以使用。[U-Boot 项目][5] 通常是用于像树莓派这样的 ARM 平台。CoreBoot 一般是用于像 Chromebook 这样的 x86 平台。引导加载程序是目标硬件专用的。引导加载程序的选择总体上取决于项目的需求以及目标硬件(可以去网络上在线搜索开源引导加载程序的列表)。
### Now Bring the Penguin
引导加载程序将加载 Linux 内核到内存中然后去运行它。Linux 就像一个扩展的引导加载程序:它包含了硬件设置以及加载高级软件的预处理工作。内核的核心将设置和预处理应用程序和硬件之间共享使用的内存;预处理任务管理器以允许多个应用程序同时运行;初始化没有被引导加载程序配置的或者是已经配置了但是没有完成的硬件组件;以及开启人机交互界面。内核可以并不会配置为它自己去做这些工作,但是,它可以包含一个嵌入的、轻量级的文件系统,这类文件系统大家熟知的有 initramfs 或者 initrd它们可以独立于内核而创建用于去辅助设置硬件。
内核操作的另外的事情是去下载二进制块(通常称为固件)到硬件设备。固件是用特定格式预编译的对象文件,用于在引导加载程序或者内核不能访问的地方去初始化特定硬件。许多的这种固件对象可以从 Linux 内核源仓库中获取,但是,还有很多其它的固件只能从特定的硬件供应商处获得。例如,经常由它们自己提供固件的设备有数字电视调谐器或者 WiFi 网卡。
固件可以从 initramfs 中加载,也或者是在内核从 root 文件系统中启动 init 进程之后加载。但是,当你去创建一个定制的 Linux 发行版时,创建内核的过程常常就是获取各种固件的过程。
### 轻量级核心平台
Linux 内核做的最后一件事情是尝试去运行一个被称为 init 进程的专用程序。这个专用程序的名字可能是 init 或者 linuxrc 或者是由加载程序传递给内核的名字。init 进程保存在一个能够被内核访问的文件系统中。在 initramfs 的示例中这个文件系统保存在内存中它可能是被内核自己放置到那里也可能是被引导加载程序放置在那里。但是对于运行更复杂的应用程序initramfs 通常并不够完整。因此需要另外一个文件系统,这就是众所周知的 root 文件系统。
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12278f3.png)
图 3\. 构建 root 配置菜单
initramfs 文件系统可以使用 Linux 内核自己去构建,但是更常用的作法是,使用一个被称为 [BusyBox][6] 的项目去创建。BusyBox 组合许多 GNU 实用程序比如grep 或者 awk到一个单个的二进制文件中以便于减小文件系统自身的大小。BusyBox 通常用于去启动 root 文件系统的创建过程。
但是BusyBox 是特意轻量化设计的。它并不打算提供目标平台所需要的所有工具甚至提供的工具也是经过功能简化的。BusyBox 有一个“妹妹”项目叫做 [Buildroot][7],它可以用于去得到一个完整的 root 文件系统,提供了各种库、实用程序、以及脚本语言。像 Crosstool-NG 和 Linux 内核一样BusyBox 和 Buildroot 也都允许使用 kconfig 菜单系统去定制配置。更重要的是Buildroot 系统自动处理依赖关系,因此,选定实用程序将会保证该程序所需要的软件也会被构建并安装到 root 文件系统。
Buildroot 可以用多种格式去生成一个 root 文件系统包。但是,需要重点注意的是,这个文件系统是被打包的。单个的实用程序和库并不是以 Debian 或者 RPM 格式打包进去的。使用 Buildroot 将生成一个 root 文件系统镜像但是它的内容不是管理包。即使如此Buildroot 还是提供对 opkg 和 rpm 包管理器的支持的。这意味着,虽然 root 文件系统自身并不支持包管理,但是,安装在 root 文件系统上的定制应用程序能够进行包管理。
### 交叉编译和脚本化
Buildroot 的其中一个特性是能够生成一个临时树。这个目录包含库和实用程序,它可以被用于去交叉编译其它应用程序。使用一个临时树和交叉编译工具链,在主机系统上而不是目标平台上对 Buildroot 之外的其它应用程序编译成为可能。使用 rpm 或者 opkg 包管理软件之后,这些应用程序可以在运行时被安装在目标平台的 root 文件系统上。
大多数定制系统的构建都是围绕着用脚本语言构建应用程序的想法去构建的。如果需求在目标平台上运行脚本,在 Buildroot 上有多种可用的选择,包括 Python、PHP、Lua 以及基于 Node.js 的 JavaScript。对于需要使用 OpenSSL 加密的应用程序也提供支持。
### 接下来做什么
Linux 内核和引导加载程序的编译过程与大多数应用程序是一样的。它们的构建系统被设计为去构建一个专用的软件位。Crosstool-NG 和 Buildroot 是元构建。一个元构建是将一系列有自己构建系统的软件集合封装为一个构建系统。可靠的元构建包括 [Yocto][8] 和 [OpenEmbedded][9]。Buildroot 的好处是可以将更高级别的元构建进行轻松的封装,以便于将定制 Linux 发行版的构建过程自动化。这样做之后,将会打开 Buildroot 指向到项目专用的缓存仓库的选项。使用缓存仓库可以加速开发过程,并且可以在无需担心上游仓库变化的情况下提供构建快照。
一个实现高级构建系统的示例是 [PiBox][10]。PiBox 就是封装了在本文中讨论的各种工具的一个元构建。它的目的是黑围绕所有工具去增加一个通用的 GNU Make 目标架构为了生成一个核心平台这个平台可以构建或分发其它软件。PiBox 媒体中心和 kiosk 项目是安装在核心平台之上的应用层软件的实现,目的是用于去产生一个构建平台。[Iron Man 项目][11] 是为了家庭自动化的目的而扩展了这种应用程序,它集成了语音管理和物联网设备的管理。
但是PiBox 如果没有这些核心的软件工具,它什么也做不了。并且,如果不去深入了解一个完整的定制发行版的构建过程,那么你将无法正确运行 PiBox。而且如果没有 PiBox 开发团队对这个项目的长期奉献,也就没有 PiBox 项目,它完成了定制发行版构建中的大量任务。
--------------------------------------------------------------------------------
via: http://www.linuxjournal.com/content/custom-embedded-linux-distributions
作者:[Michael J.Hammel][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxjournal.com/user/1000879
[1]:https://www.kernel.org
[2]:http://crosstool-ng.github.io
[3]:https://elinux.org/Main_Page
[4]:https://elinux.org/Main_Page
[5]:https://www.denx.de/wiki/U-Boot
[6]:https://busybox.net
[7]:https://buildroot.org
[8]:https://www.yoctoproject.org
[9]:https://www.openembedded.org/wiki/Main_Page
[10]:https://www.piboxproject.com
[11]:http://redmine.graphics-muse.org/projects/ironman/wiki/Getting_Started