mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-25 23:13:26 +00:00
misc: efi-stub: Barebone efi-stub for secure boot
ACRN EFI application based on the legacy efi-stub code provides booting method of HV on UEFI-BIOS without using the GRUB Bootloader. It is supposed to be used for secure booting on certain platform. By means of that users can boot HV, Service VM kernel, pre-launched VM kernel and its ACPI table binary packed in the Slim Bootloader container boot image file format. ACRN EFI application has additional dependencies to compile which are not listed in the existing ACRN GSG doc. Since this is an optional feature but not all users need, it does not get compiled by default to avoid causing any confusion for existing users. README for how to use the feature will come later in a separated commit. This patch adds barebone implementation of this efi-stub. The following files are reused from a previous version of efi-stub without changes: efilinux.h, pe.c, stdlib.h Other files contains stubbed functions, whose implementation will come in coming patches. Tracked-On: #6241 Signed-off-by: Toshiki Nishioka <toshiki.nishioka@intel.com> Signed-off-by: Yifan Liu <yifan1.liu@intel.com> Co-developed-by: Yifan Liu <yifan1.liu@intel.com>
This commit is contained in:
parent
fd7f0e2c45
commit
52790b5c0e
94
misc/efi-stub/Makefile
Normal file
94
misc/efi-stub/Makefile
Normal file
@ -0,0 +1,94 @@
|
||||
#
|
||||
# Copyright (c) 2011 - 2021, Intel Corporation
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
HV_OBJDIR:=build
|
||||
HV_SRC:=../../hypervisor
|
||||
C_SRCS = boot.c pe.c malloc.c
|
||||
ACRN_OBJS := $(patsubst %.c,$(EFI_OBJDIR)/%.o,$(C_SRCS))
|
||||
INCLUDE_PATH += $(INCDIR)/efi
|
||||
INCLUDE_PATH += $(HV_SRC)/include/public
|
||||
INCLUDE_PATH += $(HV_SRC)/include/lib
|
||||
|
||||
BOARD ?= tgl-rvp
|
||||
SCENARIO ?= hybrid_rt
|
||||
|
||||
OBJCOPY=objcopy
|
||||
|
||||
ARCH := x86_64
|
||||
FORMAT := efi-app-x86-64
|
||||
|
||||
# Different Linux distributions have the 'gnu-efi' package install
|
||||
# its tools and libraries in different folders. The next couple of
|
||||
# variables will determine and set the right path for both the
|
||||
# tools $(GNUEFI_DIR) and libraries $(LIBDIR)
|
||||
GNUEFI_DIR := $(shell find $(SYSROOT)/usr/lib* -name elf_$(ARCH)_efi.lds -type f | xargs dirname)
|
||||
LIBDIR := $(subst gnuefi,,$(GNUEFI_DIR))
|
||||
CRT0 := $(GNUEFI_DIR)/crt0-efi-$(ARCH).o
|
||||
LDSCRIPT := $(GNUEFI_DIR)/elf_$(ARCH)_efi.lds
|
||||
|
||||
INCDIR := $(SYSROOT)/usr/include
|
||||
|
||||
CFLAGS=-I. -I.. -I$(INCDIR)/efi -I$(INCDIR)/efi/$(ARCH) \
|
||||
-DEFI_FUNCTION_WRAPPER -fPIC -fshort-wchar -ffreestanding \
|
||||
-Wall -I../fs/ -D$(ARCH) -O2 \
|
||||
|
||||
CFLAGS += -mno-mmx -mno-sse -mno-sse2 -mno-80387 -mno-fp-ret-in-387
|
||||
|
||||
CFLAGS += -fno-delete-null-pointer-checks -fwrapv -mno-red-zone
|
||||
|
||||
LDFLAGS=-T $(LDSCRIPT) -Bsymbolic -shared -nostdlib -znocombreloc \
|
||||
-L$(LIBDIR) $(CRT0)
|
||||
BOOT=$(EFI_OBJDIR)/boot.efi
|
||||
|
||||
all: $(BOOT)
|
||||
|
||||
$(BOOT): $(EFI_OBJDIR)/boot.so
|
||||
|
||||
$(EFI_OBJDIR)/boot.so: $(ACRN_OBJS)
|
||||
$(LD) $(LDFLAGS) -o $@ $^ -lgnuefi -lefi $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
clean:
|
||||
rm -f $(BOOT) $(EFI_OBJDIR)/boot.so $(ACRN_OBJS)
|
||||
|
||||
-include $(ACRN_OBJS:.o=.d)
|
||||
|
||||
$(EFI_OBJDIR)/%.o:%.S
|
||||
[ ! -e $@ ] && mkdir -p $(dir $@); \
|
||||
$(CC) $(CFLAGS) -c -o $@ $< -MMD -MT $@
|
||||
|
||||
$(EFI_OBJDIR)/%.o: %.c
|
||||
[ ! -e $@ ] && mkdir -p $(dir $@); \
|
||||
$(CC) $(patsubst %, -I%, $(INCLUDE_PATH)) -I. -c $(CFLAGS) $(ARCH_CFLAGS) $< -o $@ -MMD -MT $@
|
||||
|
||||
%.efi: %.so
|
||||
$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
|
||||
-j .rela -j .reloc --target=$(FORMAT) $*.so $@
|
272
misc/efi-stub/boot.c
Normal file
272
misc/efi-stub/boot.c
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2021, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include "efilinux.h"
|
||||
#include "stdlib.h"
|
||||
#include "boot.h"
|
||||
#include "container.h"
|
||||
|
||||
EFI_SYSTEM_TABLE *sys_table;
|
||||
EFI_BOOT_SERVICES *boot;
|
||||
EFI_RUNTIME_SERVICES *runtime;
|
||||
HV_LOADER hvld;
|
||||
|
||||
EFI_STATUS
|
||||
get_efi_memmap(struct efi_memmap_info *mi, int size_only)
|
||||
{
|
||||
UINTN map_size, map_key;
|
||||
UINT32 desc_version;
|
||||
UINTN desc_size;
|
||||
EFI_MEMORY_DESCRIPTOR *map_buf;
|
||||
EFI_STATUS err = EFI_SUCCESS;
|
||||
|
||||
/* We're just interested in the map's size for now */
|
||||
map_size = 0;
|
||||
err = get_memory_map(&map_size, NULL, NULL, &desc_size, NULL);
|
||||
if (err != EFI_SUCCESS && err != EFI_BUFFER_TOO_SMALL)
|
||||
goto out;
|
||||
|
||||
if (size_only) {
|
||||
mi->map_size = map_size;
|
||||
mi->desc_size = desc_size;
|
||||
return err;
|
||||
}
|
||||
|
||||
again:
|
||||
err = allocate_pool(EfiLoaderData, map_size, (void **) &map_buf);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Remember! We've already allocated map_buf with emalloc (and
|
||||
* 'map_size' contains its size) which means that it should be
|
||||
* positioned below our allocation for the kernel. Use that
|
||||
* space for the memory map.
|
||||
*/
|
||||
err = get_memory_map(&map_size, map_buf, &map_key,
|
||||
&desc_size, &desc_version);
|
||||
if (err != EFI_SUCCESS) {
|
||||
if (err == EFI_BUFFER_TOO_SMALL) {
|
||||
/*
|
||||
* Argh! The buffer that we allocated further
|
||||
* up wasn't large enough which means we need
|
||||
* to allocate them again, but this time
|
||||
* larger. 'map_size' has been updated by the
|
||||
* call to memory_map().
|
||||
*/
|
||||
free_pool(map_buf);
|
||||
goto again;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
mi->map_size = map_size;
|
||||
mi->map_key = map_key;
|
||||
mi->desc_version = desc_version;
|
||||
mi->desc_size = desc_size;
|
||||
mi->mmap = map_buf;
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static EFI_STATUS
|
||||
terminate_boot_services(EFI_HANDLE image, struct efi_memmap_info *mmap_info)
|
||||
{
|
||||
EFI_STATUS err = EFI_SUCCESS;
|
||||
|
||||
err = exit_boot_services(image, mmap_info->map_key);
|
||||
if (err != EFI_SUCCESS) {
|
||||
if (err == EFI_INVALID_PARAMETER) {
|
||||
/*
|
||||
* Incorrect map key: memory map changed during the call of get_memory_map
|
||||
* and exit_boot_services.
|
||||
* We must call get_memory_map and exit_boot_services one more time.
|
||||
* We can't allocate nor free pool since exit_boot_services has already been called.
|
||||
* Original memory pool should be sufficient and this call is expected to succeed.
|
||||
*/
|
||||
err = get_memory_map(&mmap_info->map_size, mmap_info->mmap,
|
||||
&mmap_info->map_key, &mmap_info->desc_size, &mmap_info->desc_version);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
err = exit_boot_services(image, mmap_info->map_key);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline void hv_jump(EFI_PHYSICAL_ADDRESS hv_entry, uint32_t mbi, int32_t magic)
|
||||
{
|
||||
asm volatile (
|
||||
"cli\n\t"
|
||||
"jmp *%2\n\t"
|
||||
:
|
||||
: "a"(magic), "b"(mbi), "r"(hv_entry)
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS construct_mbi(HV_LOADER hvld, struct multiboot_info **mbinfo, struct efi_memmap_info *mmap_info)
|
||||
{
|
||||
EFI_STATUS err = EFI_SUCCESS;
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
construct_mbi2(struct hv_loader *hvld, void **mbi_addr, struct efi_memmap_info *mmap_info)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static EFI_STATUS
|
||||
run_acrn(EFI_HANDLE image, HV_LOADER hvld)
|
||||
{
|
||||
EFI_STATUS err;
|
||||
struct efi_memmap_info memmapinfo;
|
||||
void *mbi;
|
||||
int32_t mb_version = hvld->get_multiboot_version(hvld);
|
||||
|
||||
if (mb_version == 2) {
|
||||
err = construct_mbi2(hvld, &mbi, &memmapinfo);
|
||||
}
|
||||
else {
|
||||
err = construct_mbi(hvld, (struct multiboot_info **)&mbi, &memmapinfo);
|
||||
}
|
||||
|
||||
if (err != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
err = terminate_boot_services(image, &memmapinfo);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
hv_jump(hvld->get_hv_entry(hvld), (uint32_t)(uint64_t)mbi,
|
||||
mb_version == 2 ? MULTIBOOT2_INFO_MAGIC : MULTIBOOT_INFO_MAGIC);
|
||||
|
||||
/* Not reached on success */
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_main - The entry point for the OS loader image.
|
||||
* @image: firmware-allocated handle that identifies the image
|
||||
* @sys_table: EFI system table
|
||||
*/
|
||||
EFI_STATUS
|
||||
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table)
|
||||
{
|
||||
WCHAR *error_buf;
|
||||
EFI_STATUS err;
|
||||
EFI_LOADED_IMAGE *info;
|
||||
EFI_STATUS (*hvld_init)(EFI_LOADED_IMAGE *, HV_LOADER *);
|
||||
|
||||
INTN index;
|
||||
|
||||
InitializeLib(image, _table);
|
||||
sys_table = _table;
|
||||
boot = sys_table->BootServices;
|
||||
runtime = sys_table->RuntimeServices;
|
||||
|
||||
if (CheckCrc(sys_table->Hdr.HeaderSize, &sys_table->Hdr) != TRUE)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
err = handle_protocol(image, &LoadedImageProtocol, (void **)&info);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto failed;
|
||||
|
||||
/* We may support other containers in the future */
|
||||
hvld_init = container_init;
|
||||
|
||||
/*
|
||||
* Load hypervisor boot image handler. Currently Slim Bootloader
|
||||
* compatible embedded container format is supported. File system
|
||||
* mode to come future.
|
||||
*/
|
||||
err = hvld_init(info, &hvld);
|
||||
if (err != EFI_SUCCESS) {
|
||||
Print(L"Unable to init container library %r ", err);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
err = hvld->load_boot_image(hvld);
|
||||
if (err != EFI_SUCCESS) {
|
||||
Print(L"Unable to load ACRNHV Image %r ", err);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
err = hvld->load_modules(hvld);
|
||||
if (err != EFI_SUCCESS) {
|
||||
Print(L"Unable to load VM modules %r ", err);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
err = run_acrn(image, hvld);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto failed;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
failed:
|
||||
if (hvld) {
|
||||
hvld->deinit(hvld);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to be careful not to trash 'err' here. If we fail
|
||||
* to allocate enough memory to hold the error string fallback
|
||||
* to returning 'err'.
|
||||
*/
|
||||
if (allocate_pool(EfiLoaderData, ERROR_STRING_LENGTH,
|
||||
(void **)&error_buf) != EFI_SUCCESS) {
|
||||
Print(L"Couldn't allocate pages for error string\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
StatusToString(error_buf, err);
|
||||
Print(L": %s\n", error_buf);
|
||||
|
||||
/* If we don't wait for user input, (s)he will not see the error message */
|
||||
uefi_call_wrapper(sys_table->ConOut->OutputString, 2, sys_table->ConOut, \
|
||||
L"\r\n\r\n\r\nHit any key to exit\r\n");
|
||||
uefi_call_wrapper(sys_table->BootServices->WaitForEvent, 3, 1, \
|
||||
&sys_table->ConIn->WaitForKey, &index);
|
||||
|
||||
return exit(image, err, ERROR_STRING_LENGTH, error_buf);
|
||||
}
|
220
misc/efi-stub/boot.h
Normal file
220
misc/efi-stub/boot.h
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2021, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ACRNBOOT_H__
|
||||
#define __ACRNBOOT_H__
|
||||
|
||||
#include "multiboot.h"
|
||||
|
||||
#define E820_RAM 1
|
||||
#define E820_RESERVED 2
|
||||
#define E820_ACPI 3
|
||||
#define E820_NVS 4
|
||||
#define E820_UNUSABLE 5
|
||||
|
||||
#define ERROR_STRING_LENGTH 32
|
||||
#define EFI_LOADER_SIGNATURE "EL64"
|
||||
|
||||
#define ACPI_XSDT_ENTRY_SIZE (sizeof(UINT64))
|
||||
#define ACPI_NAME_SIZE 4
|
||||
#define ACPI_OEM_ID_SIZE 6
|
||||
#define ACPI_OEM_TABLE_ID_SIZE 8
|
||||
|
||||
#define MSR_IA32_PAT 0x00000277 /* PAT */
|
||||
#define MSR_IA32_EFER 0xC0000080
|
||||
#define MSR_IA32_FS_BASE 0xC0000100U
|
||||
#define MSR_IA32_GS_BASE 0xC0000101
|
||||
#define MSR_IA32_SYSENTER_ESP 0x00000175 /* ESP for sysenter */
|
||||
#define MSR_IA32_SYSENTER_EIP 0x00000176 /* EIP for sysenter */
|
||||
|
||||
#define UEFI_BOOT_LOADER_NAME "ACRN UEFI loader"
|
||||
|
||||
#define ALIGN_UP(addr, align) \
|
||||
(((addr) + (typeof (addr)) (align) - 1) & ~((typeof (addr)) (align) - 1))
|
||||
|
||||
/* Read MSR */
|
||||
#define CPU_MSR_READ(reg, msr_val_ptr) \
|
||||
{ \
|
||||
uint32_t msrl, msrh; \
|
||||
asm volatile ("rdmsr" : "=a"(msrl), \
|
||||
"=d"(msrh) : "c" (reg)); \
|
||||
*msr_val_ptr = ((uint64_t)msrh << 32U) | msrl; \
|
||||
}
|
||||
|
||||
EFI_STATUS get_pe_section(CHAR8 *base, char *section_name, UINTN section_name_len, UINTN *vaddr, UINTN *size);
|
||||
typedef void(*hv_func)(int32_t, struct multiboot_info*);
|
||||
|
||||
/*
|
||||
* We allocate memory for the following struct together with hyperivosr itself
|
||||
* memory allocation during boot.
|
||||
*/
|
||||
#define MBOOT_MMAP_NUMS 256
|
||||
#define MBOOT_MMAP_SIZE (sizeof(struct multiboot_mmap) * MBOOT_MMAP_NUMS)
|
||||
#define MBOOT_INFO_SIZE (sizeof(struct multiboot_info))
|
||||
#define MBOOT_MODS_NUMS 4
|
||||
#define MBOOT_MODS_SIZE (sizeof(struct multiboot_module) * MBOOT_MODS_NUMS)
|
||||
#define BOOT_LOADER_NAME_SIZE 17U
|
||||
#define EFI_BOOT_MEM_SIZE \
|
||||
(MBOOT_MMAP_SIZE + MBOOT_INFO_SIZE + MBOOT_MODS_SIZE + BOOT_LOADER_NAME_SIZE)
|
||||
#define MBOOT_MMAP_PTR(addr) \
|
||||
((struct multiboot_mmap *)((VOID *)(addr)))
|
||||
#define MBOOT_INFO_PTR(addr) \
|
||||
((struct multiboot_info *)((VOID *)(addr) + MBOOT_MMAP_SIZE))
|
||||
#define MBOOT_MODS_PTR(addr) \
|
||||
((struct multiboot_module *)((VOID *)(addr) + MBOOT_MMAP_SIZE + MBOOT_INFO_SIZE))
|
||||
#define BOOT_LOADER_NAME_PTR(addr) \
|
||||
((char *)((VOID *)(addr) + MBOOT_MMAP_SIZE + MBOOT_INFO_SIZE + MBOOT_MODS_SIZE))
|
||||
|
||||
struct efi_memmap_info {
|
||||
UINTN map_size;
|
||||
UINTN map_key;
|
||||
UINT32 desc_version;
|
||||
UINTN desc_size;
|
||||
EFI_MEMORY_DESCRIPTOR *mmap;
|
||||
};
|
||||
|
||||
typedef struct mb_module_info {
|
||||
UINTN mod_start;
|
||||
UINTN mod_end;
|
||||
const char *cmd;
|
||||
UINTN cmdsize;
|
||||
} MB_MODULE_INFO;
|
||||
|
||||
struct efi_info {
|
||||
UINT32 efi_loader_signature;
|
||||
UINT32 efi_systab;
|
||||
UINT32 efi_memdesc_size;
|
||||
UINT32 efi_memdesc_version;
|
||||
UINT32 efi_memmap;
|
||||
UINT32 efi_memmap_size;
|
||||
UINT32 efi_systab_hi;
|
||||
UINT32 efi_memmap_hi;
|
||||
};
|
||||
|
||||
struct e820_entry {
|
||||
UINT64 addr; /* start of memory segment */
|
||||
UINT64 size; /* size of memory segment */
|
||||
UINT32 type; /* type of memory segment */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct acpi_table_rsdp {
|
||||
/* ACPI signature, contains "RSD PTR " */
|
||||
char signature[8];
|
||||
/* ACPI 1.0 checksum */
|
||||
UINT8 checksum;
|
||||
/* OEM identification */
|
||||
char oem_id[ACPI_OEM_ID_SIZE];
|
||||
/* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */
|
||||
UINT8 revision;
|
||||
/* 32-bit physical address of the RSDT */
|
||||
UINT32 rsdt_physical_address;
|
||||
/* Table length in bytes, including header (ACPI 2.0+) */
|
||||
UINT32 length;
|
||||
/* 64-bit physical address of the XSDT (ACPI 2.0+) */
|
||||
UINT64 xsdt_physical_address;
|
||||
/* Checksum of entire table (ACPI 2.0+) */
|
||||
UINT8 extended_checksum;
|
||||
/* Reserved, must be zero */
|
||||
UINT8 reserved[3];
|
||||
};
|
||||
|
||||
struct acpi_table_header {
|
||||
/* ASCII table signature */
|
||||
char signature[ACPI_NAME_SIZE];
|
||||
/* Length of table in bytes, including this header */
|
||||
UINT32 length;
|
||||
/* ACPI Specification minor version number */
|
||||
UINT8 revision;
|
||||
/* To make sum of entire table == 0 */
|
||||
UINT8 checksum;
|
||||
/* ASCII OEM identification */
|
||||
char oem_id[ACPI_OEM_ID_SIZE];
|
||||
/* ASCII OEM table identification */
|
||||
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE];
|
||||
/* OEM revision number */
|
||||
UINT32 oem_revision;
|
||||
/* ASCII ASL compiler vendor ID */
|
||||
char asl_compiler_id[ACPI_NAME_SIZE];
|
||||
/* ASL compiler version */
|
||||
UINT32 asl_compiler_revision;
|
||||
};
|
||||
|
||||
/* hypervisor loader operation table */
|
||||
typedef struct hv_loader *HV_LOADER;
|
||||
struct hv_loader {
|
||||
/* Load ACRN hypervisor image into memory */
|
||||
EFI_STATUS (*load_boot_image)(IN HV_LOADER hvld);
|
||||
/* Load VM Kernels and ACPI Tables into memory */
|
||||
EFI_STATUS (*load_modules)(IN HV_LOADER hvld);
|
||||
|
||||
const char *(*get_boot_cmd)(IN HV_LOADER hvld);
|
||||
/* Get hypervisor boot command length */
|
||||
UINTN (*get_boot_cmdsize)(IN HV_LOADER hvld);
|
||||
|
||||
MB_MODULE_INFO *(*get_mods_info)(IN HV_LOADER hvld, UINTN index);
|
||||
/* Get the number of multiboot2 modules */
|
||||
UINTN (*get_mod_count)(IN HV_LOADER hvld);
|
||||
/* Get the total memory size allocated to load module files */
|
||||
UINTN (*get_total_modsize)(IN HV_LOADER hvld);
|
||||
/* Get the total lengths of the module commands */
|
||||
UINTN (*get_total_modcmdsize)(IN HV_LOADER hvld);
|
||||
|
||||
/* Get the total memory size of hv image */
|
||||
UINTN (*get_hv_ram_size)(IN HV_LOADER hvld);
|
||||
|
||||
/* Get the start address of the memory region stored ACRN hypervisor image */
|
||||
EFI_PHYSICAL_ADDRESS (*get_hv_hpa)(IN HV_LOADER hvld);
|
||||
/* Get the start address of the memory region stored module files */
|
||||
EFI_PHYSICAL_ADDRESS (*get_mod_hpa)(IN HV_LOADER hvld);
|
||||
/* Get the entry point of ACRN hypervisor */
|
||||
EFI_PHYSICAL_ADDRESS (*get_hv_entry)(IN HV_LOADER hvld);
|
||||
|
||||
/* Get the supported multiboot version of ACRN hypervisor image */
|
||||
int (*get_multiboot_version)(IN HV_LOADER hvld);
|
||||
|
||||
/* free up memory allocated by hypervisor loader */
|
||||
void (*deinit)(IN HV_LOADER hvld);
|
||||
};
|
||||
|
||||
EFI_STATUS get_efi_memmap(struct efi_memmap_info *mmap_info, int size_only);
|
||||
|
||||
static inline uint64_t
|
||||
msr_read(uint32_t reg_num)
|
||||
{
|
||||
uint64_t msr_val;
|
||||
|
||||
CPU_MSR_READ(reg_num, &msr_val);
|
||||
return msr_val;
|
||||
}
|
||||
|
||||
#endif
|
44
misc/efi-stub/container.h
Normal file
44
misc/efi-stub/container.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __ACRNCONTAINER_H__
|
||||
#define __ACRNCONTAINER_H__
|
||||
|
||||
/**
|
||||
* container_init - Initialize Container Library and returned the loader operation table.
|
||||
* @info: Firmware-allocated handle that identifies the EFI application image (i.e. acrn.efi)
|
||||
* @hvld: Loader operation table
|
||||
*/
|
||||
EFI_STATUS container_init(EFI_LOADED_IMAGE *info, HV_LOADER *hvld);
|
||||
|
||||
#endif /* __ACRNCONTAINER_H__ */
|
287
misc/efi-stub/efilinux.h
Normal file
287
misc/efi-stub/efilinux.h
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2021, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file contains some wrappers around the gnu-efi functions. As
|
||||
* we're not going through uefi_call_wrapper() directly, this allows
|
||||
* us to get some type-safety for function call arguments and for the
|
||||
* compiler to check that the number of function call arguments is
|
||||
* correct.
|
||||
*
|
||||
* It's also a good place to document the EFI interface.
|
||||
*/
|
||||
|
||||
#ifndef __EFILINUX_H__
|
||||
#define __EFILINUX_H__
|
||||
|
||||
#define EFILINUX_VERSION_MAJOR 1
|
||||
#define EFILINUX_VERSION_MINOR 0
|
||||
|
||||
#define MEM_ADDR_1MB (1U << 20U)
|
||||
#define MEM_ADDR_4GB (0xFFFFFFFFU)
|
||||
|
||||
|
||||
extern EFI_SYSTEM_TABLE *sys_table;
|
||||
extern EFI_BOOT_SERVICES *boot;
|
||||
extern EFI_RUNTIME_SERVICES *runtime;
|
||||
|
||||
extern EFI_STATUS
|
||||
emalloc_reserved_aligned(EFI_PHYSICAL_ADDRESS *addr, UINTN size, UINTN align,
|
||||
EFI_PHYSICAL_ADDRESS minaddr, EFI_PHYSICAL_ADDRESS maxaddr);
|
||||
|
||||
/**
|
||||
* allocate_pages - Allocate memory pages from the system
|
||||
* @atype: type of allocation to perform
|
||||
* @mtype: type of memory to allocate
|
||||
* @num_pages: number of contiguous 4KB pages to allocate
|
||||
* @memory: used to return the address of allocated pages
|
||||
*
|
||||
* Allocate @num_pages physically contiguous pages from the system
|
||||
* memory and return a pointer to the base of the allocation in
|
||||
* @memory if the allocation succeeds. On success, the firmware memory
|
||||
* map is updated accordingly.
|
||||
*
|
||||
* If @atype is AllocateAddress then, on input, @memory specifies the
|
||||
* address at which to attempt to allocate the memory pages.
|
||||
*/
|
||||
static inline EFI_STATUS
|
||||
allocate_pages(EFI_ALLOCATE_TYPE atype, EFI_MEMORY_TYPE mtype,
|
||||
UINTN num_pages, EFI_PHYSICAL_ADDRESS *memory)
|
||||
{
|
||||
return uefi_call_wrapper(boot->AllocatePages, 4, atype,
|
||||
mtype, num_pages, memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* free_pages - Return memory allocated by allocate_pages() to the firmware
|
||||
* @memory: physical base address of the page range to be freed
|
||||
* @num_pages: number of contiguous 4KB pages to free
|
||||
*
|
||||
* On success, the firmware memory map is updated accordingly.
|
||||
*/
|
||||
static inline EFI_STATUS
|
||||
free_pages(EFI_PHYSICAL_ADDRESS memory, UINTN num_pages)
|
||||
{
|
||||
return uefi_call_wrapper(boot->FreePages, 2, memory, num_pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* allocate_pool - Allocate pool memory
|
||||
* @type: the type of pool to allocate
|
||||
* @size: number of bytes to allocate from pool of @type
|
||||
* @buffer: used to return the address of allocated memory
|
||||
*
|
||||
* Allocate memory from pool of @type. If the pool needs more memory
|
||||
* pages are allocated from EfiConventionalMemory in order to grow the
|
||||
* pool.
|
||||
*
|
||||
* All allocations are eight-byte aligned.
|
||||
*/
|
||||
static inline EFI_STATUS
|
||||
allocate_pool(EFI_MEMORY_TYPE type, UINTN size, void **buffer)
|
||||
{
|
||||
return uefi_call_wrapper(boot->AllocatePool, 3, type, size, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* free_pool - Return pool memory to the system
|
||||
* @buffer: the buffer to free
|
||||
*
|
||||
* Return @buffer to the system. The returned memory is marked as
|
||||
* EfiConventionalMemory.
|
||||
*/
|
||||
static inline EFI_STATUS free_pool(void *buffer)
|
||||
{
|
||||
return uefi_call_wrapper(boot->FreePool, 1, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* get_memory_map - Return the current memory map
|
||||
* @size: the size in bytes of @map
|
||||
* @map: buffer to hold the current memory map
|
||||
* @key: used to return the key for the current memory map
|
||||
* @descr_size: used to return the size in bytes of EFI_MEMORY_DESCRIPTOR
|
||||
* @descr_version: used to return the version of EFI_MEMORY_DESCRIPTOR
|
||||
*
|
||||
* Get a copy of the current memory map. The memory map is an array of
|
||||
* EFI_MEMORY_DESCRIPTORs. An EFI_MEMORY_DESCRIPTOR describes a
|
||||
* contiguous block of memory.
|
||||
*
|
||||
* On success, @key is updated to contain an identifer for the current
|
||||
* memory map. The firmware's key is changed every time something in
|
||||
* the memory map changes. @size is updated to indicate the size of
|
||||
* the memory map pointed to by @map.
|
||||
*
|
||||
* @descr_size and @descr_version are used to ensure backwards
|
||||
* compatibility with future changes made to the EFI_MEMORY_DESCRIPTOR
|
||||
* structure. @descr_size MUST be used when the size of an
|
||||
* EFI_MEMORY_DESCRIPTOR is used in a calculation, e.g when iterating
|
||||
* over an array of EFI_MEMORY_DESCRIPTORs.
|
||||
*
|
||||
* On failure, and if the buffer pointed to by @map is too small to
|
||||
* hold the memory map, EFI_BUFFER_TOO_SMALL is returned and @size is
|
||||
* updated to reflect the size of a buffer required to hold the memory
|
||||
* map.
|
||||
*/
|
||||
static inline EFI_STATUS
|
||||
get_memory_map(UINTN *size, EFI_MEMORY_DESCRIPTOR *map, UINTN *key,
|
||||
UINTN *descr_size, UINT32 *descr_version)
|
||||
{
|
||||
return uefi_call_wrapper(boot->GetMemoryMap, 5, size, map,
|
||||
key, descr_size, descr_version);
|
||||
}
|
||||
|
||||
/**
|
||||
* exit_boot_serivces - Terminate all boot services
|
||||
* @image: firmware-allocated handle that identifies the image
|
||||
* @key: key to the latest memory map
|
||||
*
|
||||
* This function is called when efilinux wants to take complete
|
||||
* control of the system. efilinux should not make calls to boot time
|
||||
* services after this function is called.
|
||||
*/
|
||||
static inline EFI_STATUS
|
||||
exit_boot_services(EFI_HANDLE image, UINTN key)
|
||||
{
|
||||
return uefi_call_wrapper(boot->ExitBootServices, 2, image, key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* handle_protocol - Query @handle to see if it supports @protocol
|
||||
* @handle: the handle being queried
|
||||
* @protocol: the GUID of the protocol
|
||||
* @interface: used to return the protocol interface
|
||||
*
|
||||
* Query @handle to see if @protocol is supported. If it is supported,
|
||||
* @interface contains the protocol interface.
|
||||
*/
|
||||
static inline EFI_STATUS
|
||||
handle_protocol(EFI_HANDLE handle, EFI_GUID *protocol, void **interface)
|
||||
{
|
||||
return uefi_call_wrapper(boot->HandleProtocol, 3,
|
||||
handle, protocol, interface);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* emalloc_reserved_mem - it is called to allocate memory hypervisor itself
|
||||
* and trampoline code, and mark the allocate memory as EfiReserved memory
|
||||
* type so that SOS won't touch it during boot.
|
||||
* @addr: a pointer to the allocated address on success
|
||||
* @size: size in bytes of the requested allocation
|
||||
* @max_addr: the allocated memory must be no more than this threshold
|
||||
*/
|
||||
static inline EFI_STATUS emalloc_reserved_mem(EFI_PHYSICAL_ADDRESS *addr,
|
||||
UINTN size, EFI_PHYSICAL_ADDRESS max_addr)
|
||||
{
|
||||
*addr = max_addr;
|
||||
return allocate_pages(AllocateMaxAddress, EfiReservedMemoryType,
|
||||
EFI_SIZE_TO_PAGES(size), addr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* emalloc_fixed_addr - it is called to allocate memory hypervisor itself
|
||||
* when CONFIG_RELOC config is NOT enable.And mark the allocated memory as
|
||||
* EfiReserved memory type so that SOS won't touch it during boot.
|
||||
* @addr: a pointer to the allocated address on success
|
||||
* @size: size in bytes of the requested allocation
|
||||
*/
|
||||
static inline EFI_STATUS emalloc_fixed_addr(EFI_PHYSICAL_ADDRESS *addr,
|
||||
UINTN size, EFI_PHYSICAL_ADDRESS fixed_addr)
|
||||
{
|
||||
*addr = fixed_addr;
|
||||
return allocate_pages(AllocateAddress, EfiReservedMemoryType,
|
||||
EFI_SIZE_TO_PAGES(size), addr);
|
||||
}
|
||||
|
||||
static inline EFI_STATUS get_variable(const CHAR16 *name, EFI_GUID *guid, UINT32 *attrs, UINTN *size, void *data)
|
||||
{
|
||||
return uefi_call_wrapper(runtime->GetVariable, 5, name, guid, attrs, size, data);
|
||||
}
|
||||
|
||||
static inline EFI_STATUS set_variable(const CHAR16 *name, EFI_GUID *guid, UINT32 attrs, UINTN size, void *data)
|
||||
{
|
||||
return uefi_call_wrapper(runtime->SetVariable, 5, name, guid, attrs, size, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* exit - Terminate a loaded EFI image
|
||||
* @image: firmware-allocated handle that identifies the image
|
||||
* @status: the image's exit code
|
||||
* @size: size in bytes of @reason. Ignored if @status is EFI_SUCCESS
|
||||
* @reason: a NUL-terminated status string, optionally followed by binary data
|
||||
*
|
||||
* This function terminates @image and returns control to the boot
|
||||
* services. This function MUST NOT be called until all loaded child
|
||||
* images have exited. All memory allocated by the image must be freed
|
||||
* before calling this function, apart from the buffer @reason, which
|
||||
* will be freed by the firmware.
|
||||
*/
|
||||
static inline EFI_STATUS
|
||||
exit(EFI_HANDLE image, EFI_STATUS status, UINTN size, CHAR16 *reason)
|
||||
{
|
||||
return uefi_call_wrapper(boot->Exit, 4, image, status, size, reason);
|
||||
}
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
static const CHAR16 *memory_types[] = {
|
||||
L"EfiReservedMemoryType",
|
||||
L"EfiLoaderCode",
|
||||
L"EfiLoaderData",
|
||||
L"EfiBootServicesCode",
|
||||
L"EfiBootServicesData",
|
||||
L"EfiRuntimeServicesCode",
|
||||
L"EfiRuntimeServicesData",
|
||||
L"EfiConventionalMemory",
|
||||
L"EfiUnusableMemory",
|
||||
L"EfiACPIReclaimMemory",
|
||||
L"EfiACPIMemoryNVS",
|
||||
L"EfiMemoryMappedIO",
|
||||
L"EfiMemoryMappedIOPortSpace",
|
||||
L"EfiPalCode",
|
||||
};
|
||||
|
||||
static inline const CHAR16 *memory_type_to_str(UINT32 type)
|
||||
{
|
||||
if (type > sizeof(memory_types)/sizeof(CHAR16 *))
|
||||
return L"Unknown";
|
||||
|
||||
return memory_types[type];
|
||||
}
|
||||
|
||||
extern EFI_STATUS memory_map(EFI_MEMORY_DESCRIPTOR **map_buf,
|
||||
UINTN *map_size, UINTN *map_key,
|
||||
UINTN *desc_size, UINT32 *desc_version);
|
||||
|
||||
#endif /* __EFILINUX_H__ */
|
150
misc/efi-stub/malloc.c
Normal file
150
misc/efi-stub/malloc.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2021, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include "efilinux.h"
|
||||
#include "stdlib.h"
|
||||
#include "boot.h"
|
||||
|
||||
EFI_STATUS
|
||||
emalloc_reserved_aligned(EFI_PHYSICAL_ADDRESS *addr, UINTN size, UINTN align,
|
||||
EFI_PHYSICAL_ADDRESS minaddr, EFI_PHYSICAL_ADDRESS maxaddr)
|
||||
{
|
||||
struct efi_memmap_info mmap_info;
|
||||
UINTN msize, desc_sz, desc_addr, pages;
|
||||
EFI_MEMORY_DESCRIPTOR *mbuf;
|
||||
EFI_STATUS err;
|
||||
|
||||
pages = EFI_SIZE_TO_PAGES(size);
|
||||
|
||||
/* Memory map may change so we request it again */
|
||||
err = get_efi_memmap(&mmap_info, 0);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
msize = mmap_info.map_size;
|
||||
desc_sz = mmap_info.desc_size;
|
||||
mbuf = mmap_info.mmap;
|
||||
|
||||
/* ACRN requests for lowest possible address that's greater than minaddr */
|
||||
/* TODO: in the future we may want to support both preferences */
|
||||
for (desc_addr = (UINTN)mbuf; desc_addr <= (UINTN)mbuf + msize - desc_sz; desc_addr += desc_sz) {
|
||||
EFI_MEMORY_DESCRIPTOR *desc;
|
||||
EFI_PHYSICAL_ADDRESS start, end;
|
||||
|
||||
desc = (EFI_MEMORY_DESCRIPTOR*)desc_addr;
|
||||
if (desc->Type != EfiConventionalMemory)
|
||||
continue;
|
||||
|
||||
start = desc->PhysicalStart;
|
||||
end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT);
|
||||
|
||||
/* 1MB low memory is allocated only if required/requested */
|
||||
if ((end <= MEM_ADDR_1MB) && (maxaddr > MEM_ADDR_1MB))
|
||||
continue;
|
||||
|
||||
/* starting allocation from 1M above unless requested */
|
||||
if ((start < MEM_ADDR_1MB) && (maxaddr > MEM_ADDR_1MB)) {
|
||||
start = MEM_ADDR_1MB;
|
||||
}
|
||||
|
||||
/* zero page won't be allocated */
|
||||
if (start < 4096) {
|
||||
start = 4096;
|
||||
}
|
||||
|
||||
if (start < minaddr) {
|
||||
start = minaddr;
|
||||
}
|
||||
start = (start + align - 1) & ~(align - 1);
|
||||
|
||||
/* Since this routine is called during booting, memory block is large
|
||||
* enought, the reduction of memory size for memory alignment won't
|
||||
* impact allocation. It is true in most cases. if it is not true, loop
|
||||
* again
|
||||
*/
|
||||
if ((start + size <= end) && (start + size <= maxaddr)) {
|
||||
err = allocate_pages(AllocateAddress, EfiReservedMemoryType, pages, &start);
|
||||
if (err == EFI_SUCCESS) {
|
||||
*addr = start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (desc_addr > (UINTN)mbuf + msize - desc_sz) {
|
||||
err = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
free_pool(mbuf);
|
||||
|
||||
fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS dump_e820(void)
|
||||
{
|
||||
UINTN map_size, map_key, desc_size;
|
||||
EFI_MEMORY_DESCRIPTOR *map_buf;
|
||||
UINTN d, map_end;
|
||||
UINTN i;
|
||||
UINT32 desc_version;
|
||||
EFI_STATUS err;
|
||||
|
||||
err = memory_map(&map_buf, &map_size, &map_key,
|
||||
&desc_size, &desc_version);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
d = (UINTN)map_buf;
|
||||
map_end = (UINTN)map_buf + map_size;
|
||||
|
||||
for (i = 0; d < map_end; d += desc_size, i++) {
|
||||
EFI_MEMORY_DESCRIPTOR *desc;
|
||||
EFI_PHYSICAL_ADDRESS start, end;
|
||||
|
||||
desc = (EFI_MEMORY_DESCRIPTOR *)d;
|
||||
if (desc->Type != EfiConventionalMemory)
|
||||
continue;
|
||||
|
||||
start = desc->PhysicalStart;
|
||||
end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT);
|
||||
|
||||
Print(L"[%d]start:%lx, end:%lx, type:%d\n", i, start, end, desc->Type);
|
||||
}
|
||||
|
||||
free_pool(map_buf);
|
||||
fail:
|
||||
return err;
|
||||
}
|
||||
|
378
misc/efi-stub/multiboot.h
Normal file
378
misc/efi-stub/multiboot.h
Normal file
@ -0,0 +1,378 @@
|
||||
/* [ORIGIN: src/sys/arch/i386/include/... */
|
||||
/* $NetBSD: multiboot.h,v 1.8 2009/02/22 18:05:42 ahoka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Julio M. Merino Vidal.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* multiboot.h
|
||||
*/
|
||||
|
||||
#ifndef _MULTIBOOT_H
|
||||
#define _MULTIBOOT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
|
||||
struct multiboot_info;
|
||||
extern struct multiboot_info mbi;
|
||||
|
||||
/*
|
||||
* Multiboot header structure.
|
||||
*/
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
#define MULTIBOOT_HEADER_MODS_ALIGNED 0x00000001
|
||||
#define MULTIBOOT_HEADER_WANT_MEMORY 0x00000002
|
||||
#define MULTIBOOT_HEADER_HAS_VBE 0x00000004
|
||||
#define MULTIBOOT_HEADER_HAS_ADDR 0x00010000
|
||||
|
||||
#define MULTIBOOT_HEADER_ALIGN 4
|
||||
#define MULTIBOOT_SEARCH 8192
|
||||
|
||||
#if !defined(_LOCORE)
|
||||
struct multiboot_header {
|
||||
uint32_t mh_magic;
|
||||
uint32_t mh_flags;
|
||||
uint32_t mh_checksum;
|
||||
|
||||
/* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */
|
||||
uint32_t mh_header_addr;
|
||||
uint32_t mh_load_addr;
|
||||
uint32_t mh_load_end_addr;
|
||||
uint32_t mh_bss_end_addr;
|
||||
uint32_t mh_entry_addr;
|
||||
|
||||
/* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE. */
|
||||
uint32_t mh_mode_type;
|
||||
uint32_t mh_width;
|
||||
uint32_t mh_height;
|
||||
uint32_t mh_depth;
|
||||
};
|
||||
#endif /* !defined(_LOCORE) */
|
||||
|
||||
/*
|
||||
* Symbols defined in locore.S.
|
||||
*/
|
||||
extern struct multiboot_header *Multiboot_Header;
|
||||
|
||||
/*
|
||||
* Multiboot information structure.
|
||||
*/
|
||||
#define MULTIBOOT_INFO_MAGIC 0x2BADB002U
|
||||
#define MULTIBOOT_INFO_HAS_MEMORY 0x00000001U
|
||||
#define MULTIBOOT_INFO_HAS_BOOT_DEVICE 0x00000002U
|
||||
#define MULTIBOOT_INFO_HAS_CMDLINE 0x00000004U
|
||||
#define MULTIBOOT_INFO_HAS_MODS 0x00000008U
|
||||
#define MULTIBOOT_INFO_HAS_AOUT_SYMS 0x00000010U
|
||||
#define MULTIBOOT_INFO_HAS_ELF_SYMS 0x00000020U
|
||||
#define MULTIBOOT_INFO_HAS_MMAP 0x00000040U
|
||||
#define MULTIBOOT_INFO_HAS_DRIVES 0x00000080U
|
||||
#define MULTIBOOT_INFO_HAS_CONFIG_TABLE 0x00000100U
|
||||
#define MULTIBOOT_INFO_HAS_LOADER_NAME 0x00000200U
|
||||
#define MULTIBOOT_INFO_HAS_APM_TABLE 0x00000400U
|
||||
#define MULTIBOOT_INFO_HAS_VBE 0x00000800U
|
||||
|
||||
#if !defined(_LOCORE)
|
||||
struct multiboot_info {
|
||||
uint32_t mi_flags;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_MEMORY. */
|
||||
uint32_t mi_mem_lower;
|
||||
uint32_t mi_mem_upper;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_BOOT_DEVICE. */
|
||||
uint8_t mi_boot_device_part3;
|
||||
uint8_t mi_boot_device_part2;
|
||||
uint8_t mi_boot_device_part1;
|
||||
uint8_t mi_boot_device_drive;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_CMDLINE. */
|
||||
uint32_t mi_cmdline;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_MODS. */
|
||||
uint32_t mi_mods_count;
|
||||
uint32_t mi_mods_addr;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_{AOUT,ELF}_SYMS. */
|
||||
uint32_t mi_elfshdr_num;
|
||||
uint32_t mi_elfshdr_size;
|
||||
uint32_t mi_elfshdr_addr;
|
||||
uint32_t mi_elfshdr_shndx;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_MMAP. */
|
||||
uint32_t mi_mmap_length;
|
||||
uint32_t mi_mmap_addr;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_DRIVES. */
|
||||
uint32_t mi_drives_length;
|
||||
uint32_t mi_drives_addr;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_CONFIG_TABLE. */
|
||||
uint32_t unused_mi_config_table;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_LOADER_NAME. */
|
||||
uint32_t mi_loader_name;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_APM. */
|
||||
uint32_t unused_mi_apm_table;
|
||||
|
||||
/* Valid if mi_flags sets MULTIBOOT_INFO_HAS_VBE. */
|
||||
uint32_t unused_mi_vbe_control_info;
|
||||
uint32_t unused_mi_vbe_mode_info;
|
||||
uint32_t unused_mi_vbe_interface_seg;
|
||||
uint32_t unused_mi_vbe_interface_off;
|
||||
uint32_t unused_mi_vbe_interface_len;
|
||||
}__aligned(8);
|
||||
|
||||
|
||||
/*
|
||||
* Memory mapping. This describes an entry in the memory mappings table
|
||||
* as pointed to by mi_mmap_addr.
|
||||
*
|
||||
* Be aware that mm_size specifies the size of all other fields *except*
|
||||
* for mm_size. In order to jump between two different entries, you
|
||||
* have to count mm_size + 4 bytes.
|
||||
*/
|
||||
struct __attribute__((packed)) multiboot_mmap {
|
||||
uint32_t mm_size;
|
||||
uint64_t mm_base_addr;
|
||||
uint64_t mm_length;
|
||||
uint32_t mm_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* Modules. This describes an entry in the modules table as pointed
|
||||
* to by mi_mods_addr.
|
||||
*/
|
||||
|
||||
struct multiboot_module {
|
||||
uint32_t mmo_start;
|
||||
uint32_t mmo_end;
|
||||
uint32_t mmo_string;
|
||||
uint32_t mmo_reserved;
|
||||
} __packed;
|
||||
|
||||
#endif /* !defined(_LOCORE) */
|
||||
|
||||
struct multiboot2_header
|
||||
{
|
||||
uint32_t magic;
|
||||
uint32_t architecture;
|
||||
uint32_t header_length;
|
||||
uint32_t checksum;
|
||||
};
|
||||
|
||||
#define MULTIBOOT2_SEARCH 32768
|
||||
|
||||
#define MULTIBOOT2_HEADER_ALIGN 8
|
||||
|
||||
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6U
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT2_INFO_MAGIC 0x36d76289U
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT2_INFO_ALIGN 0x00000008U
|
||||
|
||||
/* Flags set in the 'flags' member of the multiboot header. */
|
||||
|
||||
#define MULTIBOOT2_TAG_ALIGN 8U
|
||||
#define MULTIBOOT2_TAG_TYPE_END 0U
|
||||
#define MULTIBOOT2_TAG_TYPE_CMDLINE 1U
|
||||
#define MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME 2U
|
||||
#define MULTIBOOT2_TAG_TYPE_MODULE 3U
|
||||
#define MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO 4U
|
||||
#define MULTIBOOT2_TAG_TYPE_BOOTDEV 5U
|
||||
#define MULTIBOOT2_TAG_TYPE_MMAP 6U
|
||||
#define MULTIBOOT2_TAG_TYPE_VBE 7U
|
||||
#define MULTIBOOT2_TAG_TYPE_FRAMEBUFFER 8U
|
||||
#define MULTIBOOT2_TAG_TYPE_ELF_SECTIONS 9U
|
||||
#define MULTIBOOT2_TAG_TYPE_APM 10U
|
||||
#define MULTIBOOT2_TAG_TYPE_EFI32 11U
|
||||
#define MULTIBOOT2_TAG_TYPE_EFI64 12U
|
||||
#define MULTIBOOT2_TAG_TYPE_SMBIOS 13U
|
||||
#define MULTIBOOT2_TAG_TYPE_ACPI_OLD 14U
|
||||
#define MULTIBOOT2_TAG_TYPE_ACPI_NEW 15U
|
||||
#define MULTIBOOT2_TAG_TYPE_NETWORK 16U
|
||||
#define MULTIBOOT2_TAG_TYPE_EFI_MMAP 17U
|
||||
#define MULTIBOOT2_TAG_TYPE_EFI_BS 18U
|
||||
#define MULTIBOOT2_TAG_TYPE_EFI32_IH 19U
|
||||
#define MULTIBOOT2_TAG_TYPE_EFI64_IH 20U
|
||||
#define MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR 21U
|
||||
|
||||
#define MULTIBOOT2_HEADER_TAG_END 0
|
||||
#define MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST 1
|
||||
#define MULTIBOOT2_HEADER_TAG_ADDRESS 2
|
||||
#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS 3
|
||||
#define MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS 4
|
||||
#define MULTIBOOT2_HEADER_TAG_FRAMEBUFFER 5
|
||||
#define MULTIBOOT2_HEADER_TAG_MODULE_ALIGN 6
|
||||
#define MULTIBOOT2_HEADER_TAG_EFI_BS 7
|
||||
#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
|
||||
#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
|
||||
#define MULTIBOOT2_HEADER_TAG_RELOCATABLE 10
|
||||
#define MULTIBOOT2_HEADER_TAG_OPTIONAL 1
|
||||
|
||||
#define MULTIBOOT2_ARCHITECTURE_I386 0
|
||||
|
||||
#ifndef ASSEMBLER
|
||||
|
||||
struct multiboot2_header_tag
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot2_header_tag_information_request
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
uint32_t size;
|
||||
uint32_t requests[0];
|
||||
};
|
||||
|
||||
struct multiboot2_header_tag_address
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
uint32_t size;
|
||||
uint32_t header_addr;
|
||||
uint32_t load_addr;
|
||||
uint32_t load_end_addr;
|
||||
uint32_t bss_end_addr;
|
||||
};
|
||||
|
||||
struct multiboot2_header_tag_entry_address
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
uint32_t size;
|
||||
uint32_t entry_addr;
|
||||
};
|
||||
|
||||
struct multiboot2_header_tag_console_flags
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
uint32_t size;
|
||||
uint32_t console_flags;
|
||||
};
|
||||
|
||||
struct multiboot2_header_tag_framebuffer
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
uint32_t size;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t depth;
|
||||
};
|
||||
|
||||
struct multiboot2_header_tag_module_align
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot2_header_tag_relocatable
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
uint32_t size;
|
||||
uint32_t min_addr;
|
||||
uint32_t max_addr;
|
||||
uint32_t align;
|
||||
uint32_t preference;
|
||||
};
|
||||
|
||||
struct multiboot2_mmap_entry
|
||||
{
|
||||
uint64_t addr;
|
||||
uint64_t len;
|
||||
uint32_t type;
|
||||
uint32_t zero;
|
||||
};
|
||||
|
||||
struct multiboot2_tag
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot2_tag_string
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
char string[0];
|
||||
};
|
||||
|
||||
struct multiboot2_tag_module
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t mod_start;
|
||||
uint32_t mod_end;
|
||||
char cmdline[0];
|
||||
};
|
||||
|
||||
struct multiboot2_tag_mmap
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t entry_size;
|
||||
uint32_t entry_version;
|
||||
struct multiboot2_mmap_entry entries[0];
|
||||
};
|
||||
|
||||
struct multiboot2_tag_new_acpi
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct multiboot2_tag_efi64
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint64_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot2_tag_efi_mmap {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t descr_size;
|
||||
uint32_t descr_vers;
|
||||
uint8_t efi_mmap[0];
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* _MULTIBOOT_H */
|
173
misc/efi-stub/pe.c
Normal file
173
misc/efi-stub/pe.c
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2021, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file contains some wrappers around the gnu-efi functions. As
|
||||
* we're not going through uefi_call_wrapper() directly, this allows
|
||||
* us to get some type-safety for function call arguments and for the
|
||||
* compiler to check that the number of function call arguments is
|
||||
* correct.
|
||||
*
|
||||
* It's also a good place to document the EFI interface.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include "stdlib.h"
|
||||
|
||||
#define DOS_FILE_MAGIC_NUMBER 0x5A4D /* "MZ" */
|
||||
struct DosFileHeader {
|
||||
uint16_t mMagic;
|
||||
uint16_t LastSize;
|
||||
uint16_t nBlocks;
|
||||
uint16_t nReloc;
|
||||
uint16_t HdrSize;
|
||||
uint16_t MinAlloc;
|
||||
uint16_t MaxAlloc;
|
||||
uint16_t ss;
|
||||
uint16_t sp;
|
||||
uint16_t Checksum;
|
||||
uint16_t ip;
|
||||
uint16_t cs;
|
||||
uint16_t RelocPos;
|
||||
uint16_t nOverlay;
|
||||
uint16_t reserved[4];
|
||||
uint16_t OEMId;
|
||||
uint16_t OEMInfo;
|
||||
uint16_t reserved2[10];
|
||||
uint32_t ExeHeader;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define IMAGE_FILE_MACHINE_I386 0x14c
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define PE_FILE_MAGIC_NUMBER 0x00004550 /* "PE\0\0" */
|
||||
struct PeHeader {
|
||||
uint32_t mMagic;
|
||||
uint16_t mMachine;
|
||||
uint16_t mNumberOfSections;
|
||||
uint32_t mTimeDateStamp;
|
||||
uint32_t mPointerToSymbolTable;
|
||||
uint32_t mNumberOfSymbols;
|
||||
uint16_t mSizeOfOptionalHeader;
|
||||
uint16_t mCharacteristics;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct OptionHeader {
|
||||
uint16_t Format;
|
||||
uint8_t MajorLinkVer;
|
||||
uint8_t MinorLinkVer;
|
||||
uint32_t CodeSize;
|
||||
uint32_t InitializedDataSize;
|
||||
uint32_t UninitializedDataSize;
|
||||
uint32_t EntryPoint;
|
||||
uint32_t BaseOfCode;
|
||||
uint32_t BaseOfDate;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
struct PeSectionHeader {
|
||||
char mName[8];
|
||||
uint32_t mVirtualSize;
|
||||
uint32_t mVirtualAddress;
|
||||
uint32_t mSizeOfRawData;
|
||||
uint32_t mPointerToRawData;
|
||||
uint32_t mPointerToRealocations;
|
||||
uint32_t mPointerToLinenumbers;
|
||||
uint16_t mNumberOfRealocations;
|
||||
uint16_t mNumberOfLinenumbers;
|
||||
uint32_t mCharacteristics;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
EFI_STATUS get_pe_section(CHAR8 *base, char *section_name,
|
||||
UINTN section_name_len, UINTN *vaddr, UINTN *size)
|
||||
{
|
||||
struct PeSectionHeader *ph;
|
||||
struct DosFileHeader *dh;
|
||||
struct PeHeader *pe;
|
||||
UINTN i;
|
||||
UINTN offset;
|
||||
|
||||
dh = (struct DosFileHeader *)base;
|
||||
|
||||
if (dh->mMagic != DOS_FILE_MAGIC_NUMBER)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
pe = (struct PeHeader *)&base[dh->ExeHeader];
|
||||
if (pe->mMagic != PE_FILE_MAGIC_NUMBER)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
if ((pe->mMachine != IMAGE_FILE_MACHINE_AMD64)
|
||||
&& (pe->mMachine != IMAGE_FILE_MACHINE_I386))
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
offset = dh->ExeHeader + sizeof(*pe) + pe->mSizeOfOptionalHeader;
|
||||
|
||||
for (i = 0; i < pe->mNumberOfSections; i++) {
|
||||
ph = (struct PeSectionHeader *)&base[offset];
|
||||
if (CompareMem(ph->mName, section_name, section_name_len) == 0) {
|
||||
*vaddr = (UINTN)ph->mVirtualAddress;
|
||||
*size = (UINTN)ph->mVirtualSize;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += sizeof(*ph);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_IMAGE_ENTRY_POINT get_pe_entry(CHAR8 *base)
|
||||
{
|
||||
struct DosFileHeader* dh;
|
||||
struct PeHeader* pe;
|
||||
struct OptionHeader* oh;
|
||||
UINTN offset;
|
||||
|
||||
dh = (struct DosFileHeader *)base;
|
||||
|
||||
if (dh->mMagic != DOS_FILE_MAGIC_NUMBER)
|
||||
return NULL;
|
||||
|
||||
pe = (struct PeHeader *)&base[dh->ExeHeader];
|
||||
if (pe->mMagic != PE_FILE_MAGIC_NUMBER)
|
||||
return NULL;
|
||||
|
||||
if ((pe->mMachine != IMAGE_FILE_MACHINE_AMD64)
|
||||
&& (pe->mMachine != IMAGE_FILE_MACHINE_I386))
|
||||
return NULL;
|
||||
|
||||
offset = dh->ExeHeader + sizeof(*pe);
|
||||
oh = (struct OptionHeader*)&base[offset];
|
||||
|
||||
return (EFI_IMAGE_ENTRY_POINT)((UINT64)base + oh->EntryPoint);
|
||||
}
|
128
misc/efi-stub/stdlib.h
Normal file
128
misc/efi-stub/stdlib.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2021, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This file contains some wrappers around the gnu-efi functions. As
|
||||
* we're not going through uefi_call_wrapper() directly, this allows
|
||||
* us to get some type-safety for function call arguments and for the
|
||||
* compiler to check that the number of function call arguments is
|
||||
* correct.
|
||||
*
|
||||
* It's also a good place to document the EFI interface.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __STDLIB_H__
|
||||
#define __STDLIB_H__
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
static inline void memset(void *dstv, char ch, UINTN size)
|
||||
{
|
||||
char *dst = dstv;
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
dst[i] = ch;
|
||||
}
|
||||
|
||||
static inline void memcpy(char *dst, const char *src, UINTN size)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static inline int32_t strlen(const char *str)
|
||||
{
|
||||
int32_t len;
|
||||
|
||||
len = 0;
|
||||
while (*str++)
|
||||
len++;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline CHAR16 *strstr_16(CHAR16 *haystack, CHAR16 *needle, UINTN len)
|
||||
{
|
||||
CHAR16 *p;
|
||||
CHAR16 *word = NULL;
|
||||
|
||||
if (!len)
|
||||
return NULL;
|
||||
|
||||
p = haystack;
|
||||
while (*p) {
|
||||
if (!StrnCmp(p, needle, len)) {
|
||||
word = p;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
return (CHAR16*)word;
|
||||
}
|
||||
|
||||
static inline char *ch16_2_ch8(CHAR16 *str16, UINTN len)
|
||||
{
|
||||
UINTN i;
|
||||
char *str8;
|
||||
|
||||
str8 = AllocatePool((len + 1) * sizeof(char));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
str8[i] = str16[i];
|
||||
|
||||
str8[len] = 0;
|
||||
|
||||
return str8;
|
||||
}
|
||||
|
||||
static inline CHAR16 *ch8_2_ch16(char *str8, UINTN len)
|
||||
{
|
||||
UINTN i;
|
||||
CHAR16 *str16;
|
||||
|
||||
str16 = AllocatePool((len + 1) * sizeof(CHAR16));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
str16[i] = str8[i];
|
||||
|
||||
str16[len] = 0;
|
||||
|
||||
return str16;
|
||||
}
|
||||
|
||||
#endif /* __STDLIB_H__ */
|
Loading…
Reference in New Issue
Block a user