On 2017-07-12 14:38, [ext] Reichel Andreas wrote:
> Update and rework documentation for better user support.
>
> Signed-off-by: Andreas Reichel <[email protected]>
> ---
> 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:
> +[[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..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:
Hmm, does that make sense? The sane use case is rather to modify the
other env, not the current one. What is a valid use case to touch the
current env at all?
> +
> +```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
This implementation aspect is a bit too detailed when someone just want
to understand the usage.
> +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.
> +
Isn't this description kind of replicating the walk-through in the usage
section? Better have things in one place that risking to repeat yourself
or, even worse, have both parts diverge over time (which happened
already, see below).
> +
> +## 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`.
What is the specific meaning of CHAR16 here? For the user, I mean. Isn't
that an implementation detail? I do want to know that by var can't get
longer than 255 chars, though.
> +
> +To overwrite a given configuration, specified by a fixed zero-based config
> +partition number, i.e. `4`, execute:
> +
> +```
> +./bg_setenv -p 4 [...]
4 includes also non-FAT partitions?
> +```
> +
> +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:
"To mark an environment as working after booting into it and testing
essential features" - or so. I first thought I had to issue -c to
confirm an update prior to booting into it.
> +
> +```
> +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
It makes sense to use the long form of the arguments in the docs - makes
things more readable.
> +```
> +
> +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)
if needed - UEFI compliant BIOSes without preexisting configurations
have to fall back to the standard search path. Do you mention this
somewhere? That is
/EFI/BOOT/BOOT<arch>.EFI
> +
> +## 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
Please align columns for text-only reading.
> +
> +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"
bg_setenv --help (current next - am I missing an update?) talks about
--kernel and --args. Moreover, which file will "-f" write out? That
parameter suggests a bit to take a name, but it seems that this name is
hard-coded. In that case, better take a path where the file with the
required name is placed. Also avoids that explicit cd then.
> +# 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
It's probably better to pull the setup of the second environment after
booting into the first one. Having both created initially makes no sense
in practice.
> +```
> +
> +## 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.
I would recommend the second step first - UEFI shell is horrible for
people not familiar with DOS anymore.
> +
> +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"
In fact, that should never be needed for any non-broken BIOS. At most,
you would have to remove any existing settings and let the BIOS fall
back to that. I would not highlight the exceptional case here.
> +```
> +
> +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"
Ah, this is now the new syntax? Or the old one? :)
> +```
> +
> +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
Please align columns properly for non-markdown readers.
> +
> +`efibootguard` works with three internal variables regarding the update
> mechanism:
> +
> +* `revision`
> +* `testing`
> +* `boot_once`
Why do we need these internal vars? Why does the user need to know about
them? Is it planned to move to symbolic states instead (ustate with names)?
> +
> +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
Here some alignment as well.
> +
> +
> +## 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()
> -
>
Jan
--
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux
--
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/52c2befa-d686-e349-15b3-543624ee86b8%40siemens.com.
For more options, visit https://groups.google.com/d/optout.