Skip to content

Commit

Permalink
[sd-stub] add support for embedding devicetree
Browse files Browse the repository at this point in the history
  • Loading branch information
mxre committed Oct 15, 2021
1 parent 0a51337 commit 33bc9b7
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 3 deletions.
25 changes: 25 additions & 0 deletions src/boot/efi/devicetree.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,31 @@ EFI_STATUS devicetree_install(struct devicetree_state *state,
return uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
}

EFI_STATUS devicetree_install_from_memory(struct devicetree_state *state,
const VOID *dtb_buffer, UINTN dtb_length) {

EFI_STATUS err;

assert(state);
assert(dtb_buffer && dtb_length > 0);

err = LibGetSystemConfigurationTable(&EfiDtbTableGuid, &state->orig);
if (EFI_ERROR(err))
return EFI_UNSUPPORTED;

err = devicetree_allocate(state, dtb_length);
if (EFI_ERROR(err))
return err;

CopyMem(PHYSICAL_ADDRESS_TO_POINTER(state->addr), dtb_buffer, dtb_length);

err = devicetree_fixup(state, dtb_length);
if (EFI_ERROR(err))
return err;

return uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
}

void devicetree_cleanup(struct devicetree_state *state) {
EFI_STATUS err;

Expand Down
2 changes: 2 additions & 0 deletions src/boot/efi/devicetree.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ struct devicetree_state {
};

EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE_HANDLE root_dir, CHAR16 *name);
EFI_STATUS devicetree_install_from_memory(
struct devicetree_state *state, const VOID *dtb_buffer, UINTN dtb_length);
void devicetree_cleanup(struct devicetree_state *state);
2 changes: 1 addition & 1 deletion src/boot/efi/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ efi_headers = files('''

common_sources = '''
assert.c
devicetree.c
disk.c
graphics.c
measure.c
Expand All @@ -31,7 +32,6 @@ common_sources = '''
systemd_boot_sources = '''
boot.c
console.c
devicetree.c
drivers.c
random-seed.c
shim.c
Expand Down
19 changes: 17 additions & 2 deletions src/boot/efi/stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <efilib.h>

#include "cpio.h"
#include "devicetree.h"
#include "disk.h"
#include "graphics.h"
#include "linux.h"
Expand Down Expand Up @@ -141,6 +142,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
SECTION_LINUX,
SECTION_INITRD,
SECTION_SPLASH,
SECTION_DTB,
_SECTION_MAX,
};

Expand All @@ -149,12 +151,15 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
[SECTION_LINUX] = (const CHAR8*) ".linux",
[SECTION_INITRD] = (const CHAR8*) ".initrd",
[SECTION_SPLASH] = (const CHAR8*) ".splash",
[SECTION_DTB] = (const CHAR8*) ".dtb",
NULL,
};

UINTN cmdline_len = 0, linux_size, initrd_size, credential_initrd_size = 0, sysext_initrd_size = 0;
UINTN cmdline_len = 0, linux_size, initrd_size, dt_size;
UINTN credential_initrd_size = 0, sysext_initrd_size = 0;
_cleanup_freepool_ VOID *credential_initrd = NULL, *sysext_initrd = NULL;
EFI_PHYSICAL_ADDRESS linux_base, initrd_base;
EFI_PHYSICAL_ADDRESS linux_base, initrd_base, dt_base;
_cleanup_(devicetree_cleanup) struct devicetree_state dt_state = {};
EFI_LOADED_IMAGE *loaded_image;
UINTN addrs[_SECTION_MAX] = {};
UINTN szs[_SECTION_MAX] = {};
Expand Down Expand Up @@ -228,6 +233,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
initrd_size = szs[SECTION_INITRD];
initrd_base = initrd_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_INITRD] : 0;

dt_size = szs[SECTION_DTB];
dt_base = dt_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_DTB] : 0;

if (credential_initrd || sysext_initrd) {
/* If we have generated initrds dynamically, let's combine them with the built-in initrd. */
err = combine_initrd(
Expand All @@ -250,6 +258,13 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
}
}

if (dt_size > 0) {
err = devicetree_install_from_memory(
&dt_state, PHYSICAL_ADDRESS_TO_POINTER(dt_base), dt_size);
if (EFI_ERROR(err))
log_error_stall(L"Error loading embedded devicetree: %r", err);
}

err = linux_exec(image, cmdline, cmdline_len,
PHYSICAL_ADDRESS_TO_POINTER(linux_base), linux_size,
PHYSICAL_ADDRESS_TO_POINTER(initrd_base), initrd_size);
Expand Down

0 comments on commit 33bc9b7

Please sign in to comment.