HV: Add elf loader sketch

This patch adds a function elf_loader() to load elf image.
It checks the elf header, get its 32/64 bit type, then calls
the corresponding loading routines, which are empty, and
will be realized later.

Tracked-On: #6323

Signed-off-by: Zhou, Wu <wu.zhou@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Zhou, Wu 2021-08-12 15:34:10 +08:00 committed by wenlingz
parent 306baa00bf
commit ba8d4eeb4c
4 changed files with 97 additions and 1 deletions

View File

@ -289,6 +289,9 @@ endif
ifeq ($(CONFIG_GUEST_KERNEL_RAWIMAGE),y) ifeq ($(CONFIG_GUEST_KERNEL_RAWIMAGE),y)
VP_BASE_C_SRCS += boot/guest/rawimage_loader.c VP_BASE_C_SRCS += boot/guest/rawimage_loader.c
endif endif
ifeq ($(CONFIG_GUEST_KERNEL_ELF),y)
VP_BASE_C_SRCS += boot/guest/elf_loader.c
endif
VP_BASE_C_SRCS += common/hv_main.c VP_BASE_C_SRCS += common/hv_main.c
VP_BASE_C_SRCS += common/vm_load.c VP_BASE_C_SRCS += common/vm_load.c
VP_BASE_C_SRCS += arch/x86/configs/pci_dev.c VP_BASE_C_SRCS += arch/x86/configs/pci_dev.c

View File

@ -0,0 +1,86 @@
/*
* Copyright (C) 2021 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm/guest/vm.h>
#include <vboot.h>
#include <elf.h>
#include <logmsg.h>
/**
* @pre vm != NULL
* must run in stac/clac context
*/
static void *do_load_elf64(struct acrn_vm *vm)
{
struct sw_kernel_info *sw_kernel = &(vm->sw.kernel_info);
void *p_elf_img = (void *)sw_kernel->kernel_src_addr;
return p_elf_img;
}
/**
* @pre vm != NULL
* must run in stac/clac context
*/
static void *do_load_elf32(struct acrn_vm *vm)
{
struct sw_kernel_info *sw_kernel = &(vm->sw.kernel_info);
void *p_elf_img = (void *)sw_kernel->kernel_src_addr;
return p_elf_img;
}
/**
* @pre vm != NULL
*/
static int32_t load_elf(struct acrn_vm *vm)
{
void *elf_entry = NULL;
struct sw_kernel_info *sw_kernel = &(vm->sw.kernel_info);
void *p_elf_img = (void *)sw_kernel->kernel_src_addr;
int32_t ret = 0;
stac();
if (*(uint32_t *)p_elf_img == ELFMAGIC) {
if (*(uint8_t *)(p_elf_img + EI_CLASS) == ELFCLASS64) {
elf_entry = do_load_elf64(vm);
} else if (*(uint8_t *)(p_elf_img + EI_CLASS) == ELFCLASS32) {
elf_entry = do_load_elf32(vm);
} else {
pr_err("%s, unsupported elf class(%d)", __func__, *(uint8_t *)(p_elf_img + EI_CLASS));
}
} else {
pr_err("%s, booting elf but no elf header found!", __func__);
}
clac();
sw_kernel->kernel_entry_addr = elf_entry;
if (elf_entry == NULL) {
ret = -EFAULT;
}
return ret;
}
int32_t elf_loader(struct acrn_vm *vm)
{
uint64_t vgdt_gpa = 0x800;
/*
* TODO:
* - We need to initialize the guest BSP(boot strap processor) registers according to
* guest boot mode (real mode vs protect mode)
* - The memory layout usage is unclear, only GDT might be needed as its boot param.
* currently we only support Zephyr which has no needs on cmdline/e820/efimmap/etc.
* hardcode the vGDT GPA to 0x800 where is not used by Zephyr so far;
*/
init_vcpu_protect_mode_regs(vcpu_from_vid(vm, BSP_CPU_ID), vgdt_gpa);
return load_elf(vm);
}

View File

@ -17,6 +17,8 @@ int32_t bzimage_loader(struct acrn_vm *vm);
#ifdef CONFIG_GUEST_KERNEL_RAWIMAGE #ifdef CONFIG_GUEST_KERNEL_RAWIMAGE
int32_t rawimage_loader(struct acrn_vm *vm); int32_t rawimage_loader(struct acrn_vm *vm);
#endif #endif
#ifdef CONFIG_GUEST_KERNEL_ELF
int32_t elf_loader(struct acrn_vm *vm);
#endif
#endif /* end of include guard: VBOOT_H */ #endif /* end of include guard: VBOOT_H */

View File

@ -39,6 +39,11 @@ int32_t prepare_os_image(struct acrn_vm *vm)
case KERNEL_RAWIMAGE: case KERNEL_RAWIMAGE:
ret = rawimage_loader(vm); ret = rawimage_loader(vm);
break; break;
#endif
#ifdef CONFIG_GUEST_KERNEL_ELF
case KERNEL_ELF:
ret = elf_loader(vm);
break;
#endif #endif
default: default:
ret = -EINVAL; ret = -EINVAL;