-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow elfloader to put kernel images directly after firmware on RISCV #135
base: master
Are you sure you want to change the base?
Conversation
I'm not deep enough in the RISCV details to review this one, but I am in favour of the general idea. |
return (char *)0; | ||
} | ||
|
||
/* Check that the current image location doesn't overlap with the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could copy backwards if they overlap, just not sure if that is necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually the memmove implementation in the elfloader can handle this. I originally thought that it was just the same implementation of memcpy. I can fix this up to handle overlap apart from the code segment apart so that it's like the original assembly (which I originally thought was not properly handling overlap).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the issue when there is overlapping, there is chance that the code that is currently executing is not overwritten and thus the result might be undefined? So this must be detected and avoided. Same for overwriting the stack/global in bss
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've fixed this up to only check for collision up until _archive_start.
@@ -89,11 +91,6 @@ static int map_kernel_window(struct image_info *kernel_info) | |||
|
|||
/* Map the elfloader into the new address space */ | |||
|
|||
if (!IS_ALIGNED((uintptr_t)_text, PT_LEVEL_2_BITS)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you explain why the check existed previously and why it can be removed a bit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the kernel also could only handle setting up the kernel mappings if the image was on a page boundary and because the elfloader was always placed on a page boundary by the bbl/opensbi implementation. The rest of map_kernel_window was specialized to these assumptions and so had the checks to catch when there was divergence. Now that divergence can be handled by the code, the checks should be able to be removed.
@@ -49,9 +49,6 @@ function(ApplyData61ElfLoaderSettings kernel_platform kernel_sel4_arch) | |||
if(KernelPlatformZynqmp AND KernelSel4ArchAarch32) | |||
set(IMAGE_START_ADDR 0x8000000 CACHE INTERNAL "" FORCE) | |||
endif() | |||
if(KernelPlatformSpike AND KernelSel4ArchRiscV32) | |||
set(IMAGE_START_ADDR 0x80400000 CACHE INTERNAL "" FORCE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be removed because of the DTS overlay change in another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, it was being ignored by opensbi before and wasn't having any effect.
52f3510
to
9381ff3
Compare
fedf5ca
to
c422134
Compare
These changes also allow the issue underlying #76 to be resolved. |
c422134
to
6bb649a
Compare
This relocation needs to consider the DTB passed through from opensbi when doing relocations otherwise it could get overwritten. This is an outstanding issue on Arm (https://sel4.atlassian.net/browse/SELFOUR-2138) |
6bb649a
to
8ed4a93
Compare
Porting from assembly to a higher level language makes this function more portable. Signed-off-by: Kent McLeod <[email protected]>
It's not necessary to require the kernel and ELFloader images are loaded at the start of page boundaries. Signed-off-by: Kent McLeod <[email protected]>
When booting via opensbi, the image format is a binary image and so if the .bss section is at the end it must be initialized unconditionally. Signed-off-by: Kent McLeod <[email protected]>
This reverts commit 8de8c9f. Signed-off-by: Kent McLeod <[email protected]>
The SBI implementation usually loads the elfloader where the kernel would prefer to also be loaded. Allow the elfloader to move itself to a higher address before loading the kernel and user images. This requires ensuring that the stacks are not overwritten during the merge, and so must be placed before the _archive_cpio section in the linker script. Signed-off-by: Kent McLeod <[email protected]>
8ed4a93
to
0d14941
Compare
This is now handled by the most recent commit. |
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]>
0d14941
to
0675897
Compare
@@ -344,6 +344,8 @@ if(DEFINED KernelDTBPath) | |||
set_property(SOURCE src/drivers/driver.c PROPERTY OBJECT_DEPENDS ${DEVICES_GEN_H}) | |||
endif() | |||
|
|||
set_property(SOURCE src/common.c PROPERTY OBJECT_DEPENDS ${IMAGE_START_ADDR_H}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really necessary? With this PR #include <image_start_addr.h>
is added to common.c
, so it should be part of the normal dependency generation.
|
||
|
||
/* Perform the move and clean/invalidate caches if necessary */ | ||
char *ret = memmove(target_base, load_base, image_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop ret
and use target_base
instead, so it's easier to understand what this does. We could assert ro abort if memmove()
does not return target_base
, because that indicated something is terribly broken.
@@ -26,12 +23,13 @@ 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 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't there a possibility on ARM also that we get passed a DTB here, and thus we have to check that it's not overwritten?
char *fixup_image_base(char const *fdt) | ||
{ | ||
char *load_base = _start; | ||
char *target_base = (char *) IMAGE_START_ADDR; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
char *target_base = (char *) IMAGE_START_ADDR; | |
char *target_base = (char *)IMAGE_START_ADDR; |
@@ -57,7 +59,10 @@ unsigned long l2pt[PTES_PER_PT] __attribute__((aligned(4096))); | |||
unsigned long l2pt_elf[PTES_PER_PT] __attribute__((aligned(4096))); | |||
#endif | |||
|
|||
char elfloader_stack_alloc[BIT(CONFIG_KERNEL_STACK_BITS)]; | |||
/* This stack cannot go in the .bss section because it's already in use when the | |||
* .bss section is zeroed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder, don't we have the same problem on ARM also then? Seem implementing clear_bss
in assembly, so it does not use a stack is the cleanest way to avoid running into issues here.
opensbi puts the elfloader in a fixed location right after it in memory which is where we normally wish to place the kernel with the elfloader higher in memory. This allows the kernel to immediately reclaim the elfloader memory and slightly reduces memory fragmentation by allowing the kernel reserved memory to be located next to the opensbi reserved memory and all memory after free for application use.
Test with: seL4/seL4#759