diff --git a/content/hardwarebringup.md b/content/hardwarebringup.md new file mode 100644 index 0000000000000000000000000000000000000000..bb6f61b4a64716ab10e72489dae9d2cfe336eec9 --- /dev/null +++ b/content/hardwarebringup.md @@ -0,0 +1,266 @@ ++++ +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).