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