From: Andreas Reichel <[email protected]> From: Andreas Reichel <[email protected]>
Update and rework documentation for better user support. Signed-off-by: Andreas Reichel <[email protected]> --- README.md | 283 ++++--------------------------------------- docs/API.md | 74 +++++++++++ docs/COMPILE.md | 48 ++++++++ docs/TODO.md | 37 ++++++ docs/TOOLS.md | 82 +++++++++++++ docs/UPDATE.md | 99 +++++++++++++++ docs/USAGE.md | 171 ++++++++++++++++++++++++++ swupdate-adapter/swupdate.md | 101 +++++++++++---- 8 files changed, 611 insertions(+), 284 deletions(-) create mode 100644 docs/API.md create mode 100644 docs/COMPILE.md create mode 100644 docs/TODO.md create mode 100644 docs/TOOLS.md create mode 100644 docs/UPDATE.md create mode 100644 docs/USAGE.md diff --git a/README.md b/README.md index 95292e8..d29151f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,17 @@ Provides the following functionality: * Arm a hardware watchdog prior to loading an OS * Provides a simple update mechanism with fail-save algorithm +## Development ## + +Mailing list: +[[email protected]]([email protected]) + +Archive: +[https://www.mail-archive.com/[email protected]/](https://www.mail-archive.com/[email protected]) + +For sending patches, please refer to the mailing list and `CONTRIBUTING.md` in +the source tree. + ## Watchdog support ## The following watchdog drivers are implemented: @@ -13,273 +24,23 @@ The following watchdog drivers are implemented: * Intel TCO * Intel i6300esb +Currently, it is not possible to disable the watchdog initialization. If no +working watchdog is found, the boot process fails. + ## Configuration ## `efibootguard` reads its configuration from an environment storage. Currently, the following environment backends are implemented: * Dual FAT Partition storage -## Update Mechanism ## - -Each environment configuration has a revision. The number of possible -environments must be configured at compile-time. The larger the revision value, -the newer the environment is. `efibootguard` always loads the latest environment -data, meaning the one with the greatest revision value. - -The structure of the environment data is as follows: - -``` -struct _BG_ENVDATA { - uint16_t kernelfile[ENV_STRING_LENGTH]; - uint16_t kernelparams[ENV_STRING_LENGTH]; - uint8_t testing; - uint8_t boot_once; - uint16_t watchdog_timeout_sec; - uint32_t revision; - uint32_t crc32; -}; -``` - -The fields have the following meaning: -* `kernelfile`: Path to the kernel image, utf-16 encoding -* `kernelparams`: Arguments to the kernel, utf-16 encoding -* `testing`: A flag that specifies if the configuration is in test mode -* `boot_once`: Set by `efibootguard` if it first boots a test configuration -* `watchdog_timeout_sec`: Number of seconds, the watchdog times out after -* `revision`: The revision number explained above -* `crc32`: A crc32 checksum - - -Assume, the system has been booted with a configuration that has a `revision` of -`4`. The user can set a new configuration with a revision of `5`, with `testing` -flag set. On the next reboot, `efibootguard` loads the configuration with the -highest `revision` number. If it detects, that `testing` is set, it will enable -the `boot_once` flag and boot the system with this configuration. - -### Example scenario 1 - Successful update ### - -Once booted, the user disables both `testing` and `boot_once` to confirm the -udpate. - -### Example scenario 2 - System crash during first boot after update ### - -If the system crashes during boot, the watchdog will reset the system. -Afterwards, `efibootguard` sees, that this configuration had already been tested -before, because `boot_once` is already set. Thus, it will deactivate both -`boot_once` and `testing` and load the 2nd latest configuration instead. It will -signal to the user, that the update failed by setting the revision of the failed -configuration to `0`. - -### Visual explanation of the update process ### - - +--------------++--------------+ - | || | - | Rev: latest || Rev: oldest | - | (working) || | - | || | - +--------------++--------------+ - | | - +---+ | update - | | - v v - +---------------+ +--------------+ - | | | | - +----> | Rev: latest-1 | | Rev: latest | - | | (working) | | testing: 1 | - | | | | boot_once: 0 | - | +---------------+ +--------------+ - | | - | | reboot - | v - | +--------------+ - | | | - | | Rev: latest | - | | testing: 1 | - | | boot_once: 1 | - | +--------------+ - | | no - | success? ------------------+ - | watchdog reboot | watchdog reboot | - | yes, confirm | | - | v v - | +--------------+ +-------------------+ - | | | | | - | | Rev: latest | | Rev: 0 | - | | testing: 0 | | testing: 1 | - | | boot_once: 0 | | boot_once: 1 | - | +--------------+ +-------------------+ - | boots | - +----- latest' = latest-1 +--------------------------------+ - - -## Environment Tools ## - -In the `tools` directory, there is a utility named `bg_setenv`/`bg_printenv`. -With this, the user can display the configuration data or update as needed. - -**NOTE**: The environment tools only work, if the correct number of config -partitions is detected. This also means that the stored configuration data has a -valid checksum. If this is not the case, environments must be repaired first. To -do so, follow the initial setup step explained below in the `Installation` -section. - -To access configuration data on FAT partitions, the partition must either -already be mounted, with access rights for the user using the tool, or the tool -can mount the partition by itself, provided that it has the `CAP_SYS_ADMIN` -capability. This is the case if the user is granted `root` privileges or the -corresponding capability is set in the filesystem. - -*NOTE*: `CHAR16` environment variables are limited to 255 characters as stated -in `include/envdata.h`. - -### Creating a new configuration ### - -In most cases, the user wants to create a new environment configuration, which -can be done by - -``` -./bg_setenv -u --kernel="XXXX" --args="YYYY" --watchdog=25 --testing=1 -``` - -The `-u` parameter tells `bg_setenv` to automatically overwrite the oldest -configuration set and sets the revision value to the newest. - -If the user wants to specify the revision number and the configuration partition -to overwrite manually, he can do so by - -``` -./bg_setenv -p 4 -r 13 [...] -``` - -which specifies to set the data set in partition number 4 to revision 13. Please -keep in mind, that counting of configuration partitions starts with 0. - -Some debug output can be activated if compiling with -``` -make DEBUG=1 -``` - -#### Kernel Location #### - -To load the kernel from a different FAT partition than `efibootguard`, there are -two possible mechanisms. One directly uses the label of the FAT partition, -created with `dosfslabel`: - -``` -./bg_setenv -u --kernel="L:FATLABEL:kernelfile" -``` - -where `FATLABEL` is the label of the FAT partition. On some older UEFI -implementations, the label is not supported properly and a user defined label -can be created instead, which is a file named `EFILABEL` in the root directory -of the corresponding FAT partition. This file contains an UTF-16le encoded -partition name and can be used as follows: - -``` -./bg_setenv -u --kernel="C:USERLABEL:kernelfile" -``` - -### Interface API ### - -The library `libebgenv.a` provides an API to access the environment from a user -program. - -The header file with the prototypes and a short description is `ebgenv.h`. - -Documentation and further examples can be found in -`swupdate-adapter/swupdate.md`. - -The following example program opens the current environment and modifies the -kernel file name: - -```c -#include <stdbool.h> -#include "ebgenv.h" - -int main(void) -{ - ebg_env_open_current(); - ebg_env_set("kernelfile", "vmlinux-new"); - ebg_env_close(); - return 0; -} -``` - -The following example program creates a new environment with the latest revision -and sets it to the testing state: - -```c -#include <stdbool.h> -#include "ebgenv.h" - -int main(void) -{ - ebg_env_create_new(); - ebg_env_set("kernelfile", "vmlinux-new"); - ebg_env_set("kernelparams", "root=/dev/bootdevice"); - ebg_env_set("watchdog_timeout_sec", "30"); - ebg_env_close(); - return 0; -} -``` - -*Note*: If no watchdog timeout value is specified, a default of 30 seconds is -set. - -## Required libraries and headers for compilation ## - -### Arch Linux ### - -``` -pacman -S gnu-efi-libs pciutils -``` - -### Debian 8 ### - -``` -apt-get install gnu-efi libparted-dev libpci-dev -``` - -## Installation ## - -### Environment setup ### - -Create the needed number of FAT16 partitions as defined by -`CONFIG_PARTITION_COUNT` in `include/envdata.h`. Create a new `BGENV.DAT` -configuration file with the `bg_setenv` tool and the `-f` option and copy the -files to the FAT16 partitions. - -*NOTE*: Currently, FAT partitions must neither be `FAT12`, `FAT32` nor `FAT32e`. -During detection of config partitions, all non-FAT16 partitions are ignored and -do not count to the valid number of config partitions. - -### Bootloader installation ### - -Copy `efibootguard.efi` to `EFI/boot/` and rename it to bootx64.efi. - -If the system does not select this file for booting automatically, boot into -`UEFI shell` and use the `bcfg` command. - -Issue the following command to list the currently configured boot sequence: -``` -bcfg boot dump -``` - -The following command deletes item number `n`: -``` -bcfg boot rm `n` -``` - -The following command create an entry for `bootx64.efi`: -``` -bcfg boot add 0 fs0:\efi\boot\bootx64.efi "efi boot guard" -``` -where the binary is on drive `fs0:`. +See `Installation And Usage` for further information. -Exit efi shell with the `reset` command. +## Further Documentation ## -## Future work ## +* [Update Mechanism](docs/UPDATE.md) +* [Environment Tools](docs/TOOLS.md) +* [API Library](docs/API.md) +* [Compilation Instructions](docs/COMPILE.md) +* [Installation And Usage](docs/USAGE.md) +* [Future Work](docs/TODO.md) -* The number of valid config partitions expected by the bootloader and the tools - is currently fixed to the number defined by `CONFIG_PARTITION_COUNT` in - `include/envdata.h`. This value should be made configurable by a config flag. diff --git a/docs/API.md b/docs/API.md new file mode 100644 index 0000000..8778b70 --- /dev/null +++ b/docs/API.md @@ -0,0 +1,74 @@ +# API Library # + +## General information ## + +The library `libebgenv.a` provides an API to access the environment from a +user space program. + +The header file with the interface definitions is +[/swupdate-adapter/ebgenv.h](../swupdate-adapter/ebgenv.h). + +The interface provides functions to: +* enable/disable for output to stdout and stderr +* create a new environment +* edit the latest environment +* reset the error state +* check the last update state + +An example and detailed information on how to interpret the returned state values +is given in the [swupdate-adapter documentation](../swupdate-adapter/swupdate.md). + +To link a program to the library, you can install `efibootguard` with + +``` +make install +``` + +This will install `libebgenv.a` into your system for your linker to find it (usually +to `/usr/lib/libebgenv.a`). + +If you want to cross-compile this library, you have to cross-compile the +`efibootguard tools` since both tools and this API library both depend on a +common static library. Refer to [compilation instructions](COMPILE.md). + +## Example programs ## + +The following example program creates a new environment with the latest revision +and sets it to the testing state: + +```c +#include <stdbool.h> +#include "ebgenv.h" + +int main(void) +{ + ebg_env_create_new(); + ebg_env_set("kernelfile", "vmlinux-new"); + ebg_env_set("kernelparams", "root=/dev/bootdevice"); + ebg_env_set("watchdog_timeout_sec", "30"); + ebg_env_close(); + return 0; +} +``` + +*Note*: If no watchdog timeout value is specified, a default of 30 seconds is +set. + +### Advanced Usage ### + +In some cases, for example in tests, access to the current environment is +needed. The following example program opens the current environment and +modifies the kernel file name: + +```c +#include <stdbool.h> +#include "ebgenv.h" + +int main(void) +{ + ebg_env_open_current(); + ebg_env_set("kernelfile", "vmlinux-new"); + ebg_env_close(); + return 0; +} +``` diff --git a/docs/COMPILE.md b/docs/COMPILE.md new file mode 100644 index 0000000..51c2008 --- /dev/null +++ b/docs/COMPILE.md @@ -0,0 +1,48 @@ +# Compilation Instructions # + +## Required libraries and headers for compilation ## + +### Arch Linux ### + +``` +pacman -S gnu-efi-libs pciutils +``` + +### Debian 8 ### + +``` +apt-get install gnu-efi libpci-dev +``` + +## Compilation ## + +This project uses autotools. Here you find useful documentations for +[autoconf](https://www.gnu.org/software/autoconf/manual/autoconf.html), and +[automake](https://www.gnu.org/software/automake/manual/automake.html). + +To compile `efibootguard`, checkout the sources and run: + +``` +autoreconf -fi +./configure +make +``` + +To cross-compile, the environment variables must be set accordingly, i.e. +`CXX=<compiler-to-use>`. The following example shows how to specify needed +paths for an out-of-tree build, where cross-compilation environment variables +have already been set before (i.e. by an embedded SDK from `yocto` or alike): + +``` +mkdir build +cd build +autoreconf -fi .. +../configure --host=i586 --build=x86_64-unknown-linux-gnu \ + --with-gnuefi-sys-dir=<sys-root-dir> \ + --with-gnuefi-include-dir=<sys-root-dir>/usr/include/efi \ + --with-gnuefi-lds-dir=<sys-root-dir>/usr/lib \ + --with-gnuefi-lib-dir=<sys-root-dir>/usr/lib +make +``` + +where `<sys-root-dir>` points to the wanted sysroot for cross-compilation. diff --git a/docs/TODO.md b/docs/TODO.md new file mode 100644 index 0000000..40d5ba8 --- /dev/null +++ b/docs/TODO.md @@ -0,0 +1,37 @@ +# The following items will be implemented # + + +* Tools modification + * Make `bg_setenv -c` and the underlying confirm mechanism to backup + the current working environment to the (latest-1) environment, so + that if the current environment breaks, there is a backup with the + latest values. + * Make `bg_setenv -f` take a path to where the `BGENV.DAT` is stored. + +* Application specific variables + * applications may need to store their own variables into the + bootloader environment. Currently this is not possible. A generic + method must be defined and implemented to account for generic + key-value pairs. + +* State refactoring + * Currently, there are three variables 'revision', 'testing', + 'boot_once', where the latter two are mapped onto a variable called + 'ustate'. The 'ustate' variable in turn equals an enum type variable + within swupdate, so that for the swupdate adapter, a complex mapping + must be implemented. To resolve this issue, the two variables + 'boot_once' and 'testing' will be unified to the 'ustate' variable, + which will have the same enum type as used in 'swupdate'. + +* API refactoring + * Currently, there are two APIs, a lower API 'bg_utils.c', and an + adapter-API 'ebgenv.c'. After refactoring the state variable, the API + will be simplified as well. It is possible, that only one API is + needed then. + * Function / Datatype / Variable names remind of Parted and should be + renamed if code developes independent of libparted. + * The number of valid config partitions expected by the bootloader and + the tools is currently fixed to the number defined by + `CONFIG_PARTITION_COUNT` in `include/envdata.h`. This value should be + made configurable by a config flag. + diff --git a/docs/TOOLS.md b/docs/TOOLS.md new file mode 100644 index 0000000..c79e5a8 --- /dev/null +++ b/docs/TOOLS.md @@ -0,0 +1,82 @@ +# Environment Tools # + +Two tools exist for handling `efibootguard`'s environment: +* `bg_setenv` +* `bg_printenv`. + +With these, the user can change environment content or display it. + +**NOTE**: The environment tools only work, if the correct number and type of +config partitions is detected. This also means that the stored configuration +data must have a valid checksum. If this is not the case, environments must be +repaired first. To do so, follow the `Initial Setup` step section below. + +## Initial Setup ## + +Generation of a valid configuration partition is described in +[docs/USAGE.md](USAGE.md). + +*NOTE*: To access configuration data on FAT partitions, the partition must +either already be mounted, with access rights for the user using the tool, or +the tool can mount the partition by itself. The latter is only possible if the +tool has the `CAP_SYS_ADMIN` capability. This is the case if the user is `root` +or the corresponding capability is set in the filesystem. + +## Updating a configuration ## + +In most cases, the user wants to update to a new environment configuration, +which can be done with: + +``` +./bg_setenv --update --kernel="XXXX" --args="YYYY" --watchdog=25 --testing=1 +``` + +The `--update` parameter tells `bg_setenv` to automatically overwrite the +configuration with the lowest revision and sets its revision value to the +highest. Hence, the oldest revision becomes the latest. + +*NOTE*: Environment variables are limited to 255 characters as stated in +`include/envdata.h`. + +To overwrite a given configuration, specified by a fixed zero-based `config +partition` number, i.e. `4`, execute: + +``` +./bg_setenv --part=4 [...] +``` + +To also specify a specific revision to set, i.e. `13`, execute: + +``` +./bg_setenv --part=4 --revision=13 [...] +``` + +This specifies the revision number of the configuration in config partition +number 4 to be set to 13. + +Please note that the config partition index is zero-based as displayed with: + +``` +bg_printenv +``` + +To mark the current environment as working after having successfully booted +with it and having tested essential features, use the `--confirm` option: + +``` +bg_setenv --confirm +``` + +To simulate a failed update, with its environment data stored in config partition 1, +issue: + +``` +bg_setenv --partition=1 --bootonce --testing=1 --revision=0 +``` + +To simulate a reboot of a recently updated configuration stored in config partition 1, +issue: + +``` +bg_setenv --partition=1 --boot_once +``` diff --git a/docs/UPDATE.md b/docs/UPDATE.md new file mode 100644 index 0000000..169fb9d --- /dev/null +++ b/docs/UPDATE.md @@ -0,0 +1,99 @@ +# Update Mechanism # + +`efibootguard` works with a predefined number of configuration environments. +The number is defined at compile-time. Each environment has a revision. +`efibootguard` always loads the latest environment data, which is indicated by +the highest revision value. + +The structure of the environment data is as follows: + +```c +struct _BG_ENVDATA { + uint16_t kernelfile[ENV_STRING_LENGTH]; + uint16_t kernelparams[ENV_STRING_LENGTH]; + uint8_t testing; + uint8_t boot_once; + uint16_t watchdog_timeout_sec; + uint32_t revision; + uint32_t crc32; +}; +``` + +The fields have the following meaning: +* `kernelfile`: Path to the kernel image, utf-16 encoded +* `kernelparams`: Arguments to the kernel, utf-16 encoded +* `testing`: A flag that specifies if the configuration is in test mode +* `boot_once`: Set by `efibootguard` if it first boots a test configuration +* `watchdog_timeout_sec`: Number of seconds, the watchdog times out after +* `revision`: The revision number explained above +* `crc32`: A crc32 checksum + +The following example cases demonstrate the meaning of the update-specific +struct members. + +## Example cases ## + +Assume the following for the next examples: The system has been booted with a +configuration that has a `revision` of `4`. The user can set a new +configuration with a `revision` of `5`, with `testing` flag set. On the next +reboot, `efibootguard` loads the configuration with the highest `revision` +number. If it detects, that `testing` is set, it will enable the `boot_once` +flag and boot the system with this configuration. + +### Example scenario 1 - Successful update ### + +Once booted, the user disables both `testing` and `boot_once` to confirm the +update using the [tools](TOOLS.md). + +### Example scenario 2 - System crash during first boot after update ### + +If the system freezes during boot, the watchdog will reset the system. On the +next boot `efibootguard` detects that this configuration had already been +tested before, because `boot_once` is already set. Thus, it will load the 2nd +latest configuration instead. The failed update is indicated by the revision +of the failed configuration set to `0` with both `boot_once` and `testing` +enabled. A revision of 0 is the lowest possible number and avoids that the +corresponding configuration is booted again in future. + +## Visual explanation of the update process ## + +``` + +--------------++--------------+ + | || | + | Rev: latest || Rev: oldest | + +--------> | (working) || | + | | || | + | +--------------++--------------+ + | | + | | update + | v + | +---------------++--------------+ + | | || | + | | Rev: latest-1 || Rev: latest | + | | (working) || testing: 1 | + | | || boot_once: 0 | + | +---------------++--------------+ + | | + | | reboot + | v + | +---------------++--------------+ + | | || | + | | Rev: latest-1 || Rev: latest | + | | (working) || testing: 1 | + | | || boot_once: 1 | + | +---------------++--------------+ + | | no + | success? ---------------------+ + | | watchdog reboot | + | yes, confirm | | + | v v + | +----------++--------------+ +----------++--------------+ + | | || | | || | + | | Rev: || Rev: latest | | Rev: || Rev: 0 | + | | latest-1 || testing: 0 | | latest-1 || testing: 1 | + | | || boot_once: 0 | | || boot_once: 1 | + | +----------++--------------+ +----------++--------------+ + | boots | + +----- latest' = latest-1 +---------------------------+ + +``` diff --git a/docs/USAGE.md b/docs/USAGE.md new file mode 100644 index 0000000..7dd89ce --- /dev/null +++ b/docs/USAGE.md @@ -0,0 +1,171 @@ +# Installation AND Usage # + +In order to use `efibootguard` one needs to +* have a valid disk partitioning scheme +* have the bootloader binary installed in the proper place +* have valid configuration files +* configure the UEFI boot sequence (may be optional) + +## Creating a valid partitioning scheme ## + +UEFI by default supports FAT file systems, which are used to store +configuration data for `efibootguard`. The following partition type GUIDS are +supported for GPT partition entries: + +GUID | description +-------------------------------------|---------------------------------- +EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 | Microsoft default data partition +C12A7328-F81F-11D2-BA4B-00A0C93EC93B | EFI System partition + +For robustness of the fail-safe mechanism, each configuration file revision is +stored into a separate FAT partition. The following example shows how to create a +new GPT using `parted`: + +**IMPORTANT**: Replace `/dev/sdX` with the correct block device. + +* Start `parted` for block device `/dev/sdX` and create an EFI system partition + +``` +# parted /dev/sdX +(parted) mklabel GPT +(parted) mkpart +Partition name? []? +File system type? [ext2]? fat32 +Start? 0% +End? 20% +(parted) toggle 1 +Flag to Invert? ESP +``` + +* Create two config partitions + +``` +(parted) mkpart +Partition name? []? +File system type? [ext2]? fat16 +Start? 20% +End? 40% +(parted) mkpart +Partition name? []? +File system type? [ext2]? fat16 +Start? 40% +End? 60% +``` + +* Create two root partitions and leave `parted` + +``` +(parted) mkpart +Partition name? []? +File system type? [ext2]? ext4 +Start? 60% +End? 80% +(parted) mkpart +Partition name? []? +File system type? [ext2]? ext4 +Start? 80% +End? 100% +(parted) q +``` + +* Create all file systems + +``` +# mkfs.fat /dev/sdX1 +# mkfs.fat -F 16 /dev/sdX2 +# mkfs.fat -F 16 /dev/sdX3 +# mkfs.ext4 /dev/sdX4 +# mkfs.ext4 /dev/sdX5 +``` + +*NOTE*: `FAT16`, as specified by `-F 16` is usefull for smaller partitions +(i.e. 500 MB). `FAT12` and `FAT32` is also supported. + +## Install the boot loader binary file ## + +This example is for an `x64` architecture. + +``` +# mount /dev/sdX1 /mnt +# mkdir -p /mnt/EFI/boot +# cp efibootguardx64.efi /mnt/EFI/boot/bootx64.efi +# umount /mnt +``` + +## Create a default configuration ## + +This step first creates a custom label contained in `EFILABEL`, which is later +used to specify the kernel location. + +``` +# mount /dev/sdX2 /mnt && cd /mnt +# echo -n "KERNEL1" | iconv -f ascii -t UTF-16LE > EFILABEL +# bg_setenv -f -r 1 --kernel="C:KERNEL1:vmlinuz-linux" --args="root=/dev/sdX4 noinitrd" +# umount /mnt +# mount /dev/sdX3 /mnt && cd /mnt +# echo -n "KERNEL2" | iconv -f ascii -t UTF-16LE > EFILABEL +# bg_setenv -f -r 2 --kernel="C:KERNEL2:vmlinuz-linux" --args="root=/dev/sdX5 noinitrd" +# umount /mnt +``` + +## Configuring UEFI boot sequence (Optional) ## + +UEFI compliant firmwares fall back to a standard search path for the boot loader binary. This is + +``` +/EFI/BOOT/BOOT<arch>.EFI +``` + +In some cases, if the system does not select the correct `bootx64.efi` for +booting automatically, use the `efibootmgr` user space tool to setup the boot +sequence configuration. + +Another possibility is to boot into `UEFI shell` and use the `bcfg` command. + +Issue the following command to list the currently configured boot sequence: + +``` +bcfg boot dump +``` + +The following command deletes item number `n`: + +``` +bcfg boot rm `n` +``` + +The following command create an entry for `bootx64.efi`: + +``` +bcfg boot add 0 fs0:\efi\boot\bootx64.efi "efi boot guard" +``` + +where the binary is on drive `fs0:`. + +Exit `UEFI shell` with the `reset` command. + +## Kernel Location ## + +If you just specify a file name as `--kernelfile`, `efibootguard` loads the +kernel from the same FAT partition as the boot loader binary itself. + +To load the kernel from a different FAT partition than `efibootguard`, there are +two possible mechanisms. One directly uses the label of the FAT partition, +created with `dosfslabel`: + +``` +./bg_setenv -u --kernel="L:FATLABEL:kernelfile" +``` + +where `FATLABEL` is the label of the FAT partition. On some older UEFI +implementations, the label is not supported properly and a user defined label +can be created instead, which is a file named `EFILABEL` in the root directory +of the corresponding FAT partition. This file contains an UTF-16le encoded +partition name and can be used as follows: + +``` +./bg_setenv -u --kernel="C:USERLABEL:kernelfile" +``` + +*NOTE*: Do not mix-up the file system label and the GPT entry label. + diff --git a/swupdate-adapter/swupdate.md b/swupdate-adapter/swupdate.md index 334aa5f..7df0c43 100644 --- a/swupdate-adapter/swupdate.md +++ b/swupdate-adapter/swupdate.md @@ -1,5 +1,68 @@ # Update process with swupdate # + +## Update state mapping ## + +Swupdate-Suricatta works with an internal state variable, which is called `ustate` +per default. + +The values of common interest are: + +ustate | meaning +--------|----------------------------------- +0 | nothing to do +1 | update installed (reboot pending) +2 | update testing (after reboot) +3 | update failed +4 | state not available + +`efibootguard` works with three internal variables regarding the update mechanism: + +* `revision` +* `testing` +* `boot_once` + +The values of these variables are mapped onto ustate according to the following matrix: + +*Note*: A failed revision exists, if its `revision` is `0` and at the same time, +both `boot_once` and `testing` are set to `1`. If such a revision exists in any of +the stored environment partitions, this is marked as [FAILED] in the matrix below. + +`efibootguard` | `suricatta` +---------------------------------------------------------------------------|------------ + (current env.)<br />testing = 0<br />boot_once = 0<br /><br />NOT [FAILED]| ustate = 0 + (current env.)<br />testing = 1<br />boot_once = 0<br /><br />NOT [FAILED]| ustate = 1 + (current env.)<br />testing = 1<br />boot_once = 1<br /><br />NOT [FAILED]| ustate = 2 + [FAILED] | ustate = 3 + Environment<br />Error | ustate = 4 + + +## Update state mapping with API functions ## + +1. Call `ebg_env_open_current`, which will initialize the configuration environment. + +2. Use the following logic + +``` +ebg_env_isupdatesuccessful() is false? + ustate = 3 +else + ebg_env_isokay() is true? + ustate = 0 + + ebg_env_isinstalled() is true? + ustate = 1 + + ebg_env_istesting() is true? + ustate = 2 + +``` + +3. call `ebg_env_close()` + + +## Detailed example ## + Test environment: 2 config partitions, FAT16, GPT **Initial suricatta state: OK** @@ -25,7 +88,7 @@ test flag: disabled boot once flag: not set ``` -## Installation of Update ## +### Installation of Update ### Used sw-description: @@ -61,11 +124,10 @@ Command with block dev access to update efibootguard environment: ``` swupdate -v -i test.swu - ``` -### Resulting environment ### +#### Resulting environment #### ``` Config Partition #0 Values: @@ -93,17 +155,19 @@ Test conditions: Function to retrieve state: `ebg_env_isinstalled()` -## Rebooting ## +### Rebooting ### -efibootguard will detect the `testing` flag and set `boot_once`. This can be simulated by +efibootguard will detect the `testing` flag and set `boot_once`. This can be +simulated by ``` bg_setenv -p X -b ``` -where `X` is the 0-based index of the config partition to be updated. This sets the `boot_once` flag. +where `X` is the 0-based index of the config partition to be updated. This sets +the `boot_once` flag. -### Resulting Environment ### +#### Resulting Environment #### ``` Config Partition #0 Values: @@ -131,13 +195,13 @@ Test conditions: Function to retrieve state: `ebg_env_istesting()` -## Confirming working update ## +### Confirming working update ### ``` bg_setenv -c ``` -### Resulting environment ### +#### Resulting environment #### ``` Config Partition #0 Values: @@ -165,11 +229,12 @@ Test conditions: Function to retrieve state: `ebg_env_isokay()` -## Not confirming and rebooting ## +### Not confirming and rebooting ### After rebooting with state == INSTALLED and not confirming, the resulting environment is: +#### Resulting environment #### ``` Config Partition #0 Values: revision: 15 @@ -191,7 +256,8 @@ boot once flag: set **suricatta state: FAILED** Test conditions: -* ebg_env_isupdatesuccessful == FALSE (since a revision is 0 and both flags set in this config) +* ebg_env_isupdatesuccessful == FALSE (since a revision is 0 and both flags set + in this config) ### Manually resetting failure state ### @@ -202,7 +268,7 @@ bg_setenv -u -t 0 replaces the oldest environment with these and then updates the newly set values (-t 0).* -### Resulting environment ### +#### Resulting environment #### ``` Config Partition #0 Values: @@ -222,14 +288,3 @@ test flag: disabled boot once flag: not set ``` -# State mapping # - -Condition A is ebg_env_isupdatesuccessful == true - -Suricatta state | condition | function -------------------------------------------------------------------------------------- -FAILED | !A | !ebg_env_isupdatesuccessful() -OK | A && testing == 0 | ebg_env_isokay() -INSTALLED | A && testing == 1 && boot_once == 0 | ebg_env_isinstalled() -TESTING | A && testing == 1 && boot_once == 1 | ebg_env_istesting() - -- 2.13.3 -- You received this message because you are subscribed to the Google Groups "EFI Boot Guard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/efibootguard-dev/20170721131739.21423-5-andreas.reichel.ext%40siemens.com. For more options, visit https://groups.google.com/d/optout.
