git: 988ee1cc6858 - main - kboot: Method to populate the avail array from EFI map
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 17 Apr 2025 21:59:16 UTC
The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=988ee1cc6858136298008df674c13fa17e943f1b commit 988ee1cc6858136298008df674c13fa17e943f1b Author: Warner Losh <imp@FreeBSD.org> AuthorDate: 2025-04-17 04:04:24 +0000 Commit: Warner Losh <imp@FreeBSD.org> CommitDate: 2025-04-17 21:56:46 +0000 kboot: Method to populate the avail array from EFI map If we can get an efi memory map, populate_avail_from_efi will create an avail array. We only use the regiions marked as 'free' to find a place for the kernel to land. The other regions are also eligible, but usually too small to materially affect where we'd put the kernel (not to worry, the kernel will use that memory). Sponsored by: Netflix Reviewed by: kevans, jhibbits Differential Revision: https://reviews.freebsd.org/D49862 --- stand/kboot/include/efi.h | 1 + stand/kboot/libkboot/efi.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/stand/kboot/include/efi.h b/stand/kboot/include/efi.h index 10368bd4a829..f75a9ea055d3 100644 --- a/stand/kboot/include/efi.h +++ b/stand/kboot/include/efi.h @@ -15,3 +15,4 @@ typedef void (*efi_map_entry_cb)(struct efi_md *, void *argp); void foreach_efi_map_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *argp); void print_efi_map(struct efi_map_header *efihdr); +bool populate_avail_from_efi(struct efi_map_header *efihdr); diff --git a/stand/kboot/libkboot/efi.c b/stand/kboot/libkboot/efi.c index 1f7f28093819..1c1d9a34d297 100644 --- a/stand/kboot/libkboot/efi.c +++ b/stand/kboot/libkboot/efi.c @@ -7,6 +7,7 @@ #include <sys/param.h> #include "stand.h" #include "efi.h" +#include "seg.h" void foreach_efi_map_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *argp) @@ -32,6 +33,7 @@ foreach_efi_map_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void * } } +/* XXX REFACTOR WITH KERNEL */ static void print_efi_map_entry(struct efi_md *p, void *argp __unused) { @@ -95,3 +97,38 @@ print_efi_map(struct efi_map_header *efihdr) foreach_efi_map_entry(efihdr, print_efi_map_entry, NULL); } + +static void +efi_map_entry_add_avail(struct efi_md *p, void *argp) +{ + bool *retval = argp; + + /* + * The kernel itself uses a lot more types as memory it can use. Be + * conservative here so we don't overwrite anything during the reboot + * process which copies the new kernel (so we can't use the Linux kenrel + * space for example). Anything that's not free, we simply don't add to + * the system ram space. We just need to find a big enough place we can + * land the kernel, and most of the other types we might use are + * typically too small anyway, even if we could safely use them. + */ + if (p->md_type != EFI_MD_TYPE_FREE) + return; + + /* + * The memory map is always disjoint, so we never have to remove avail. + */ + add_avail(p->md_phys, p->md_phys + p->md_pages * EFI_PAGE_SIZE - 1, + SYSTEM_RAM); + *retval = true; +} + +bool +populate_avail_from_efi(struct efi_map_header *efihdr) +{ + bool retval = false; + + init_avail(); + foreach_efi_map_entry(efihdr, efi_map_entry_add_avail, &retval); + return retval; +}