From 81777d48bb8f9566c94136319cbac16be40042ea Mon Sep 17 00:00:00 2001 From: Samuel Dolt Date: Fri, 10 Mar 2023 11:47:33 +0100 Subject: [PATCH 1/2] docs: update the boot chapter to reflect current boot flow --- documentation/boot/bootflow-generic.dot | 3 +- documentation/boot/bootflow-uboot.dot | 4 +- documentation/boot/overview.rst | 46 +++------------ documentation/boot/uboot-dts-handling.dot | 16 ----- documentation/boot/uboot.rst | 71 ++--------------------- 5 files changed, 18 insertions(+), 122 deletions(-) delete mode 100644 documentation/boot/uboot-dts-handling.dot diff --git a/documentation/boot/bootflow-generic.dot b/documentation/boot/bootflow-generic.dot index ffb9d22..5fc9e4e 100644 --- a/documentation/boot/bootflow-generic.dot +++ b/documentation/boot/bootflow-generic.dot @@ -5,6 +5,5 @@ digraph G { os [label = "Operating System";shape = rect;]; - fw -> btl -> os [style = dashed;]; - fw -> os; + fw -> btl -> os; } \ No newline at end of file diff --git a/documentation/boot/bootflow-uboot.dot b/documentation/boot/bootflow-uboot.dot index 1e802a4..22344a3 100644 --- a/documentation/boot/bootflow-uboot.dot +++ b/documentation/boot/bootflow-uboot.dot @@ -3,7 +3,9 @@ digraph G { uboot [label = "u-boot with EFI/EBBR support";shape = rect;]; + btl [label = "EFIBootGuard";shape = rect;]; + kernel [label = "OS (EFI Stub + Kernel + Initramfs";shape = rect;]; - rom -> uboot -> kernel; + rom -> uboot -> btl -> kernel; } \ No newline at end of file diff --git a/documentation/boot/overview.rst b/documentation/boot/overview.rst index 37720c5..9c22297 100644 --- a/documentation/boot/overview.rst +++ b/documentation/boot/overview.rst @@ -76,7 +76,7 @@ legacy like: - Fixed offsets to firmware data We require the firmware to provide a DeviceTree based system description and not -an ACPI based table (as allowed by the specification) +an ACPI based table (as allowed by the specification). We also require the firmware to implement the UEFI Secure Boot functionality. @@ -84,15 +84,12 @@ ARM64 / AArch64 based machine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The firmware for ARM64 should implement a subset of the UEFI specification, as -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 +defined by the EBBR Specification. We require the firmware to provide a DeviceTree based system description and not -an ACPI based table (as allowed by the specification) +an ACPI based table (as allowed by the specification). The DeviceTree provided +by the firmware can be very minimal as it can be replaced at boot time +by a device-tree contained inside the Operating System Image. We also require the firmware to implement the UEFI Secure Boot functionality. @@ -105,38 +102,13 @@ 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. The usage of the bootloader +is mandated. 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. It's +a Unified Kernel Image generated by tools from the EFIBootGuard project. -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. - -This allows to have all these part authenticated via UEFI secure boot. - -.. 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 - -.. 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. diff --git a/documentation/boot/uboot-dts-handling.dot b/documentation/boot/uboot-dts-handling.dot deleted file mode 100644 index 7718616..0000000 --- a/documentation/boot/uboot-dts-handling.dot +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/documentation/boot/uboot.rst b/documentation/boot/uboot.rst index 2189552..c94147b 100644 --- a/documentation/boot/uboot.rst +++ b/documentation/boot/uboot.rst @@ -21,13 +21,10 @@ to be changed at runtime. Device tree handling ==================== -As per the EBBR specification, the firmware is responsible to provide the -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. - -.. graphviz:: uboot-dts-handling.dot +As per the EBBR specification, the firmware is responsible to provide a +device tree to the kernel. Not that it's OK to export the device tree used by +U-Boot internally as it will be replaced by a propper device tree at a later +stage. This avoid the need to load the device tree from a boot partition. Features to implement per machine ================================= @@ -35,19 +32,11 @@ 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. +return the list of add-ons board detected. DT Fixup -------- @@ -55,53 +44,3 @@ 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. - -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. From ddf9f9ce44a97ac467c97d90eced9b4924cc389f Mon Sep 17 00:00:00 2001 From: Samuel Dolt Date: Fri, 10 Mar 2023 11:48:26 +0100 Subject: [PATCH 2/2] docs: add a components part --- documentation/_static/css/coreos.css | 6 + .../components/core/efibootguard.rst | 104 ++++++++++++++++++ documentation/components/core/index.rst | 15 +++ documentation/components/core/kernel.rst | 27 +++++ documentation/components/core/systemd.rst | 7 ++ documentation/components/core/u-boot.rst | 46 ++++++++ documentation/components/optional/index.rst | 14 +++ .../components/optional/networkmanager.rst | 10 ++ documentation/components/optional/openssh.rst | 9 ++ documentation/components/optional/podman.rst | 9 ++ documentation/conf.py | 4 + documentation/index.rst | 8 ++ 12 files changed, 259 insertions(+) create mode 100644 documentation/_static/css/coreos.css create mode 100644 documentation/components/core/efibootguard.rst create mode 100644 documentation/components/core/index.rst create mode 100644 documentation/components/core/kernel.rst create mode 100644 documentation/components/core/systemd.rst create mode 100644 documentation/components/core/u-boot.rst create mode 100644 documentation/components/optional/index.rst create mode 100644 documentation/components/optional/networkmanager.rst create mode 100644 documentation/components/optional/openssh.rst create mode 100644 documentation/components/optional/podman.rst diff --git a/documentation/_static/css/coreos.css b/documentation/_static/css/coreos.css new file mode 100644 index 0000000..3c3b2f0 --- /dev/null +++ b/documentation/_static/css/coreos.css @@ -0,0 +1,6 @@ + +/* Make tables more convenient by wrapping line instead of using an + horizontal scrollbar */ +.wy-table-responsive table td, .wy-table-responsive table th { + white-space: normal; +} \ No newline at end of file diff --git a/documentation/components/core/efibootguard.rst b/documentation/components/core/efibootguard.rst new file mode 100644 index 0000000..69d7f67 --- /dev/null +++ b/documentation/components/core/efibootguard.rst @@ -0,0 +1,104 @@ +.. index:: EFIBOOTGUARD + +Bootloader: EFIBootGuard +************************ + +CoreOS use `EFIBootGuard `_ as a +bootloader. EFIBootGuard is the components responsible to find and load the +right Unified Kernel Image (UKI). + +Installation +------------ + +EFIBootGuard is an UEFI application. It's installed inside the EFI System +Partition at: + +.. list-table:: + :widths: 25 25 + :header-rows: 1 + + * - Platform Architecture + - Path + * - ARM32 + - /EFI/BOOT/bootarm.efi + * - ARM64 + - /EFI/BOOT/bootaa64.efi + * - x86_64 + - /EFI/BOOT/bootax64.efi + +Workflow +-------- + +Configuration lookup +~~~~~~~~~~~~~~~~~~~~ + +When started, EFIBootGuard will scan all vFAT partition to list all the valid +boot partition. + +A valid boot partition is a vFAT partition that contain a valid BGENV.DAT file. + +This file contains the following parameters: + +- Path to a Kernel file +- Parameter to pass to the kernel +- Flag for in progress update +- Update Status (OK, INSTALLED, TESTING, FAILED) +- Watchdog timeout +- Revision numbers +- User data (not used) + +Consistency of the configuration is guaranteed by a CRC check. + +.. hint:: + CoreOS use a signed Unified Kernel Image that embed the parameters to pass + to the Linux Kernel. Parameters from the UKI always override parameters + set inside the EFIBootGuard configuration file. + + This is a security measure to ensure that only a signed kernel parameters is + used (secure boot). + +Booting +~~~~~~~ + +EFIBootGuard will try to load a kernel using the parameters from the +configuration with the higher revision number. + +Update Handling +~~~~~~~~~~~~~~~ + +Before booting, EFIBootGuard will check the state flags inside the configuration +file. + +If it's OK it means that it's a valid configuration. + +If the state is INSTALLED, it's mean that a new image was flash but was never +booted. EFIBootGuard will change the state to TESTING then boot the kernel. + +If the state is TESTING, it's mean that the kernel was already booted one time, +but the running system has not marked the update as working. EFIBootGuard will +set the status to FAILED and set the revision number to 0 and boot another +configuration. + +.. hint:: + To mark the update as working from a running system, you can use the + following command:: + + bg_setenv --confirm + + This should be done after an update to tell the bootloader that the new + system image is working. CoreOS doesn't do it automatically for now. + +Known Issues +------------ + +.. list-table:: + :widths: 15 85 + :header-rows: 1 + + * - Bugs + - Description + * - `#370558 `_ + - On machine use a Marvel CN913x CPU like the cn9130-cf-pro machine, the version + of U-Boot provided don't provide the UEFI api needed by EFIBootGuard to update + his configuration file at boot time. EFIBootGuard is not able to detect + a failed update. diff --git a/documentation/components/core/index.rst b/documentation/components/core/index.rst new file mode 100644 index 0000000..873c2f1 --- /dev/null +++ b/documentation/components/core/index.rst @@ -0,0 +1,15 @@ + +====================== +CoreOS Core Components +====================== + +| + +.. toctree:: + :caption: Table of Contents + :numbered: + + Firmware: U-Boot + Bootloader: EFIBootGuard + Kernel: Unified Kernel Image + Init System: SystemD diff --git a/documentation/components/core/kernel.rst b/documentation/components/core/kernel.rst new file mode 100644 index 0000000..5265e4f --- /dev/null +++ b/documentation/components/core/kernel.rst @@ -0,0 +1,27 @@ +.. index:: UKI + +Kernel: Unified Kernel Image +***************************** + +CoreOS use by default a `Unified Kernel Image (UKI) `_ +generated by tools from the EFIBootGuard project. + +An UKI is a EFI app that load in memory multiple artifacts needed by the Linux +Kernel before loading and booting the Linux Kernel itself: + +* The kernel commands line is always loaded from the UKI +* A device-tree file: UKI can contain multiple UKI and will load the one + matching the device-tree file passed by the firmware. + +Known Issues and unimplemented feature +-------------------------------------- + +.. note:: + + Bundling an INITRD image into the UKI is not implemented yet. + +.. danger:: + + The Unified Kernel Image is signed but CoreOS currently provide no way to + verify the integrity of the choosed ROOTFS partition as CoreOS doesn't + provide an end-to-end secure boot solution yet. diff --git a/documentation/components/core/systemd.rst b/documentation/components/core/systemd.rst new file mode 100644 index 0000000..13a5487 --- /dev/null +++ b/documentation/components/core/systemd.rst @@ -0,0 +1,7 @@ +.. index:: SYSTEMD + +Init System: SystemD +******************** + +`SystemD `_ is used as +init system in CoreOS. diff --git a/documentation/components/core/u-boot.rst b/documentation/components/core/u-boot.rst new file mode 100644 index 0000000..48c25b7 --- /dev/null +++ b/documentation/components/core/u-boot.rst @@ -0,0 +1,46 @@ +.. index:: UBOOT + +Firmware: U-Boot +**************** + +.. hint:: + CoreOS should work with any UEFI compliant firmware. Using U-Boot is not + mandatory. + +`U-Boot `_ is built by default with +UEFI enabled and secure boot enabled. UEFI secure boot related keys are +installed at build time and can't be changed from the U-Boot command line. + +Workflow +-------- + +U-Boot will boot the default UEFI application from the EFI System Partition. + +The path to the default UEFI application is architecture dependent: + +.. list-table:: + :widths: 25 25 + :header-rows: 1 + + * - Platform Architecture + - Path + * - ARM32 + - /EFI/BOOT/bootarm.efi + * - ARM64 + - /EFI/BOOT/bootaa64.efi + * - x86_64 + - /EFI/BOOT/bootax64.efi + +Known Issues +------------ + +.. danger:: + + The U-Boot configuration used by CoreOS currently was not reviewed for + security issue and is not safe (access to u-boot command line is allowed). + +.. danger:: + + CoreOS U-Boot configuration enable UEFI Secure Boot but the U-Boot binary + itself is not validated. Thus we don't provide a full end-to-end secure boot + solution yet. diff --git a/documentation/components/optional/index.rst b/documentation/components/optional/index.rst new file mode 100644 index 0000000..1bd8a95 --- /dev/null +++ b/documentation/components/optional/index.rst @@ -0,0 +1,14 @@ + +========================== +CoreOS Optional Components +========================== + +| + +.. toctree:: + :caption: Table of Contents + :numbered: + + Network Manager: NetworkManager + SSH Server: OpenSSH + Container: Podman diff --git a/documentation/components/optional/networkmanager.rst b/documentation/components/optional/networkmanager.rst new file mode 100644 index 0000000..8bd0f0b --- /dev/null +++ b/documentation/components/optional/networkmanager.rst @@ -0,0 +1,10 @@ +.. index:: NETWORKMANAGER + +Network Manager: NetworkManager +******************************* + +You can add `NetworkManager `_ to an image that +inherit from `coreos-image` by adding:: + + IMAGE_FEATURES += "networkmanager" + diff --git a/documentation/components/optional/openssh.rst b/documentation/components/optional/openssh.rst new file mode 100644 index 0000000..aa6e3ee --- /dev/null +++ b/documentation/components/optional/openssh.rst @@ -0,0 +1,9 @@ +.. index:: OPENSSH + +SSH Server: OpenSSH +******************* + +You can add an `OpenSSH `_ based ssh server to an +image that inherit from `coreos-image` by adding:: + + IMAGE_FEATURES += "ssh-server" diff --git a/documentation/components/optional/podman.rst b/documentation/components/optional/podman.rst new file mode 100644 index 0000000..a2d854d --- /dev/null +++ b/documentation/components/optional/podman.rst @@ -0,0 +1,9 @@ +.. index:: PODMAN + +Container: Podman +***************** + +You can add `Podman `_ to an image that inherit from +`coreos-image` by adding:: + + IMAGE_FEATURES += "podman" diff --git a/documentation/conf.py b/documentation/conf.py index e6f0ecf..68d062b 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -112,6 +112,10 @@ except ImportError: # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] +html_css_files = [ + 'css/coreos.css', +] + # Hide 'Created using Sphinx' text html_show_sphinx = False diff --git a/documentation/index.rst b/documentation/index.rst index 1be8c50..a90d640 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -26,6 +26,14 @@ same structures. Setting up a CoreOS based distro Building and using a Container Image +.. toctree:: + :maxdepth: 1 + :caption: Software Components + + Core Components + Optional Components + + .. toctree:: :maxdepth: 1 :caption: Manuals