Compare commits
2 Commits
HEAD
...
docs/docke
| Author | SHA1 | Date |
|---|---|---|
|
|
162c0098b8 | |
|
|
f275e7e499 |
|
|
@ -1,10 +0,0 @@
|
|||
digraph G {
|
||||
fw [label = "Firmware";shape = rect;];
|
||||
|
||||
btl [label = "Bootloader";shape = rect;];
|
||||
|
||||
os [label = "Operating System";shape = rect;];
|
||||
|
||||
fw -> btl -> os [style = dashed;];
|
||||
fw -> os;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
@startuml
|
||||
!theme cloudscape-design
|
||||
start
|
||||
:**Firmware**;
|
||||
note right
|
||||
Implement a subset of the UEFI specification
|
||||
Usually implemented by u-boot
|
||||
end note
|
||||
:**Bootloader**
|
||||
efibootguard;
|
||||
note right
|
||||
The bootloader is responsible to find and load the Operating System
|
||||
It's an UEFI application that can be signed
|
||||
end note
|
||||
:**Operating System**
|
||||
Unified Kernel Image;
|
||||
note right
|
||||
The Operating System is a single UEFI application that can be signed
|
||||
This application has to call the ExitBootService UEFI protocol
|
||||
This application contains at least the Linux Kernel
|
||||
end note
|
||||
end
|
||||
@enduml
|
||||
|
|
@ -3,7 +3,7 @@ digraph G {
|
|||
|
||||
uboot [label = "u-boot with EFI/EBBR support";shape = rect;];
|
||||
|
||||
kernel [label = "OS (EFI Stub + Kernel + Initramfs";shape = rect;];
|
||||
kernel [label = "UKI (EFI Stub + Kernel + DTS + Initramfs";shape = rect;];
|
||||
|
||||
rom -> uboot -> kernel;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
***********
|
||||
Disk Layout
|
||||
***********
|
||||
|
||||
Standard Disk Layout
|
||||
====================
|
||||
|
||||
|
||||
|
||||
Disk Layout using GPT
|
||||
======================
|
||||
|
||||
Modern product use a GPT partionning disk with at least 5 partitions:
|
||||
|
||||
- EFI
|
||||
- PLATFORM0
|
||||
- PLATFORM1
|
||||
- BOOT0
|
||||
- BOOT1
|
||||
|
||||
Order and position of theses partitions doesn't matter as long as the
|
||||
right partition label, partition label and filesystem are used.
|
||||
|
||||
.. image:: disk/disk-layout.png
|
||||
|
||||
Partitions
|
||||
==========
|
||||
|
||||
EFI
|
||||
---
|
||||
|
||||
The EFI partition contains the bootloader (efibootguard).
|
||||
|
||||
.. image:: disk/part-efi.png
|
||||
|
||||
BOOT0 and BOOT1
|
||||
---------------
|
||||
|
||||
The BOOT0 and BOOT1 partition contains a kernel and a configuration files.
|
||||
|
||||
.. image:: disk/part-boot0.png
|
||||
|
||||
PLATFORM0 and PLATFORM1
|
||||
-----------------------
|
||||
|
||||
The PLATFORM0 and PLATFORM1 partitions contains a Linux root filesystem.
|
||||
|
||||
.. image:: disk/part-platform0.png
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
|
|
@ -0,0 +1,100 @@
|
|||
************************
|
||||
Bootloader: efibootguard
|
||||
************************
|
||||
|
||||
Efibootguard is the default bootloader of CoreOS. It's an open source
|
||||
bootloader based on UEFI made by Siemens and released under GPLv2, that
|
||||
implement the A/B booting scheme.
|
||||
|
||||
Efibootguard allow us to have a redondant boot partition that contain a
|
||||
configuration file for efibootguard and a signed Unified Kernel Image
|
||||
|
||||
A/B Switch
|
||||
==========
|
||||
|
||||
Two partition are used to store two diffrent configuration. The first partition
|
||||
is called boot0 and the second one boot1.
|
||||
|
||||
At boot, efibootguard find the configuration file stored inside each boot
|
||||
partition and load it. Inside the configuration, the field "revision" is used
|
||||
to select the configuration to use to boot the board. It will be the one
|
||||
with the highest revision
|
||||
|
||||
.. uml::
|
||||
|
||||
@startuml
|
||||
!theme cloudscape-design
|
||||
start
|
||||
partition A/B selector {
|
||||
|
||||
:read boot0 configuration;
|
||||
:read boot1 configuration;
|
||||
|
||||
if (boot0.revision > boot1.revision") then (yes)
|
||||
:select boot0;
|
||||
else (no)
|
||||
:select boot1;
|
||||
endif
|
||||
}
|
||||
|
||||
end
|
||||
@enduml
|
||||
|
||||
State checking
|
||||
==============
|
||||
|
||||
After having selecting the configuration to use, efibootguard will use the
|
||||
state field to determine is the configuration is already know to work or not.
|
||||
|
||||
Theses states are possible:
|
||||
|
||||
- ok: the configuration is known to be working
|
||||
- installed: the configuration was just updated and was never booted
|
||||
- testing: the configuration was just updated and was already booted once
|
||||
- failed: the configuration is not working
|
||||
|
||||
.. uml::
|
||||
|
||||
@startuml
|
||||
!theme cloudscape-design
|
||||
start
|
||||
partition state checking {
|
||||
switch (state?)
|
||||
case ( ok )
|
||||
:set state to ok;
|
||||
case ( installed )
|
||||
:set state to testing;
|
||||
case ( testing )
|
||||
:set state to failed;
|
||||
:set revision to 0;
|
||||
:reboot;
|
||||
stop
|
||||
case ( failed )
|
||||
:set revision to 0;
|
||||
:reboot;
|
||||
stop
|
||||
endswitch
|
||||
}
|
||||
end
|
||||
@enduml
|
||||
|
||||
Image loading
|
||||
==============
|
||||
|
||||
The last part of the boot process just consist of reading kernel image
|
||||
from the selected boot partition and then calling the load_image EFI function
|
||||
to let the EFI firmware start the given image. The firmware will then first
|
||||
check the signature of the kernel before starting it.
|
||||
|
||||
.. uml::
|
||||
|
||||
@startuml
|
||||
!theme cloudscape-design
|
||||
start
|
||||
partition kernel loading {
|
||||
: read unified kernel image from boot partition;
|
||||
: load image to memory;
|
||||
}
|
||||
: call EFI load_image();
|
||||
end
|
||||
@enduml
|
||||
|
|
@ -11,3 +11,6 @@ Belden CoreOS Boot Concepts
|
|||
|
||||
overview
|
||||
uboot
|
||||
efibootguard
|
||||
uki
|
||||
disk
|
||||
|
|
@ -13,8 +13,8 @@ In this document, the following terms have specific meanings:
|
|||
.. glossary::
|
||||
|
||||
Firmware
|
||||
Program that implement the boot and runtime services as defined by the
|
||||
:ext+uefi:ref:`UEFI specifications <maincontent>`.
|
||||
Program that implement some of the boot and runtime services defined by
|
||||
the :ext+uefi:ref:`UEFI specifications <maincontent>`.
|
||||
|
||||
Application
|
||||
Program written according to the UEFI specification that can be started
|
||||
|
|
@ -25,17 +25,26 @@ In this document, the following terms have specific meanings:
|
|||
configuration or autodetection.
|
||||
|
||||
Operating system
|
||||
Application that include at least the Linux Kernel and the initial RAM
|
||||
disk.
|
||||
Application that include at least the Linux Kernel.
|
||||
|
||||
Unified Kernel Image
|
||||
Application that include the Linux kernel and the command line to pass to
|
||||
the kernel and optionaly one or more device trees and a RAM disk
|
||||
|
||||
|
||||
Generic Boot Flow
|
||||
=================
|
||||
|
||||
.. graphviz:: bootflow-generic.dot
|
||||
.. uml:: bootflow-generic.plantuml
|
||||
|
||||
CoreOS use a standardized workflow based on UEFI: the firmware automatically
|
||||
start the bootloader. The bootloader is stored inside the EFI partition, under:
|
||||
`/EFI/BOOT/BOOT<ARCH>.EFI` where `<ARCH>` is:
|
||||
|
||||
- ARM for Arm32 CPU
|
||||
- A64 for Aarch64 CPU
|
||||
- X64 for Amd64 CPU
|
||||
|
||||
CoreOS use a standardized workflow: the firmware can start either an
|
||||
optional bootloader or an operating system as an UEFI application.
|
||||
|
||||
Firmware
|
||||
========
|
||||
|
|
@ -88,6 +97,7 @@ defined by the EBBR Specification. The part of the specification marked as
|
|||
legacy or deprecated must not be used.
|
||||
|
||||
This means:
|
||||
|
||||
- Only GPT partionning disk are supported
|
||||
- No fixed offsets to firmware data
|
||||
|
||||
|
|
@ -105,38 +115,36 @@ The firmware for AMD64 should implement the UEFI specification.
|
|||
Bootloader
|
||||
==========
|
||||
|
||||
CoreOS only support `systemd-boot` as bootloader. The usage of the bootloader
|
||||
is optional. It's primary use case is for system that don't use a firmware
|
||||
provided by CoreOS.
|
||||
CoreOS only support `efibootguard` as bootloader.
|
||||
|
||||
|
||||
Operating system
|
||||
================
|
||||
|
||||
The operating system image is an UEFI application that contain the kernel. We
|
||||
support two method to create this image:
|
||||
The operating system image is an UEFI application that contain the kernel.
|
||||
|
||||
Two ways can be used to generate this application:
|
||||
|
||||
Kernel built with the built-in EFI stub
|
||||
---------------------------------------
|
||||
|
||||
This method use the EFI stub provided by the kernel.
|
||||
|
||||
|
||||
Unified Kernel Images (UKI)
|
||||
---------------------------
|
||||
|
||||
This is the most secure method. The UEFI entry point is provided by
|
||||
`systemd-stub` and the image contains the Linux Kernel, the boot arguments of
|
||||
the kernel, the os-release file and an initrd ram disk.
|
||||
`efibootguard/stub` and the image contains the Linux Kernel with it's built-in
|
||||
EFI stub, the boot arguments of the kernel and optionaly multiple device trees
|
||||
and an initial RAM disk.
|
||||
|
||||
This allows to have all these part authenticated via UEFI secure boot.
|
||||
This allows to have all these part authenticated via UEFI secure boot just by
|
||||
signing the UKI.
|
||||
|
||||
.. warning::
|
||||
UKI are not supported for ARM32 target at the moment, due to a bug in objcopy.
|
||||
See https://sourceware.org/bugzilla/show_bug.cgi?id=26218
|
||||
.. important::
|
||||
|
||||
.. note::
|
||||
UKI has the advantages to be discoverable by the bootloader without any
|
||||
configuration file, and doesn't need a firmware that is able to set the
|
||||
kernel command line.
|
||||
|
||||
Kernel built with the built-in EFI sub
|
||||
--------------------------------------
|
||||
|
||||
This method use the EFI stub provided by the kernel. The initramfs image has to
|
||||
be bundled with the Kernel, using `INITRAMFS_IMAGE_BUNDLE`, as otherwise it
|
||||
will not be authenticated by UEFI secure boot.
|
||||
Only the Unified Kernel Image methods is supported by the CoreOS teams. Using
|
||||
the kernel directly should be used only for new hardware bring-up. By default
|
||||
we only sign UKI to ensure that it's the only method used for hardware that
|
||||
ship with secure boot enabled.
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
digraph G {
|
||||
start [label = "boot";];
|
||||
|
||||
mb [label = "Detect the main board name";shape = rect;];
|
||||
|
||||
mbdts [label = "Load main board device tree";shape = rect;];
|
||||
|
||||
ext [label = "Detect the extension module name";shape = rect;];
|
||||
extdts [label = "Load a device tree overlay for each module";shape = rect;];
|
||||
|
||||
dtsprocess [label = "Add and remove device tree node as needed (DT Fixup)";shape = rect;];
|
||||
|
||||
stop [label = "Start UEFI application";];
|
||||
|
||||
start -> mb -> mbdts -> ext -> extdts -> dtsprocess -> stop;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
************************
|
||||
Using U-Boot as Firmware
|
||||
************************
|
||||
****************
|
||||
Firmware: U-Boot
|
||||
****************
|
||||
|
||||
U-boot can be configured to support the EBBR specification. This can be
|
||||
enabled by enabling both `CONFIG_EFI_LOADER` and
|
||||
|
|
@ -21,13 +21,21 @@ to be changed at runtime.
|
|||
Device tree handling
|
||||
====================
|
||||
|
||||
As per the EBBR specification, the firmware is responsible to provide the
|
||||
As per the EBBR specification, the firmware is responsible to provide a basic
|
||||
device tree to the kernel.
|
||||
|
||||
This means that loading the main device tree and all the device tree overlay are
|
||||
is the responsibility of the firmware.
|
||||
This means that we have to build u-boot with an embedded device tree. On a
|
||||
machine configuration, this mean settings the `UBOOT_BUILDENV_DEVICE_TREE`
|
||||
variables.
|
||||
|
||||
The kernel can then override the built-in device-tree to use another.
|
||||
|
||||
.. important::
|
||||
|
||||
The `compatible` field of the device-tree embedded inside `u-boot` has to
|
||||
match with the one used inside the kernel. This allow us to automatically
|
||||
load the right `device-tree` inside the unified kernel image (UKI).
|
||||
|
||||
.. graphviz:: uboot-dts-handling.dot
|
||||
|
||||
Features to implement per machine
|
||||
=================================
|
||||
|
|
@ -35,73 +43,12 @@ Features to implement per machine
|
|||
The u-boot provided by CoreOS should implement the following features for each
|
||||
supported machine:
|
||||
|
||||
board_fit_config_name_match
|
||||
----------------------------
|
||||
|
||||
This allows u-boot to select the device tree to use dynamically using board
|
||||
detection. See `README.multi-dtb-fit`
|
||||
|
||||
|
||||
extension_board_scan
|
||||
--------------------
|
||||
|
||||
The extension_board_scan function has to be implemented. This function should
|
||||
return the list of add-ons board detected, with the filename of the
|
||||
correspondig device-tree overlay.
|
||||
|
||||
DT Fixup
|
||||
--------
|
||||
|
||||
U-Boot can create, modify and remove node from the device tree dynamically
|
||||
before starting the kernel. This can be used to pass dynamic information stored
|
||||
inside a "board descriptor" eeprom or CPLD to the Kernel.
|
||||
An EFI application like a UKI can overwrite the built-in device tree with a
|
||||
custom one. The DT Fixup Protocol allow an application to ask the firmware to
|
||||
some runtime fix to the new device tree, like enabling or removing node.
|
||||
|
||||
Custom Features that are generic
|
||||
================================
|
||||
|
||||
The u-boot provided by CoreOS should implement the following custom features:
|
||||
|
||||
File authentication
|
||||
-------------------
|
||||
|
||||
In order to be able to authenticate device tree, device-tree overlay file or
|
||||
other file needed by the firmware, we need a command to authenticate a file that
|
||||
was previously loaded is the `load` command.
|
||||
|
||||
.. note::
|
||||
|
||||
My proposal is to use the UEFI Capsule format, to reuse theses function from
|
||||
u-boot:
|
||||
|
||||
- **efi_capsule_authenticate**: Authenticate the UEFI capsule using a x509
|
||||
certificate built into u-boot
|
||||
- **efi_remove_auth_hdr**: Can be used to point a pointer to the start of the
|
||||
content of an authenticated capsule.
|
||||
|
||||
An UEFI Capsule is a generic container that can be signed using a x.509
|
||||
private key. The public key is stored inside u-boot (it's not the same as
|
||||
the keys used for UEFI secure-boot). See
|
||||
https://u-boot.readthedocs.io/en/v2022.10/develop/uefi/uefi.html?highlight=capsule#enabling-capsule-authentication
|
||||
|
||||
|
||||
extension_overlay_cmd
|
||||
---------------------
|
||||
|
||||
A custom command should be made for `extension_overlay_cmd`. The extension
|
||||
subsystem use the command defined as extension_overlay_cmd to load
|
||||
the overlay `${extension_overlay_name}` into `extension_overlay_addr`
|
||||
|
||||
This should reuse the file authentication mechanismus.
|
||||
|
||||
.. note::
|
||||
|
||||
A concept on where and how to securly store device tree and overlay needed
|
||||
by the kernel has to be written.
|
||||
|
||||
My proposal is to use the UEFI Capsule format, to reuse theses function from
|
||||
u-boot:
|
||||
|
||||
- **efi_capsule_authenticate**: Authenticate the UEFI capsule using a x509
|
||||
certificate built into u-boot
|
||||
- **efi_remove_auth_hdr**: Can be used to point a pointer to the start of the
|
||||
content of an authenticated capsule.
|
||||
This can be used to pass dynamic information stored inside a "board descriptor"
|
||||
eeprom or CPLD to the Kernel.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
******************************
|
||||
OS: Unified Kernel Image (UKI)
|
||||
******************************
|
||||
|
||||
|
|
@ -42,8 +42,8 @@ extensions = [
|
|||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.graphviz',
|
||||
'sphinxcontrib.plantuml',
|
||||
]
|
||||
# 'sphinxcontrib.plantuml',
|
||||
|
||||
|
||||
# external links and substitutions
|
||||
|
|
|
|||
|
|
@ -6,10 +6,29 @@ This chapter document the classes that are provided by Belden CoreOS. Classes
|
|||
provided by OpenEmbedded-Core are documented in the
|
||||
:external:doc:`Yocto Reference Manual <ref-manual/classes>`.
|
||||
|
||||
.. _ref-classes-coreos-container-image:
|
||||
.. index:: coreos-container-image.bbclass
|
||||
|
||||
``coreos-container-image.bbclass``
|
||||
==================================
|
||||
|
||||
The ``coreos-container-image`` class provides common definitions to create
|
||||
a container image.
|
||||
:extern:ref:`IMAGE_FEATURE <ref-features-image>`.
|
||||
|
||||
.. _ref-classes-coreos-container-package:
|
||||
.. index:: coreos-container-package.bbclass
|
||||
|
||||
``coreos-container-image.bbclass``
|
||||
==================================
|
||||
|
||||
The ``coreos-container-package`` class provides common definitions to create
|
||||
a package a container image. This allow a container image to be preinstalled
|
||||
into a standard image.
|
||||
|
||||
.. _ref-classes-coreos-efi-secureboot:
|
||||
.. index:: coreos-efi-secureboot.bbclass
|
||||
|
||||
|
||||
``coreos-efi-secureboot.bbclass``
|
||||
=================================
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ The *cockpit* and *dev-tools* feature are special, as they will automatically
|
|||
add package based on the other image feature that are enabled.
|
||||
|
||||
:external:ref:`IMAGE_FEATURES <ref-features-image>` defined in OpenEmbedded-Core
|
||||
are also available, but note that the
|
||||
:ref:`coreos-image <ref-classes-coreos-image>` class don't inherit from the
|
||||
are also available, but note that neither the
|
||||
:ref:`coreos-image <ref-classes-coreos-image>` class and the
|
||||
:ref:`coreos-image <ref-classes-coreos-container-image>` inherit from the
|
||||
:external:ref:`core-image <ref-classes-core-image>` class, thus `core-image`
|
||||
specific features are not available.
|
||||
|
|
|
|||
Loading…
Reference in New Issue