On 11 January 2015 at 17:23, Varad Gautam varadgautam@gmail.com wrote:
Request low-memory from UEFI and relocate.
A couple problems with the patch:
- accessing `linux_banner` in `libstub/fdt.c:update_fdt` causes a Data Abort; need a
better place to define it.
This is undoubtedly caused by the fact that the decompressor is built
with -fPIC. This results in external references to go via a Global
Offset Table (GOT) entry, which requires load time relocations as the
GOT contains absolute addresses. You can try to work around this by
adding a forward declaration
extern __attribute__((visibility("hidden"))) char const linux_banner[];
This will tell the compiler that the dependency will be fulfilled at
link time (i.e., not by a shared library) so the emitted symbol
reference will be PC relative.
- arch/arm/boot/compressed/head.S: jump to zImage `mov pc, r3` fails, although jump
to hard-coded relocated address (`ldr pc, =0x80008000`) works, 0x80008000 being the
new zImage location. Need help with calling convention - am I setting *image_addr
correctly?
I am not sure if I understand the purpose of this patch: the
decompressor is position independent, so the best place to load it is
between 32 MB and 128 MB from the base of DRAM. If you load it way at
the beginning, the first thing zImage needs to do when executed is
relocate itself /again/ so it can make room for its uncompressed self
at the base of DRAM.
--
Ard.
> Thanks,
> Varad
>
> arch/arm/boot/compressed/efi-stub.c | 64 ++++++++-----------------------------
> 1 file changed, 14 insertions(+), 50 deletions(-)
>
> diff --git a/arch/arm/boot/compressed/efi-stub.c b/arch/arm/boot/compressed/efi-stub.c
> index 1341229..0364e95 100644
> --- a/arch/arm/boot/compressed/efi-stub.c
> +++ b/arch/arm/boot/compressed/efi-stub.c
> @@ -21,10 +21,8 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
> unsigned long dram_base,
> efi_loaded_image_t *image)
> {
> - unsigned long nr_pages;
> efi_status_t status;
> - /* Use alloc_addr to tranlsate between types */
> - efi_physical_addr_t alloc_addr;
> + unsigned long kernel_size;
>
> /*
> * Verify that the DRAM base address is compatible the the ARM
> @@ -38,55 +36,21 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
> return EFI_LOAD_ERROR;
> }
>
> - /*
> - * Reserve memory for the uncompressed kernel image. This is
> - * all that prevents any future allocations from conflicting
> - * with the kernel. Since we can't tell from the compressed
> - * image how much DRAM the kernel actually uses (due to BSS
> - * size uncertainty) we allocate the maximum possible size.
> - * Do this very early, as prints can cause memory allocations
> - * that may conflict with this.
> - */
> - alloc_addr = dram_base;
> - *reserve_size = MAX_UNCOMP_KERNEL_SIZE;
> - nr_pages = round_up(*reserve_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
> - status = sys_table->boottime->allocate_pages(EFI_ALLOCATE_ADDRESS,
> - EFI_LOADER_DATA,
> - nr_pages, &alloc_addr);
> - if (status != EFI_SUCCESS) {
> - *reserve_size = 0;
> - pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n");
> - return status;
> - }
> - *reserve_addr = alloc_addr;
> -
> - /*
> - * Relocate the zImage, if required. ARM doesn't have a
> - * preferred address, so we set it to 0, as we want to allocate
> - * as low in memory as possible.
> - */
> + /* Relocate the image, if required. */
> *image_size = image->image_size;
> - status = efi_relocate_kernel(sys_table, image_addr, *image_size,
> - *image_size, 0, 0);
> - if (status != EFI_SUCCESS) {
> - pr_efi_err(sys_table, "Failed to relocate kernel.\n");
> - efi_free(sys_table, *reserve_size, *reserve_addr);
> - *reserve_size = 0;
> - return status;
> + if (*image_addr != (dram_base + TEXT_OFFSET)) {
> + kernel_size = *image_size;
> + status = efi_low_alloc(sys_table, kernel_size + TEXT_OFFSET,
> + EFI_PAGE_SIZE, reserve_addr);
> + if (status != EFI_SUCCESS) {
> + pr_efi_err(sys_table, "Failed to relocate kernel\n");
> + return status;
> + }
> + memcpy((void *)(*reserve_addr + TEXT_OFFSET), image->image_base,
> + kernel_size);
> + *image_addr = *reserve_addr + TEXT_OFFSET;
> + *reserve_size = kernel_size + TEXT_OFFSET;
> }
>
> - /*
> - * Check to see if we were able to allocate memory low enough
> - * in memory. The kernel determines the base of DRAM from the
> - * address at which the zImage is loaded.
> - */
> - if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
> - pr_efi_err(sys_table, "Failed to relocate kernel, no low memory available.\n");
> - efi_free(sys_table, *reserve_size, *reserve_addr);
> - *reserve_size = 0;
> - efi_free(sys_table, *image_size, *image_addr);
> - *image_size = 0;
> - return EFI_LOAD_ERROR;
> - }
> return EFI_SUCCESS;
> }
> --
> 2.1.2
>
>
> _______________________________________________
> Linaro-uefi mailing list
> Linaro-uefi@lists.linaro.org
>
http://lists.linaro.org/mailman/listinfo/linaro-uefi