Skip to content
Snippets Groups Projects
Commit d58847ba authored by Martyn Welch's avatar Martyn Welch Committed by Martyn Welch
Browse files

Add wip version of hardware bring-up page


This page was started as part of T6550, which was put on hold. Add this
page in a wip branch rather than it being part of the new site.

Signed-off-by: default avatarMartyn Welch <martyn.welch@collabora.com>
parent 74f0c550
No related branches found
No related tags found
1 merge request!73Draft: Add hardware bring-up page
Pipeline #196873 failed
+++
date = "2019-12-03"
weight = 100
title = "Hardware Bring-up"
aliases = [
"/old-wiki/User:Martyn/HardwareBringUp"
]
+++
When we wish to utilise Apertis on a new platform, it is highly likely
that "Hardware Bring-Up" will be one of the first tasks that needs to be
performed. Hardware bring-up is the process by which support for an
initially unsupported target platform is iteratively created and tested.
The process of board bring-up by necessity initially follows the boot
process, we need at least a basic implementation of the initial boot
steps in place before moving on to the later steps. It is likely that
this process will be iterative, with the boot process initially being
implemented in a way that is more suited to the development process and
evolving over time with the addition of extra board support to become
closer to that desired for the final end product.
Unless a third party CPU module on an architecture with highly
standardised boot firmware is being used (which may be the case with an
x86 based CPU module, where development of the boot firmware may be
entirely by-passed), development will start with enabling support in a
suitable boot firmware. For the majority of the reference platforms
currently enabled in Apertis (and as a result, the other platforms that
have been enabled in Apertis) have utilised
[U-Boot](https://www.denx.de/wiki/U-Boot) as boot firmware. In this
guide we will assume development is to be carried out on an ARM based
platform, though it is likely that the process would be broadly similar
for targets utilising other architectures as well.
# Development Environment
In order to perform the required development a suitable development
environment will be required. It is likely that early development steps
could be carried out on any Linux host with a suitable toolchain
available. As development progresses the required feature set of the
toolchain will grow and will incorporate tools generally only found in
Debian based development systems. In order to ensure that prospective
Apertis developers have access to a suitable environment, the Apertis
project makes available a [Software Development
Kit](https://wiki.apertis.org/Deployment_Environment) (SDK) which can be
used through VirtualBox.
# Boot firmware source
The two code bases that are most likely to need to be adapted or
configured to bring-up the target hardware are a boot loader, such as
U-Boot and the Linux kernel. Whilst, within reason, any relatively
recent version of a boot loader and Linux kernel can be used some of the
advanced features supported by Apertis have required specific
configuration changes and/or changes to be made to the boot loader and
kernel. In order to minimise work required to support such features
(should they be needed at a later date) and to take full advantage of
the efficiencies afforded by the Apertis platform, it is advisable to
start from the current supported Apertis bootloader. Apertis stores it's
source code in gitlab the currently supported bootloader and kernel can
be found here:
- [U-Boot](https://gitlab.apertis.org/pkg/target/u-boot)
- [Linux Kernel](https://gitlab.apertis.org/pkg/target/linux)
# Development process
## Bootloader Development
Unless developing for a target utilising an Architecture or SoC not
currently supported by the chosen firmware (something that is out of
scope for this guide), it is likely that the initial focus will be on
ensuring that the firmware is correctly configuring the memory timing,
pin multiplexing and serial port configuration . These are generally
configured in a board support file in the U-Boot firmware under
`board/`. Whilst serial ports have broadly been replaced in their
traditional use cases, the simplicity of the port means that it remains
a very common mechanism for sending boot process and debug messages
during board bring-up. If these settings are correctly configured, this
is usually enough to get early an boot message via the serial port when
booted.
Generally it is not necessary to start from scratch. The U-Boot source
contains support for a myriad of existing targets and it's acceptable to
pick support for an existing board, copy it and use that as a basis for
your own board. Please note that whilst this can be more efficient that
starting from scratch, there is a risk of picking up a board that
doesn't follow the latest preferred style/mechanisms, so it's worth
spending a bit of time looking at the available boards and understanding
which mechanisms are being used in the latest boards.
In order to ensure the development process is as efficient as possible,
it is advisable to utilise any available process that allows the target
to be booted from a remote source. In the case of the ARM architecture,
most if not all System-on-Chips (SoCs) provide some mechanism to boot
the device over USB using a SoC specific protocol to load the boot
firmware into RAM. On many SoCs, the boot process must be broken down
into multiple stages as the default state of the system is unable to
handle the size of a full U-Boot binary. In order to enable bigger
binaries to be loaded, U-Boot has the concept of a Secondary Program
Loader (SPL). This is a smaller cut-down version of U-Boot that is
loaded before the main U-Boot binary and is used to configure the system
sufficiently to enable the main U-Boot binary to be loaded. (In fact on
some systems there is also a Tertiary Program Loader (TPL) to enable
loading of the SPL.) U-Boot is able to handle a number of these SoC
specific protocols allowing the multiple stages of U-Boot to be loaded
via these mechanisms. For later components in the boot process, network
booting such as TFTP usually becomes a viable option.
In order to maximise driver reuse and to allow a single binary to
support multiple target platforms, both U-Boot and the Linux kernel make
use of a [device tree](https://elinux.org/Device_Tree_What_It_Is) to
describe the non-discoverable hardware available in a given target
system. It is common to utilise the same device tree in both U-Boot and
the Linux kernel, potentially with an overlay in U-Boot to provide
U-Boot specific customisations to the device tree. The device tree
enables U-Boot's Driver Model (DM) to instantiate drivers to drive
compatible hardware wherever they sit in the devices memory map. The use
of device trees means that for any already supported SoCs, a large part
of the work associated with initial bring up is in adding the required
nodes to the device tree to describe the hardware and enabling the
required drivers. Where possible it is highly recommended to utilise
U-Boot's driver model.
### Apertis Requirements
Apertis utilises the "[Generic Distro Configuration
Concept](https://gitlab.denx.de/u-boot/u-boot/raw/master/doc/README.distro)"
(often referred to as "Distro Boot") during it's boot process. It is
recommended to enable both the required local boot media, PXE and DHCP
options via the `BOOT_TARGET_DEVICES` macro, the PXE and DHCP options
being especially useful during development as this allows the kernel and
subsequent binaries in the boot process to be provided via a network
interface. Such a network interface may be an Ethernet connection
provided by the target board (and enabled in U-Boot) or if no Ethernet
port is available, it is possible to provide networking with a USB RNDIS
gadget should a USB On-The-Go (USB OTG) port be available. This allows
U-Boot to retrieve boot configuration and the required binaries, such as
the Linux kernel, device tree binary (DTB) and initrd, via TFTP.
## Kernel Development
Once U-Boot has reached the point where it can load via the Distro Boot
mechanism we can start to focus on the Linux kernel rather than U-Boot.
At this point we are likely to have a simple device tree, providing
nodes for the minimal support that we've needed to add for the limited
functionality we need in the bootloader. This can be integrated into the
kernel source tree and needs to be expanded whilst enabling support for
board features required at runtime, but which are not required as part
of the bootloader.
In order to provide a user space environment for testing on the target
device, especially before the on-board storage has been enabled and
initialised, it is common to use a [NFS based root file
system](https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt).
This requires networking and NFS support to be enabled in the kernel and
the location of the NFS root can be specified via the Distro Boot
configuration. This of course requires a roof file system and the
Apertis minimal OSpack (downloadable from
[images.apertis.org](https://images.apertis.org)) can be extracted and
used to provide this. The minimal image can be easily extended using
`apt` to install and tools and utilities needed to test the interfaces
and peripherals attached to the system.
Once a point has been reached where the device tree adequately describes
the hardware found in the target platform, it is worth spending the time
to update the device tree found in the U-Boot source to match the one
found in the kernel source to ensure that the two stay in sync.
### Apertis Requirements
In order to support the Apertis user space, the kernels support for
Apparmor should be enabled as this is widely used by Apertis for process
containment. As Apertis uses systemd, it is necessary to also ensure
that the [kernel configuration
options](https://github.com/systemd/systemd/blob/master/README) required
by systemd are also enabled. This will be the case if starting from the
existing [Apertis kernel
configuration]( {{< ref "/guidelines/buildingpatchingandmaintainingtheapertiskernel.md#building" >}} ).
Further guidance regarding the integration of specific hardware is
provided in [Hardware Interfaces]( {{< ref "/hardware_interfaces.md" >}} ).
## Packaging Components
Once we have a kernel booting to an NFS-based rootfs with sufficient
support (including the local storage that is to be used), we need to
package the bootloader and kernel. If using the Apertis supplied
bootloader and kernel, a lot of the necessary metadata will already be
in place and the workflow has been documented in [Building, Patching And
Maintaining The Apertis
Kernel]( {{< ref "/guidelines/buildingpatchingandmaintainingtheapertiskernel.md" >}} ).
If working from a kernel from another source, it will be necessary to
become familiar with [Debian
packaging](https://wiki.debian.org/Packaging/Intro). Note that the
Debian kernel (and thus the Apertis kernel) utilise a slightly modified
approach to configuration compared with most deb packages due to the
special nature of the kernel. More information about the kernel
configuration, see the Debian kernel's
[README.Debian](https://salsa.debian.org/kernel-team/linux/blob/master/debian/README.Debian).
## Creating Target Specific Images
Once the bootloader and kernel have been packaged, an image suitable for
loading onto the device can be created. Building these packages is
expected to be carried out from source by the Apertis infrastructure,
ensuring all packages dependencies are properly described and reducing
the risk of unexpected dependencies. This also results in the packages
being made available in a deb package repository and thus available by
the image creation tooling.
These packages are usually assembled into 2 bigger building blocks
before ultimately being combined, the `OSpack` and the `HWpack`. The
process is managed by a tool called
[Debos](https://github.com/go-debos/debos), which uses yaml
configuration files to guide what steps it takes.
### OSpack
The OSpack is a generic (architecture specific but largely hardware
independent) archived rootfs built from Apertis packages. Apertis
provides Debos yaml files to assemble a number of differently targeted
OSpacks, ranging from a minimal GUI-less OSpack, a target focused GUI
OSpack and a development environment with a desktop style GUI.
### HWpack
Unlike the OSpack, that is generic, the hardware pack (HWpack) contains
the bits needed to boot on a specific target. The HWpack is not a single
item, it is a number of packages and processes, controlled via a Debos
script, that convert a hardware independent OSpack into an image which
can be successfully booted on a specific hardware platform. It is
expected a small number of OSpacks to be combined with a number of
HWpacks to create an array of images suitable for a wide range of
targets.
The configuration used to create OSpacks and images from them for the
Apertis reference platforms can be found in
[GitLab](https://gitlab.apertis.org/infrastructure/apertis-image-recipes)
with their use documented in `README.md`.
To find out more about the process of creating OSpacks and HWpacks, see
[Image Building]( {{< ref "/image_building.md" >}} ).
### Building images for hypervisors and virtual machines
TBD (Basically the same as packaging for real hardware)
# Testing
TBD
- Boot test on both new and existing hardware
- Boot test
- Ensure changes do not result in regressions against Apertis tests
# Submitting Upstream
The Apertis project strongly supports the concept of upstreaming and
supports it's users to upstream. The Apertis project provides
documentation covering [why, where and
what](https://designs.apertis.org/latest/upstreaming.html) to upstream,
as well as [guidance on the upstreaming
process](https://designs.apertis.org/latest/contribution-process.html).
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment