Hello OpenBSD devs,

Background
----------

As some might know, FreeBSD gained an interface for querying ESRT
about a year ago ([1], [2]), which was done as part of [3].

[1]: https://reviews.freebsd.org/rGd12d651f8692cfcaf6fd0a6e8264c29547f644c9
[2]: https://reviews.freebsd.org/rG24f398e7a153a05a7e94ae8dd623e2b6d28d94eb
[3]: https://nlnet.nl/project/fwdup-BSD/

Adding it allowed to make UEFI capsule plugin of fwupd [4] work for
FreeBSD [5] to perform firmware updates on EFI systems.

[4]: https://fwupd.org/
[5]: 
https://github.com/fwupd/fwupd/blob/main/plugins/uefi-capsule/fu-uefi-backend-freebsd.c

Now it's turn for OpenBSD and we would like to ask about requirements
and recommendations on the API and its implementation such that they
would be accepted by the upstream.

ESRT
----

Initial idea is to use sysctl() interface like so:

```
void *esrt;
size_t esrt_len;
int mib[] = { CTL_HW, HW_ESRT };

esrt_len = 0;
if (sysctl(mib, 2, NULL, &esrt_len, NULL, 0) == -1 && errno != ENOMEM)
    err(1, "sysctl");

esrt = malloc(esrt_len);
if (esrt == NULL)
    err(1, "malloc");

if (sysctl(mib, 2, esrt, &esrt_len, NULL, 0) == -1)
    err(1, "sysctl");
```

However, FreeBSD decided in favour of ioctl() on /dev/efi.

EFI variables
-------------

I don't see an implementation of `efivar` or `efiboot` or anything
similar, so it needs to be added and provide at least this API subset
to be usable with fwupd:

 * efi_append_variable()
   appends data of size to the variable specified by guid and name
 * efi_del_variable()
   deletes the variable specified by guid and name
 * efi_get_variable()
   gets variable's data_size, and its attributes are stored in
   attributes
 * efi_get_variable_attributes()
   gets attributes for the variable specified by guid and name
 * efi_get_variable_size()
   gets the size of the data for the variable specified by guid and name
 * efi_get_next_variable_name()
   iterates across the currently extant variables, passing back a guid
   and name
 * efi_guid_to_name()
   translates from an efi_guid_t to a well known name
 * efi_guid_to_symbol()
   translates from an efi_guid_t to a unique (within libefivar) C-style
   symbol name
 * efi_guid_to_str()
   allocates a suitable string and populates it with string
   representation of a UEFI GUID
 * efi_name_to_guid()
   translates from a well known name to an efi_guid_t
 * efi_set_variable()
   sets the variable specified by guid and name
 * efi_str_to_guid()
   parses a UEFI GUID from string form to an efi_guid_t
 * efi_variables_supported()
   checks if EFI variables are accessible
 * efi_generate_file_device_path()
   generates an EFI file device path for an EFI binary from a filesystem
   path

Probably should be implemented as a minimal port of efivar [6] with
sufficient functionality rather than a separate project. Either way,
this too needs new kernel API for accessing EFI variables. Will sysctl()
do or a new pseudo-device or something else is needed? Usage of
existing implementations can be seen in FreeBSD [7] and Linux [8] (Linux
uses sysfs for this).

[6]: https://github.com/rhboot/efivar
[7]: 
https://github.com/freebsd/freebsd-src/blob/release/12.2.0/lib/libefivar/efivar.c
[8]: https://github.com/rhboot/efivar/blob/main/src/efivarfs.c

Implementation
--------------

I started making an EFI driver for amd64 in [9] (WIP). There isn't much
to see there yet, but let me know if you have any specific ideas about
implementation of ESRT and EFI variables, they can help to avoid too
many rounds of review. For now I'm looking at `efifb.c` and
`arm64/dev/efi.c` for how to do things.

By the way, I couldn't find OpenBSD kernel hacking guide, manual or
README. Is there a resource like that? Something that could answer
questions like:

 * should new EFI-declarations go to `sys/dev/acpi/efi.h`?
 * should efiboot look for ESRT table like it does with 2 other tables?

[9] https://github.com/openbsd/src/compare/master...3mdeb:openbsd-src:esrt

Expectations
------------

Please help shaping this API, so you'll be happy with it :)

Best regards,
Sergii

Reply via email to