Skip to content

Commit

Permalink
elfloader: use helper struct for DTB loading
Browse files Browse the repository at this point in the history
Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
Axel Heider committed May 4, 2023
1 parent b2e54f0 commit 21bd42a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 49 deletions.
13 changes: 10 additions & 3 deletions elfloader-tool/include/elfloader_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ typedef uintptr_t vaddr_t;
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#define NULL ((void *)0)


/*
* Information about a DTB we are loading.
*/
typedef struct {
paddr_t phys_base;
size_t size;
} dtb_info_t;

/*
* Information about an image we are loading.
*/
Expand Down Expand Up @@ -93,9 +102,7 @@ int load_images(
struct image_info *user_info,
unsigned int max_user_images,
unsigned int *num_images,
void const *bootloader_dtb,
void const **chosen_dtb,
size_t *chosen_dtb_size);
dtb_info_t *dtb_info);

/* Platform functions */
void platform_init(void);
Expand Down
34 changes: 22 additions & 12 deletions elfloader-tool/src/arch-arm/sys_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ char core_stack_alloc[CONFIG_MAX_NUM_NODES][BIT(PAGE_BITS)];

struct image_info kernel_info;
struct image_info user_info;
void const *dtb;
size_t dtb_size;
dtb_info_t dtb_info;

extern void finish_relocation(int offset, void *_dynamic, unsigned int total_offset);
void continue_boot(int was_relocated);
Expand Down Expand Up @@ -101,8 +100,6 @@ void relocate_below_kernel(void)
*/
void main(UNUSED void *arg)
{
void *bootloader_dtb = NULL;

/* initialize platform to a state where we can print to a UART */
initialise_devices();
platform_init();
Expand All @@ -112,13 +109,22 @@ void main(UNUSED void *arg)
print_cpuid();
printf(" paddr=[%p..%p]\n", _text, _end - 1);

/* Assume by default, that no DTB is provided from a previous bootloader
* stage. Since 0 is a valid physical address, the size field is used to
* indicate if the address is valid. The value -1 is to be used used if the
* actual size is not known.
*/
dtb_info.phys_base = 0;
dtb_info.size = 0;

#if defined(CONFIG_IMAGE_UIMAGE)

/* U-Boot passes a DTB. Ancient bootloaders may pass atags. When booting via
* bootelf argc is NULL.
*/
if (arg && (DTB_MAGIC == *(uint32_t *)arg)) {
bootloader_dtb = arg;
dtb_info.phys_base = (paddr_t)arg;
dtb_info.size = (size_t)(-1);
}

#elif defined(CONFIG_IMAGE_EFI)
Expand All @@ -128,20 +134,24 @@ void main(UNUSED void *arg)
abort();
}

bootloader_dtb = efi_get_fdt();
/* For EFI, the DTB address is not supposed to be 0. */
void *efi_dtb = efi_get_fdt();
if (efi_dtb) {
dtb_info.phys_base = (paddr_t)efi_dtb;
dtb_info.size = (size_t)(-1);
}

#endif

if (bootloader_dtb) {
printf(" dtb=%p\n", bootloader_dtb);
if (0 != dtb_info.size) {
printf(" dtb=%p\n", dtb_info.phys_base);
} else {
printf("No DTB passed in from boot loader.\n");
}

/* Unpack ELF images into memory. */
unsigned int num_apps = 0;
int ret = load_images(&kernel_info, &user_info, 1, &num_apps,
bootloader_dtb, &dtb, &dtb_size);
int ret = load_images(&kernel_info, &user_info, 1, &num_apps, &dtb_info);
if (0 != ret) {
printf("ERROR: image loading failed\n");
abort();
Expand Down Expand Up @@ -218,8 +228,8 @@ void continue_boot(int was_relocated)
user_info.phys_region_end,
user_info.phys_virt_offset,
user_info.virt_entry,
(word_t)dtb,
dtb_size);
(word_t)dtb_info.phys_base,
dtb_info.size);

/* We should never get here. */
printf("ERROR: Kernel returned back to the ELF Loader\n");
Expand Down
17 changes: 9 additions & 8 deletions elfloader-tool/src/arch-riscv/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ unsigned long l2pt_elf[PTES_PER_PT] __attribute__((aligned(4096)));
char elfloader_stack_alloc[BIT(CONFIG_KERNEL_STACK_BITS)];

/* first HART will initialise these */
void const *dtb = NULL;
size_t dtb_size = 0;
dtb_info_t dtb_info;

/*
* overwrite the default implementation for abort()
Expand Down Expand Up @@ -194,10 +193,12 @@ static int run_elfloader(UNUSED int hart_id, void *bootloader_dtb)
{
int ret;

dtb_info.phys_base = (paddr_t)bootloader_dtb;
dtb_info.size = (size_t)(-1);

/* Unpack ELF images into memory. */
unsigned int num_apps = 0;
ret = load_images(&kernel_info, &user_info, 1, &num_apps,
bootloader_dtb, &dtb, &dtb_size);
ret = load_images(&kernel_info, &user_info, 1, &num_apps, &dtb_info);
if (0 != ret) {
printf("ERROR: image loading failed, code %d\n", ret);
return -1;
Expand Down Expand Up @@ -243,8 +244,8 @@ static int run_elfloader(UNUSED int hart_id, void *bootloader_dtb)
user_info.phys_region_end,
user_info.phys_virt_offset,
user_info.virt_entry,
(word_t)dtb,
dtb_size
(word_t)dtb_info.phys_base,
dtb_info.size
#if CONFIG_MAX_NUM_NODES > 1
,
hart_id,
Expand Down Expand Up @@ -278,8 +279,8 @@ void secondary_entry(int hart_id, int core_id)
user_info.phys_region_end,
user_info.phys_virt_offset,
user_info.virt_entry,
(word_t)dtb,
dtb_size,
(word_t)dtb_info.phys_base,
dtb_info.size,
hart_id,
core_id
);
Expand Down
53 changes: 27 additions & 26 deletions elfloader-tool/src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,7 @@ int load_images(
struct image_info *user_info,
unsigned int max_user_images,
unsigned int *num_images,
void const *bootloader_dtb,
void const **chosen_dtb,
size_t *chosen_dtb_size)
dtb_info_t *dtb_info)
{
int ret;
uint64_t kernel_phys_start, kernel_phys_end;
Expand Down Expand Up @@ -434,31 +432,32 @@ int load_images(

#ifdef CONFIG_ELFLOADER_INCLUDE_DTB

if (chosen_dtb) {
printf("Looking for DTB in CPIO archive...");
/*
* Note the lack of newline in the above printf(). Normally one would
* have an fflush(stdout) here to ensure that the message shows up on a
* line-buffered stream (which is the POSIX default on terminal
* devices). But we are freestanding (on the "bare metal"), and using
* our own unbuffered printf() implementation.
*/
dtb = cpio_get_file(cpio, cpio_len, "kernel.dtb", NULL);
if (dtb == NULL) {
printf("not found.\n");
} else {
has_dtb_cpio = 1;
printf("found at %p.\n", dtb);
}
printf("Looking for DTB in CPIO archive...");
/*
* Note the lack of newline in the above printf(). Normally one would
* have an fflush(stdout) here to ensure that the message shows up on a
* line-buffered stream (which is the POSIX default on terminal
* devices). But we are freestanding (on the "bare metal"), and using
* our own unbuffered printf() implementation.
*/
dtb = cpio_get_file(cpio, cpio_len, "kernel.dtb", NULL);
if (dtb == NULL) {
printf("not found.\n");
} else {
has_dtb_cpio = 1;
printf("found at %p.\n", dtb);
}

#endif /* CONFIG_ELFLOADER_INCLUDE_DTB */

if (chosen_dtb && !dtb && bootloader_dtb) {
/* Use the bootloader's DTB if we are not using the DTB in the CPIO
* archive.
*/
dtb = bootloader_dtb;
/* If we don't have a DTB here, use the one a bootloader might have
* provided. Since 0 is a valid physical address, the size field is used to
* determin if the address is valid. A size of -1 indicates, that the actual
* size is not known - which is usually the case, because a bootloader often
* just passes an address.
*/
if (!dtb && (dtb_info->size > 0)) {
dtb = (void const *)dtb_info->phys_base;
}

/*
Expand Down Expand Up @@ -489,9 +488,11 @@ int load_images(

printf("Loaded DTB from %p.\n", dtb);
printf(" paddr=[%p..%p]\n", dtb_phys_start, dtb_phys_end - 1);
*chosen_dtb = (void *)dtb_phys_start;
*chosen_dtb_size = dtb_size;
dtb_info->phys_base = dtb_phys_start;
dtb_info->size = dtb_size;
} else {
dtb_info->phys_base = 0;
dtb_info->size = 0;
next_phys_addr = ROUND_UP(kernel_phys_end, PAGE_BITS);
}

Expand Down

0 comments on commit 21bd42a

Please sign in to comment.