tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Adding ESRT and EFI vars support for fwupd
Hello NetBSD 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.
Now it's turn for NetBSD 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.
[4]: https://fwupd.org/
[5]:
https://github.com/fwupd/fwupd/blob/main/plugins/uefi-capsule/fu-uefi-backend-freebsd.c
The same project is being done for OpenBSD as well [6]
[6]: https://www.mail-archive.com/tech%openbsd.org@localhost/msg70825.html
ESRT
----
The initial idea for accessing ESRT from userland is to use sysctl()
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.
The main question is - where should the implementation of ESRT tables go
into?
Should it be generic and span multiple architectures, or should it be
limited to for example only x86?
I found out that EFI is already handled by the x86 architecture, in
`src/sys/arch/x86/x86/efi.c`. So, the implementation would probably go
there or a new file in the same location, if the decision was to reduce
the scope of this feature to a single arch.
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 [7] 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 is something else needed? Usage of existing
implementations can be seen in FreeBSD [8] and Linux [9] (Linux uses
sysfs for this). I also saw an implementation of a pseudo-driver which
allows operations on EFI variables [10], which would suffice as an API,
but unfortunately it wasn't merged yet. Could it be used in our case?
[7]: https://github.com/rhboot/efivar
[8]:
https://github.com/freebsd/freebsd-src/blob/release/12.2.0/lib/libefivar/efivar.c
[9]: https://github.com/rhboot/efivar/blob/main/src/efivarfs.c
[10]:
https://github.com/NetBSD/src/commit/25ff60a647236a2f67fc08ecac96a14fecffd6f1
Expectations
------------
Please help us shape this API, so the community can be happy with it :)
The implementation is a separate topic, but please let me know if you
have any specific ideas about it right away, so as to help avoid any
unnecessary rounds of reviews.
Kind regards,
Pawel
Home |
Main Index |
Thread Index |
Old Index