Update and rework documentation for better user support.
Signed-off-by: Andreas Reichel <
andreas.r...@siemens.com>
---
README.md | 283 ++++---------------------------------------
docs/API.md | 71 +++++++++++
docs/COMPILE.md | 48 ++++++++
docs/TODO.md | 29 +++++
docs/TOOLS.md | 86 +++++++++++++
docs/UPDATE.md | 99 +++++++++++++++
docs/USAGE.md | 165 +++++++++++++++++++++++++
swupdate-adapter/swupdate.md | 92 +++++++++++---
8 files changed, 592 insertions(+), 281 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:
+[
efibootg...@googlegroups.com](
efibootg...@googlegroups.com)
+
+Archive:
+[
https://www.mail-archive.com/efibootg...@googlegroups.com/](https://www.mail-archive.com/efibootg...@googlegroups.com)
+
+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..741cdad
--- /dev/null
+++ b/docs/API.md
@@ -0,0 +1,71 @@
+# 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 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.
+
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..fbf5ee5
--- /dev/null
+++ b/docs/TODO.md
@@ -0,0 +1,29 @@
+# The following items will be implemented #
+
+* 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..a0d35ee
--- /dev/null
+++ b/docs/TOOLS.md
@@ -0,0 +1,86 @@
+# Environment Tools #
+
+Two tools exist for handling `efibootguard`'s environment:
+* `bg_setenv`
+* `bg_printenv`.
+
+The latter is a symbolic link to the first. The program recognizes its function
+from its filename. 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 explained below in the
+`Installation` section.
+
+## Creating an initial set of configurations ##
+
+If no valid environment is present, one can use the `-f` option to create a
+`BGENV.DAT` environment file in the current directory and restore a config
+partition by copying this file to it.
+
+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 -u --kernel="XXXX" --args="YYYY" --watchdog=25 --testing=1
+```
+
+The `-u` 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*: `CHAR16` 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 -p 4 [...]
+```
+
+To also specify a specific revision to set, i.e. `13`, execute:
+
+```
+./bg_setenv -p 4 -r 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 confirm a tested environment, just issue:
+
+```
+bg_setenv -c
+```
+
+To simulate a failed update, with its environment data stored in config partition 1,
+issue:
+
+```
+bg_setenv -p 1 -b -t 1 -r 0
+```
+
+To simulate a reboot of a recently updated configuration stored in config partition 1,
+issue:
+
+```
+bg_setenv -p 1 -b
+```
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..690da67
--- /dev/null
+++ b/docs/USAGE.md
@@ -0,0 +1,165 @@
+# 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 --kernelfile "C:KERNEL1:vmlinuz-linux" --kernelparams="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 --kernelfile "C:KERNEL2:vmlinuz-linux" --kernelparams="root=/dev/sdX5 noinitrd"
+# umount /mnt
+```
+
+## Configuring UEFI boot sequence (Optional) ##
+
+If the system does not select the correct `bootx64.efi` for booting
+automatically, boot into `UEFI shell` and use the `bcfg` command.
+
+*NOTE*: If you do not have a `UEFI shell` you may consult google on how to obtain it.
+Alternatively, you may use the `efibootmgr` user space utility.
+
+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..0d955f1 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,7 +155,7 @@ 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
@@ -103,7 +165,7 @@ 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.
-### Resulting Environment ###
+#### Resulting Environment ####
```
Config Partition #0 Values:
@@ -131,13 +193,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 +227,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
@@ -202,7 +265,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 +285,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.11.0