Skip to content

Commit

Permalink
elfloader: Don't overwrite the platform DTB
Browse files Browse the repository at this point in the history
If a DTB has been passed in from an earlier stage boot loader during an
elfloader image relocation, make sure that it doesn't get overwritten.

On Arm this isn't relevant as the protocol when relocation happens
doesn't also pass in a DTB.

Signed-off-by: Kent McLeod <[email protected]>
  • Loading branch information
kent-mcleod committed Feb 22, 2022
1 parent 9dd2537 commit 0d14941
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
1 change: 1 addition & 0 deletions elfloader-tool/src/arch-arm/64/crt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ BEGIN_FUNC(_start)
* Binary images may not be loaded in the correct location.
* Try and move ourselves so we're in the right place.
*/
mov x0, #0 /* Arg 0 of fixup_image_base is NULL */
bl fixup_image_base
mov x2, x0
/* restore original arguments for next step */
Expand Down
1 change: 1 addition & 0 deletions elfloader-tool/src/arch-riscv/crt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ _start:
* Binary images may not be loaded in the correct location.
* Try and move ourselves so we're in the right place.
*/
mv a0, a1 /* Pass dtb as first argument */
jal fixup_image_base
/* fixup_image_base returns 0 if no need to move */
beqz a0, 1f
Expand Down
20 changes: 19 additions & 1 deletion elfloader-tool/src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ extern void invalidate_icache(void);
* to ensure that it doesn't occupy memory that it needs to load the
* kernel and user applications into.
*/
char * fixup_image_base(void) {
char * fixup_image_base(char const *fdt) {
char *load_base = _start;
char *target_base = (char *) IMAGE_START_ADDR;
if (load_base == target_base) {
Expand All @@ -659,6 +659,24 @@ char * fixup_image_base(void) {
abort();
}

/* If a fdt was passed in from the previous boot stage, also
* check that it isn't overwritten.
*/
if (fdt) {
size_t dtb_size = fdt_size(fdt);
const char * fdt_end = fdt + dtb_size;
if (image_size < dtb_size) {
/* Assume the dtb is smaller than the images size to
* simplify region check */
abort();
}
if ((fdt >= target_base && fdt < target_end) ||
(fdt_end >= target_base && fdt_end < target_end)) {
abort();
}
}


/* Perform the move and clean/invalidate caches if necessary */
char *ret = memmove(target_base, load_base, image_size);
#ifdef CONFIG_ARCH_ARM
Expand Down

0 comments on commit 0d14941

Please sign in to comment.