From 9bfea51ed5d8e5fd1f73bfec3aad310d676fe2d8 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Wed, 6 Mar 2024 16:36:25 +0800 Subject: [PATCH 1/6] acpi: add an interface to get rsdp Signed-off-by: Qiang Zhang --- include/acpi.h | 2 ++ libkernelflinger/acpi.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/include/acpi.h b/include/acpi.h index 277e1018..78dbfd75 100644 --- a/include/acpi.h +++ b/include/acpi.h @@ -148,6 +148,8 @@ enum acpi_src_type { ACPI_SRC_TYPE_MAX }; +EFI_STATUS get_acpi_rsdp(VOID **prsdp); + /* Some ACPI table signatures, SSDT for instance, might appear several * times. An extra table number can be appended to the supplied * SIGNATURE to specify which one is required. For instance, with diff --git a/libkernelflinger/acpi.c b/libkernelflinger/acpi.c index 21140c7a..668a287a 100644 --- a/libkernelflinger/acpi.c +++ b/libkernelflinger/acpi.c @@ -183,6 +183,12 @@ static EFI_STATUS get_xsdt_table(struct XSDT_TABLE **xsdt) return ret; } +EFI_STATUS get_acpi_rsdp(VOID **prsdp) +{ + EFI_GUID acpi2_guid = ACPI_20_TABLE_GUID; + return LibGetSystemConfigurationTable(&acpi2_guid, prsdp); +} + EFI_STATUS get_acpi_table(const CHAR8 *signature, VOID **table) { struct XSDT_TABLE *xsdt; From 67707d2fd639c2240b16436065943521fdda0805 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Wed, 6 Mar 2024 16:42:02 +0800 Subject: [PATCH 2/6] add API to parse multiboot2 image TODO Abstracts a generic multiboot2 load flow Signed-off-by: Qiang Zhang --- include/multiboot.h | 286 +++++++++++++++++++++++++++++++++++ libkernelflinger/multiboot.c | 207 +++++++++++++++++++++++++ 2 files changed, 493 insertions(+) create mode 100644 include/multiboot.h create mode 100644 libkernelflinger/multiboot.c diff --git a/include/multiboot.h b/include/multiboot.h new file mode 100644 index 00000000..7defcb2c --- /dev/null +++ b/include/multiboot.h @@ -0,0 +1,286 @@ +/* [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 + +struct multiboot2_header +{ + uint32_t magic; + uint32_t architecture; + uint32_t header_length; + uint32_t checksum; +} __attribute__((__packed__)); + +#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 + +struct multiboot2_header_tag +{ + uint16_t type; + uint16_t flags; + uint32_t size; +}__attribute__((__packed__)); + +struct multiboot2_header_tag_information_request +{ + uint16_t type; + uint16_t flags; + uint32_t size; + uint32_t requests[0]; +}__attribute__((__packed__)); + +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; +}__attribute__((__packed__)); + +struct multiboot2_header_tag_entry_address +{ + uint16_t type; + uint16_t flags; + uint32_t size; + uint32_t entry_addr; +}__attribute__((__packed__)); + +struct multiboot2_header_tag_console_flags +{ + uint16_t type; + uint16_t flags; + uint32_t size; + uint32_t console_flags; +}__attribute__((__packed__)); + +struct multiboot2_header_tag_framebuffer +{ + uint16_t type; + uint16_t flags; + uint32_t size; + uint32_t width; + uint32_t height; + uint32_t depth; +}__attribute__((__packed__)); + +struct multiboot2_header_tag_module_align +{ + uint16_t type; + uint16_t flags; + uint32_t size; +}__attribute__((__packed__)); + +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; +}__attribute__((__packed__)); + +struct multiboot2_mmap_entry +{ + uint64_t addr; + uint64_t len; + uint32_t type; + uint32_t zero; +}__attribute__((__packed__)); + +struct multiboot2_tag +{ + uint32_t type; + uint32_t size; +}__attribute__((__packed__)); + +struct multiboot2_tag_string +{ + uint32_t type; + uint32_t size; + char string[0]; +}__attribute__((__packed__)); + +struct multiboot2_tag_module +{ + uint32_t type; + uint32_t size; + uint32_t mod_start; + uint32_t mod_end; + char cmdline[0]; +}__attribute__((__packed__)); + +struct multiboot2_tag_mmap +{ + uint32_t type; + uint32_t size; + uint32_t entry_size; + uint32_t entry_version; + struct multiboot2_mmap_entry entries[0]; +}__attribute__((__packed__)); + +struct multiboot2_tag_new_acpi +{ + uint32_t type; + uint32_t size; + uint8_t rsdp[0]; +}__attribute__((__packed__)); + +struct multiboot2_tag_efi64 +{ + uint32_t type; + uint32_t size; + uint64_t pointer; +}__attribute__((__packed__)); + +struct multiboot2_tag_efi_mmap { + uint32_t type; + uint32_t size; + uint32_t descr_size; + uint32_t descr_vers; + uint8_t efi_mmap[0]; +}__attribute__((__packed__)); + +struct mb2header_tag_list { + struct multiboot2_header_tag_information_request *info_req; + struct multiboot2_header_tag_address *addr; + struct multiboot2_header_tag_entry_address *entry; + struct multiboot2_header_tag_console_flags *console_flags; + struct multiboot2_header_tag_framebuffer *frbuf; + struct multiboot2_header_tag_module_align *modalign; + struct multiboot2_header_tag_relocatable *reloc; +}; + +const struct multiboot2_header *find_mb2header(const uint8_t *buffer, uint64_t len); +int parse_mb2header(const struct multiboot2_header *header, struct mb2header_tag_list *tags); + +#define ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1)) + + +/* in-partitioin MB2 image format, irralevant to multiboot protocol. We may + * change the image format in future. + */ +struct mb2_image_header { +#define MB2_MAGIC_SIZE 8 +#define MB2_MAGIC "ACRNMB2" + uint8_t magic[MB2_MAGIC_SIZE]; + uint32_t header_version; + uint32_t header_size; + uint32_t mod_offset; + uint32_t mod_size; + uint32_t mod_align; +#define MB2_CMDLINE_SIZE 4096 + uint8_t cmdline[MB2_CMDLINE_SIZE]; /* NULL terminated */ +}__attribute__((__packed__)); +void dump_mb2_partition(struct mb2_image_header *hdr); + +struct mb2_module { + void *start; + uint64_t size; + char *cmdline; + uint64_t cmdline_buf_size; +}; + +#define MAX_MB2_IMAGES 16 +struct mb2_images { + struct mb2_image_header *headers[MAX_MB2_IMAGES]; + const char *names[MAX_MB2_IMAGES]; + struct mb2_module mods[16]; + uint8_t cnt; +}; + +EFI_STATUS load_mb2_images(IN struct mb2_images *images); + + + +#endif /* _MULTIBOOT_H */ diff --git a/libkernelflinger/multiboot.c b/libkernelflinger/multiboot.c new file mode 100644 index 00000000..2db0c095 --- /dev/null +++ b/libkernelflinger/multiboot.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2021 - 2022, Intel Corporation. + * + * 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 +#include +#include + +#include "android.h" +#include "efilinux.h" +#include "lib.h" +#include "security.h" +#include "vars.h" +#include "power.h" +#include "targets.h" +#include "gpt.h" +#include "storage.h" +#include "text_parser.h" +#include "watchdog.h" +#ifdef HAL_AUTODETECT +#include "blobstore.h" +#endif +#include "slot.h" +#include "pae.h" +#include "timer.h" +#include "android_vb2.h" +#include "acpi.h" +#ifdef USE_FIRSTSTAGE_MOUNT +#include "firststage_mount.h" +#endif +#ifdef USE_TRUSTY +#include "trusty_common.h" +#endif + +#include "uefi_utils.h" +#include "libxbc.h" + +#include "multiboot.h" +#include "lib.h" + + +/** + * @brief Search the first len bytes in buffer for multiboot2 header. + * + * @param[in] buffer Buffer to be searched + * @param[in] len Search length + * + * @return A pointer to the multiboot2 header if found. NULL otherwise. + */ +const struct multiboot2_header *find_mb2header(const uint8_t *buffer, uint64_t len) +{ + const struct multiboot2_header *header; + + for (header = (const struct multiboot2_header *)buffer; + ((char *)header <= (char *)buffer + len - 12); + header = (struct multiboot2_header *)((uint64_t)header + MULTIBOOT2_HEADER_ALIGN / 4)) + { + if (header->magic == MULTIBOOT2_HEADER_MAGIC && + !(header->magic + header->architecture + header->header_length + header->checksum) && + header->architecture == MULTIBOOT2_ARCHITECTURE_I386) + return header; + } + + return NULL; +} + +/** + * @brief Parse the multiboot2 header and return a list of pointers to the header tags. + * + * @param[in] header Multiboot2 header to be parsed. + * @param[out] tags An mb2header_tag_list struct that contains pointers to all possible + * tags in a multiboot2 header. If a field in this struct is not NULL, it + * means the tag was found in the given header. NULL otherwise. + * + * @return 0 on success. -1 on error. + */ +int parse_mb2header(const struct multiboot2_header *header, struct mb2header_tag_list *tags) +{ + struct multiboot2_header_tag *tag; + + memset(tags, 0, sizeof(struct mb2header_tag_list)); + + for (tag = (struct multiboot2_header_tag *)(header + 1); + tag->type != MULTIBOOT2_TAG_TYPE_END; + tag = (struct multiboot2_header_tag *)((uint32_t *)tag + ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / 4)) + { + switch (tag->type) { + case MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST: + /* Ignored. Currently we didn't support all categories of requested information, + * only the part that ACRN requests. So we don't parse the requests here. */ + break; + + case MULTIBOOT2_HEADER_TAG_ADDRESS: + tags->addr = (struct multiboot2_header_tag_address *)tag; + break; + + case MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS: + tags->entry = (struct multiboot2_header_tag_entry_address *)tag; + break; + + case MULTIBOOT2_HEADER_TAG_RELOCATABLE: + tags->reloc = (struct multiboot2_header_tag_relocatable *)tag; + break; + + default: + Print(L"Unsupported multiboot2 tag type: %d\n", tag->type); + return -1; + } + } + + if (tags->addr && !tags->entry) + return -1; + + return 0; +} + +void dump_mb2_partition(struct mb2_image_header *hdr) +{ + CHAR16* cmdline16 = stra_to_str(hdr->cmdline); + debug(L"mb2 mod offset: 0x%lx", hdr->mod_offset); + debug(L"mb2 mod size: 0x%lx", hdr->mod_size); + debug(L"mb2 mod cmdline: %s", cmdline16); + FreePool(cmdline16); +} + +static bool check_mb2_image(struct mb2_image_header *hdr) +{ + return strncmp(hdr->magic, MB2_MAGIC, MB2_MAGIC_SIZE) == 0; +} + +EFI_STATUS load_mb2_images(IN struct mb2_images *images) +{ + EFI_STATUS ret; + uint8_t i; + + for (i = 0; i < images->cnt; i++) { + struct mb2_image_header *hdr = images->headers[i]; + struct mb2_module *mod = &images->mods[i]; + + CHAR16* str = stra_to_str(images->names[i]); + info(L"loading multiboot2 image/module: %s", str); + FreePool(str); + + if (!check_mb2_image(hdr)) { + return EFI_LOAD_ERROR; + } + + if (i == 0) { + EFI_PHYSICAL_ADDRESS acrn_addr; + uint8_t *buf = (uint8_t *)hdr + hdr->mod_offset; + const struct multiboot2_header *mb2_header = find_mb2header(buf, 4096); + struct mb2header_tag_list tags; + if(parse_mb2header(mb2_header, &tags)) { + error(L"fail to parse multiboot2 header"); + return EFI_LOAD_ERROR; + } + uint32_t acrn_size = tags.addr->load_end_addr - tags.addr->load_addr; + + /* copy acrn to a proper place to meet alignment requirements */ + ret = emalloc(acrn_size, 4*1024*1024, &acrn_addr, FALSE); + if (EFI_ERROR(ret)) { + error(L"fail to allocate memory for acrn image"); + return ret; + } + memset((VOID *)acrn_addr, 0, acrn_size); + memcpy((VOID *)acrn_addr, (void *)hdr + hdr->mod_offset, hdr->mod_size); + mod->start = (VOID *)acrn_addr; + mod->size = acrn_size; + mod->cmdline = hdr->cmdline; + mod->cmdline_buf_size = MB2_CMDLINE_SIZE; + } else { + /* TODO add pre launch vms */ + } + } + + return ret; +} + + From b50d35ed0c794d10d66a82f8692213a2284d800c Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Wed, 6 Mar 2024 16:46:24 +0800 Subject: [PATCH 3/6] KF: factor out a kernel load API without touching bzImage zeropage Signed-off-by: Qiang Zhang --- include/android.h | 16 ++ libkernelflinger/android.c | 308 +++++++++++++++++++++++++++---------- 2 files changed, 241 insertions(+), 83 deletions(-) diff --git a/include/android.h b/include/android.h index 0ddade1f..a5d203c6 100644 --- a/include/android.h +++ b/include/android.h @@ -25,6 +25,7 @@ #endif #include "targets.h" #include "android_vb2.h" +#include "multiboot.h" #define BOOT_MAGIC "ANDROID!" #define BOOT_MAGIC_SIZE 8 @@ -495,6 +496,21 @@ _Static_assert(sizeof(struct bootloader_control) == "struct bootloader_control has wrong size"); #endif +/* load kernel, cmdline and ramdisk */ +EFI_STATUS load_kernel( + IN __attribute__((unused)) EFI_HANDLE parent_image, + IN VOID *bootimage, + IN VOID *vendorbootimage, + IN enum boot_target boot_target, + IN UINT8 boot_state, + IN EFI_GUID *swap_guid, + IN VBDATA *vb_data, + IN const CHAR8 *abl_cmd_line, + IN EFI_PHYSICAL_ADDRESS *kernel_start, IN UINTN *kernel_size, + IN EFI_PHYSICAL_ADDRESS *ramdisk_start, IN UINTN *ramdisk_size, + IN EFI_PHYSICAL_ADDRESS *cmdline_start, IN UINTN *cmdline_size); + + /* Functions to load an Android boot image. * You can do this from a file, a partition GUID, or * from a RAM buffer */ diff --git a/libkernelflinger/android.c b/libkernelflinger/android.c index bfce0ffb..5109631c 100644 --- a/libkernelflinger/android.c +++ b/libkernelflinger/android.c @@ -560,16 +560,15 @@ static struct boot_params *get_boot_param_hdr (VOID *bootimage) return (struct boot_params *)(bootimage + hdr_size); } -static EFI_STATUS setup_ramdisk(UINT8 *bootimage, UINT8 *vendorbootimage, UINT8 *androidcmd) +static EFI_STATUS parse_ramdisk(UINT8 *bootimage, UINT8 *vendorbootimage, UINT8 *androidcmd, + EFI_PHYSICAL_ADDRESS *ramdisk_start, UINTN *ramdisk_size) { struct boot_img_hdr *aosp_header; - struct boot_params *bp; UINT32 roffset, rsize; EFI_PHYSICAL_ADDRESS ramdisk_addr; EFI_STATUS ret; aosp_header = (struct boot_img_hdr *)bootimage; - bp = get_boot_param_hdr(bootimage); if (aosp_header->header_version < BOOT_HEADER_V3) { roffset = aosp_header->page_size + pagealign(aosp_header, @@ -580,17 +579,11 @@ static EFI_STATUS setup_ramdisk(UINT8 *bootimage, UINT8 *vendorbootimage, UINT8 return EFI_SUCCESS; // no ramdisk, so nothing to do } - bp->hdr.ramdisk_len = rsize; debug(L"ramdisk size %d", rsize); ret = emalloc(rsize, 0x1000, &ramdisk_addr, FALSE); if (EFI_ERROR(ret)) return ret; - if ((UINTN)ramdisk_addr > bp->hdr.ramdisk_max) { - error(L"Ramdisk address is too high!"); - efree(ramdisk_addr, rsize); - return EFI_OUT_OF_RESOURCES; - } ret = memcpy_s((VOID *)(UINTN)ramdisk_addr, rsize, bootimage + roffset, rsize); } else if (aosp_header->header_version == BOOT_HEADER_V3) { // boot image v3 struct vendor_boot_img_hdr_v3 *vendor_hdr = (struct vendor_boot_img_hdr_v3 *)vendorbootimage; @@ -603,23 +596,16 @@ static EFI_STATUS setup_ramdisk(UINT8 *bootimage, UINT8 *vendorbootimage, UINT8 return EFI_SUCCESS; // no ramdisk, so nothing to do } - bp->hdr.ramdisk_len = rsize; ret = emalloc(rsize, 0x1000, &ramdisk_addr, FALSE); if (EFI_ERROR(ret)) return ret; - if ((UINTN)ramdisk_addr > bp->hdr.ramdisk_max) { - error(L"Ramdisk address is too high!"); - ret = EFI_OUT_OF_RESOURCES; - goto out; - } ret = memcpy_s((VOID *)(UINTN)ramdisk_addr, rsize, vendorbootimage + BOOT_IMG_HEADER_SIZE_V3, vendor_hdr->vendor_ramdisk_size); if (EFI_ERROR(ret)) goto out; - ret = memcpy_s((VOID *)(UINTN)ramdisk_addr + vendor_hdr->vendor_ramdisk_size, rsize, bootimage + roffset, boot_hdr->ramdisk_size); if (EFI_ERROR(ret)) @@ -652,17 +638,10 @@ static EFI_STATUS setup_ramdisk(UINT8 *bootimage, UINT8 *vendorbootimage, UINT8 return EFI_SUCCESS; // no ramdisk, so nothing to do } - bp->hdr.ramdisk_len = rsize; ret = emalloc(rsize, 0x1000, &ramdisk_addr, FALSE); if (EFI_ERROR(ret)) return ret; - if ((UINTN)ramdisk_addr > bp->hdr.ramdisk_max) { - error(L"Ramdisk address is too high!"); - ret = EFI_OUT_OF_RESOURCES; - goto out; - } - ret = memcpy_s((VOID *)(UINTN)ramdisk_addr, rsize, vendorbootimage + vendor_ramdisk_offset, vendor_hdr->vendor_ramdisk_size); @@ -700,7 +679,8 @@ static EFI_STATUS setup_ramdisk(UINT8 *bootimage, UINT8 *vendorbootimage, UINT8 } } - bp->hdr.ramdisk_start = (UINT32)(UINTN)ramdisk_addr; + *ramdisk_start = ramdisk_addr; + *ramdisk_size = rsize; return EFI_SUCCESS; out: @@ -708,6 +688,31 @@ static EFI_STATUS setup_ramdisk(UINT8 *bootimage, UINT8 *vendorbootimage, UINT8 return ret; } +static EFI_STATUS setup_ramdisk(UINT8 *bootimage, UINT8 *vendorbootimage, UINT8 *androidcmd) +{ + struct boot_params *bp; + EFI_STATUS ret; + EFI_PHYSICAL_ADDRESS ramdisk_start; + UINTN ramdisk_size; + + ret = parse_ramdisk(bootimage, vendorbootimage, androidcmd, + &ramdisk_start, &ramdisk_size); + if (EFI_ERROR(ret)) + return ret; + + bp = get_boot_param_hdr(bootimage); + + if (ramdisk_start > bp->hdr.ramdisk_max) { + error(L"Ramdisk address is too high!"); + efree(ramdisk_start, ramdisk_size); + return EFI_OUT_OF_RESOURCES; + } + + bp->hdr.ramdisk_len = ramdisk_size; + bp->hdr.ramdisk_start = (UINT32)ramdisk_start; + return EFI_SUCCESS; +} + EFI_STATUS setup_acpi_table(VOID *bootimage, __attribute__((__unused__)) enum boot_target target) @@ -936,7 +941,7 @@ static CHAR16 *get_command_line(IN struct boot_img_hdr *aosp_header, CHAR16 *cmdline_prepend = NULL; BOOLEAN needs_pause = FALSE; - if (boot_target == NORMAL_BOOT || boot_target == MEMORY) { + if (boot_target == NORMAL_BOOT || boot_target == ASOS || boot_target == MEMORY) { cmdline16 = get_efi_variable_str8(&loader_guid, CMDLINE_REPLACE_VAR); cmdline_append = get_efi_variable_str8(&loader_guid, CMDLINE_APPEND_VAR); cmdline_prepend = get_efi_variable_str8(&loader_guid, CMDLINE_PREPEND_VAR); @@ -1311,38 +1316,36 @@ static BOOLEAN is_same_console_type(CHAR8 *sos_console, CHAR8 *kernel_console) { return (sos_console == sos_prefix_end) && (kernel_console == kernel_prefix_end); } -/* when we call setup_command_line in EFI, parameter is EFI_GUID *swap_guid. - * when we call setup_command_line in NON EFI, parameter is const CHAR8 *abl_cmd_line. - * */ -static EFI_STATUS setup_command_line( +static EFI_STATUS parse_command_line( IN UINT8 *bootimage, IN UINT8 *vendorbootimage, IN enum boot_target boot_target, IN void *parameter, IN UINT8 boot_state, IN VBDATA *vb_data, - OUT UINT8 **androidcmd + OUT UINT8 **androidcmd, + OUT EFI_PHYSICAL_ADDRESS *cmdline_start, + OUT UINTN *cmdline_size ) { - CHAR16 *cmdline16 = NULL; - char *serialno = NULL; - CHAR16 *serialport = NULL; - CHAR16 *bootreason = NULL; - EFI_PHYSICAL_ADDRESS cmdline_addr = 0; - CHAR8 *cmdline; - CHAR8 *cmd_conf= NULL; - UINTN cmdlen; - UINTN cmdsize; - UINTN vb_cmdlen = 0; - EFI_STATUS ret; - struct boot_params *buf; - struct boot_img_hdr *aosp_header; - CHAR8 time_str8[128] = {0}; - CHAR16 *time_str16 = NULL; - EFI_GUID *swap_guid = NULL; - CHAR8 *abl_cmd_line = NULL; - BOOLEAN is_uefi = TRUE; - UINTN abl_cmd_len = 0; + CHAR16 *cmdline16 = NULL; + char *serialno = NULL; + CHAR16 *serialport = NULL; + CHAR16 *bootreason = NULL; + EFI_PHYSICAL_ADDRESS cmdline_addr = 0; + CHAR8 *cmdline; + CHAR8 *cmd_conf= NULL; + UINTN cmdlen; + UINTN cmdsize; + UINTN vb_cmdlen = 0; + EFI_STATUS ret; + struct boot_img_hdr *aosp_header; + CHAR8 time_str8[128] = {0}; + CHAR16 *time_str16 = NULL; + EFI_GUID *swap_guid = NULL; + CHAR8 *abl_cmd_line = NULL; + BOOLEAN is_uefi = TRUE; + UINTN abl_cmd_len = 0; #ifdef USE_SBL const char *cmd_for_kernel = NULL; char *tmp = NULL; @@ -1527,14 +1530,14 @@ static EFI_STATUS setup_command_line( if (EFI_ERROR(ret)) goto out; #if defined(DYNAMIC_PARTITIONS) && defined(USE_SLOT) - //BOARD_USES_RECOVERY_AS_BOOT is set to true, the recovery image is built as boot.img - //containing the recovery’s ramdisk. command line "androidboot.force_normal_boot=1" is - //mandatory for normal boot. - if(boot_target == NORMAL_BOOT) { - ret = prepend_command_line(&cmdline16, L"androidboot.force_normal_boot=1"); - if (EFI_ERROR(ret)) - goto out; - } + //BOARD_USES_RECOVERY_AS_BOOT is set to true, the recovery image is built as boot.img + //containing the recovery’s ramdisk. command line "androidboot.force_normal_boot=1" is + //mandatory for normal boot. + if(boot_target == NORMAL_BOOT || boot_target == ASOS) { + ret = prepend_command_line(&cmdline16, L"androidboot.force_normal_boot=1"); + if (EFI_ERROR(ret)) + goto out; + } #endif ret = prepend_command_line(&cmdline16, L"androidboot.acpi_idx=%a ", acpi_loaded_table_idx_to_string(BOOT_ACPI)); @@ -1710,18 +1713,18 @@ static EFI_STATUS setup_command_line( goto out; } - buf = get_boot_param_hdr(bootimage); - buf->hdr.cmd_line_ptr = (UINT32)(UINTN)cmdline; - ret = EFI_SUCCESS; + *cmdline_start = (EFI_PHYSICAL_ADDRESS)cmdline; + *cmdline_size = cmdsize; + ret = EFI_SUCCESS; out: - if (cmdline16) - FreePool(cmdline16); - if (cmd_conf) - FreePool(cmd_conf); - if (serialport) - FreePool(serialport); - if (time_str16) - FreePool(time_str16); + if (cmdline16) + FreePool(cmdline16); + if (cmd_conf) + FreePool(cmd_conf); + if (serialport) + FreePool(serialport); + if (time_str16) + FreePool(time_str16); if (EFI_ERROR(ret) && cmdline_addr) { if (is_uefi) { free_pages(cmdline_addr, EFI_SIZE_TO_PAGES(cmdsize)); @@ -1733,7 +1736,38 @@ static EFI_STATUS setup_command_line( if (f_bootreason) free_pool(f_bootreason); #endif - return ret; + + return ret; + +} + +/* when we call setup_command_line in EFI, parameter is EFI_GUID *swap_guid. + * when we call setup_command_line in NON EFI, parameter is const CHAR8 *abl_cmd_line. + * */ +static EFI_STATUS setup_command_line( + IN UINT8 *bootimage, + IN UINT8 *vendorbootimage, + IN enum boot_target boot_target, + IN void *parameter, + IN UINT8 boot_state, + IN VBDATA *vb_data, + OUT UINT8 **androidcmd) +{ + EFI_STATUS ret; + struct boot_params *buf; + EFI_PHYSICAL_ADDRESS cmdline_start; + UINTN cmdline_size; + + ret = parse_command_line(bootimage, vendorbootimage, boot_target, + parameter, boot_state, vb_data, androidcmd, + &cmdline_start, &cmdline_size); + if (EFI_ERROR(ret)) { + return ret; + } + + buf = get_boot_param_hdr(bootimage); + buf->hdr.cmd_line_ptr = (UINT32)cmdline_start; + return EFI_SUCCESS; } extern EFI_GUID GraphicsOutputProtocol; @@ -2083,23 +2117,11 @@ EFI_STATUS android_image_load_file( return ret; } - -EFI_STATUS android_image_start_buffer( - IN EFI_HANDLE parent_image, - IN VOID *bootimage, - IN VOID *vendorbootimage, - IN enum boot_target boot_target, - IN UINT8 boot_state, - IN __attribute__((unused)) EFI_GUID *swap_guid, - IN VBDATA *vb_data, - IN __attribute__((unused)) const CHAR8 *abl_cmd_line) +EFI_STATUS check_bootimage(IN VOID *bootimage, IN VOID *vendorbootimage) { struct boot_img_hdr *aosp_header; struct boot_params *buf; - void *parameter = NULL; - UINT8 *androidcmd= NULL; - EFI_STATUS ret; - BOOLEAN use_ramdisk = TRUE; + if (!bootimage) return EFI_INVALID_PARAMETER; @@ -2136,6 +2158,31 @@ EFI_STATUS android_image_start_buffer( return EFI_INVALID_PARAMETER; } + return EFI_SUCCESS; +} + +EFI_STATUS android_image_start_buffer( + IN EFI_HANDLE parent_image, + IN VOID *bootimage, + IN VOID *vendorbootimage, + IN enum boot_target boot_target, + IN UINT8 boot_state, + IN EFI_GUID *swap_guid, + IN VBDATA *vb_data, + IN const CHAR8 *abl_cmd_line) +{ + struct boot_params *buf; + void *parameter = NULL; + UINT8 *androidcmd= NULL; + EFI_STATUS ret; + BOOLEAN use_ramdisk = TRUE; + + ret = check_bootimage(bootimage, vendorbootimage); + if (EFI_ERROR(ret)) { + return ret; + } + buf = get_boot_param_hdr(bootimage); + debug(L"Creating command line"); if (is_UEFI()) parameter = (void *)swap_guid; @@ -2186,6 +2233,101 @@ EFI_STATUS android_image_start_buffer( return ret; } +EFI_STATUS load_kernel( + IN __attribute__((unused)) EFI_HANDLE parent_image, + IN VOID *bootimage, + IN VOID *vendorbootimage, + IN enum boot_target boot_target, + IN UINT8 boot_state, + IN EFI_GUID *swap_guid, + IN VBDATA *vb_data, + IN const CHAR8 *abl_cmd_line, + IN EFI_PHYSICAL_ADDRESS *kernel_start, IN UINTN *kernel_size, + IN EFI_PHYSICAL_ADDRESS *ramdisk_start, IN UINTN *ramdisk_size, + IN EFI_PHYSICAL_ADDRESS *cmdline_start, IN UINTN *cmdline_size) +{ + struct boot_img_hdr *aosp_header; + void *parameter = NULL; + UINT8 *androidcmd= NULL; + EFI_STATUS ret; + BOOLEAN use_ramdisk = TRUE; + + ret = check_bootimage(bootimage, vendorbootimage); + if (EFI_ERROR(ret)) { + return ret; + } + + debug(L"Creating command line"); + if (is_UEFI()) + parameter = (void *)swap_guid; + else + parameter = (void *)abl_cmd_line; + + ret = parse_command_line(bootimage, vendorbootimage, + boot_target, + parameter, + boot_state, + vb_data, + &androidcmd, + cmdline_start, + cmdline_size); + if (EFI_ERROR(ret)) { + efi_perror(ret, L"parse_command_line"); + if (androidcmd != NULL) + FreePool(androidcmd); + return ret; + } + debug(L"kernel cmdlen: %d", strnlen((CHAR8*)(*cmdline_start), *cmdline_size)); + + debug(L"Parsing ramdisk"); +#ifndef DYNAMIC_PARTITIONS + use_ramdisk = !recovery_in_boot_partition() || boot_target == RECOVERY || boot_target == MEMORY; +#endif + if (use_ramdisk) { + ret = parse_ramdisk(bootimage, vendorbootimage, androidcmd, ramdisk_start, ramdisk_size); + if (EFI_ERROR(ret)) { + efi_perror(ret, L"parse_ramdisk"); + if (androidcmd != NULL) + FreePool(androidcmd); + goto out_cmdline; + } + } + + if (androidcmd != NULL) + FreePool(androidcmd); + + /* acrn will not decompress it */ + debug(L"Loading kernel"); + EFI_PHYSICAL_ADDRESS buf; + VOID *kernel; + aosp_header = (struct boot_img_hdr *)bootimage; + /* need a copy? acrn will make a copy when loading */ + if (aosp_header->header_version < BOOT_HEADER_V3) + kernel = bootimage + aosp_header->page_size; + else + kernel = bootimage + BOOT_IMG_HEADER_SIZE_V3; + ret = emalloc(aosp_header->kernel_size, 2 *1024 *1024, &buf, FALSE); + if (EFI_ERROR(ret)) { + error(L"fail to allocate buffer to load bzImage"); + goto out_ramdisk; + } + memcpy((VOID *)buf, kernel, aosp_header->kernel_size); + *kernel_start = buf; + *kernel_size = aosp_header->kernel_size; + + return EFI_SUCCESS; +out_ramdisk: + efree(*ramdisk_start, *ramdisk_size); + *ramdisk_start = 0; + *ramdisk_size = 0; +out_cmdline: + free_pages(*cmdline_start, EFI_SIZE_TO_PAGES(*cmdline_size)); + *cmdline_start = 0; + *cmdline_size = 0; + return ret; + +} + #if DEBUG_MESSAGES VOID dump_bcb(IN struct bootloader_message *bcb) From 4c083e4a48abe658a1a6f820ead7d690ce9de1b4 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Wed, 6 Mar 2024 16:48:15 +0800 Subject: [PATCH 4/6] need refactor: handle acrn specific tweak on multiboot load The main multiboot2 module is acrn image, and associated cmdline is for both hypervisor and ServiceVM. Following modules are kernel, initrd and acpi blob for Pre-launched and Service VMs. The associated cmdline for each module begins with a tag defined by acrn so that acrn could known what it's for. TODO: Pass kernel/initrd multiboot tag from build system (which should match ACRN scenario.xml) to KF. Signed-off-by: Qiang Zhang --- include/acrn.h | 67 ++++++ libkernelflinger/acrn.c | 512 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 579 insertions(+) create mode 100644 include/acrn.h create mode 100644 libkernelflinger/acrn.c diff --git a/include/acrn.h b/include/acrn.h new file mode 100644 index 00000000..7cbddff3 --- /dev/null +++ b/include/acrn.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ACRN_H__ +#define __ACRN_H__ + +#include "multiboot.h" + +struct efi_memmap_info { + UINTN map_size; + UINTN map_key; + UINT32 desc_version; + UINTN desc_size; + EFI_MEMORY_DESCRIPTOR *mmap; +}; + +/* + * 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 "kernelflinger" +#define BOOT_LOADER_NAME_SIZE (strlen(BOOT_LOADER_NAME) + 1) +#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)) + + +EFI_STATUS acrn_mb2_add_kernel( + IN struct mb2_images *images, + IN EFI_PHYSICAL_ADDRESS kernel_start, + IN UINTN kernel_size, + IN EFI_PHYSICAL_ADDRESS cmdline_start, + IN UINTN cmdline_size, + IN EFI_PHYSICAL_ADDRESS ramdisk_start, + IN INTN ramdisk_size); + +/* Functions to load acrn multiboot2 image and modules. */ +EFI_STATUS acrn_image_start( + IN EFI_HANDLE parent_image, + IN struct mb2_images *images); + +#endif /* __ACRN_H__ */ diff --git a/libkernelflinger/acrn.c b/libkernelflinger/acrn.c new file mode 100644 index 00000000..f9fca625 --- /dev/null +++ b/libkernelflinger/acrn.c @@ -0,0 +1,512 @@ +#include +#include +#include + +#include "android.h" +#include "efilinux.h" +#include "lib.h" +#include "security.h" +#include "vars.h" +#include "power.h" +#include "targets.h" +#include "gpt.h" +#include "storage.h" +#include "text_parser.h" +#include "watchdog.h" +#ifdef HAL_AUTODETECT +#include "blobstore.h" +#endif +#include "slot.h" +#include "pae.h" +#include "timer.h" +#include "android_vb2.h" +#include "acpi.h" +#ifdef USE_FIRSTSTAGE_MOUNT +#include "firststage_mount.h" +#endif +#ifdef USE_TRUSTY +#include "trusty_common.h" +#endif + +#include "uefi_utils.h" +#include "libxbc.h" + +#include "acrn.h" + +#if 0 +static int mb2_images_add(struct mb2_images *images, + VOID *start, UINTN size, + CHAR8 *cmdline, UINTN cmdline_buf_size) +{ + if (images->cnt >= 15) { + error(L"too many multiboot images"); + return -1; + } + + images->mods[images->cnt].start = start; + images->mods[images->cnt].size = size; + images->mods[images->cnt].cmdline = cmdline; + images->mods[images->cnt].cmdline_buf_size = cmdline_buf_size; + images->cnt++; + return 0; +} +#endif + +static void mb2_images_dump(struct mb2_images *images) +{ + int i; + struct mb2_module *mod; + CHAR16* str; + + for(i = 0; i < images->cnt; i++) { + mod = &images->mods[i]; + str = stra_to_str(mod->cmdline); + debug(L"Image%d, start: 0x%lx, size: 0x%lx, cmdlen: %d, cmdline: %s", + i, mod->start, mod->size, strnlen(mod->cmdline, mod->cmdline_buf_size), str); + } +} + +EFI_STATUS acrn_mb2_add_kernel( + IN struct mb2_images *images, + IN EFI_PHYSICAL_ADDRESS kernel_start, + IN UINTN kernel_size, + IN EFI_PHYSICAL_ADDRESS cmdline_start, + IN UINTN cmdline_size, + IN EFI_PHYSICAL_ADDRESS ramdisk_start, + IN INTN ramdisk_size) +{ + EFI_STATUS ret; + EFI_PHYSICAL_ADDRESS tag_buf; + + if (images->cnt >= 14) + return EFI_OUT_OF_RESOURCES; + + /* append kernel cmdline to acrn cmdline line */ + struct mb2_module *acrn = &images->mods[0]; + UINTN cur_len = strnlen(acrn->cmdline, acrn->cmdline_buf_size); + UINTN kernel_cmdlen = strnlen((char*)cmdline_start, cmdline_size); + acrn->cmdline[cur_len] = ' '; + cur_len ++; + if (acrn->cmdline_buf_size < cur_len + kernel_cmdlen) { + error(L"acrn cmdline buffer is to small to hold kernel cmdline"); + } + memcpy_s(acrn->cmdline + cur_len, acrn->cmdline_buf_size - cur_len, + (VOID *)cmdline_start, kernel_cmdlen); + free_pages(cmdline_start, EFI_SIZE_TO_PAGES(cmdline_size)); + + ret = emalloc(4096, 4, &tag_buf, FALSE); + if (EFI_ERROR(ret)) + return ret; + + /* bzImage multiboot2 mod */ + CHAR8 *tag = "asos_bzimage"; + UINTN tag_size = strlen(tag); + images->mods[images->cnt].start = (VOID *)kernel_start; + images->mods[images->cnt].size = kernel_size; + images->mods[images->cnt].cmdline = (CHAR8 *)tag_buf; + images->mods[images->cnt].cmdline_buf_size = 2048; + memcpy_s((VOID *)tag_buf, 2048, tag, tag_size); + *((CHAR8*)tag_buf + tag_size) = '\0'; + images->cnt++; + + /* ramdisk mod */ + tag = "asos_ramdisk"; + tag_size = strlen(tag); + images->mods[images->cnt].start = (VOID *)ramdisk_start; + images->mods[images->cnt].size = ramdisk_size; + images->mods[images->cnt].cmdline = (CHAR8*)(tag_buf + 2048); + images->mods[images->cnt].cmdline_buf_size = 2048; + memcpy_s((VOID *)(tag_buf + 2048), 2048, tag, tag_size); + *((CHAR8*)tag_buf + 2048 + tag_size) = '\0'; + images->cnt++; + + return EFI_SUCCESS; +} + +static 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 UINT32 calc_mbi_size(struct mb2_images *images, + struct efi_memmap_info *emi, UINT32 sorted_mmap_cnt, UINT32 rsdp_len) +{ + uint32_t allmods_len = 0; + int i; + for(i = 1; i < images->cnt; i++) { + allmods_len += ALIGN_UP(sizeof(struct multiboot2_tag_module) + strnlen(images->mods[i].cmdline, images->mods[i].cmdline_buf_size) + 1, MULTIBOOT2_TAG_ALIGN); /* tailing '\0' */ + } + + return 2 * sizeof(uint32_t) \ + /* Boot command line */ + + ALIGN_UP(sizeof(struct multiboot2_tag_string) + strnlen(images->mods[0].cmdline, images->mods[0].cmdline_buf_size) + 1, MULTIBOOT2_TAG_ALIGN) \ + + /* Boot loader name */ + + ALIGN_UP(sizeof(struct multiboot2_tag_string) + BOOT_LOADER_NAME_SIZE, MULTIBOOT2_TAG_ALIGN) \ + + /* Modules */ + + allmods_len \ + + /* Memory Map */ + + ALIGN_UP((sizeof(struct multiboot2_tag_mmap) + sorted_mmap_cnt * sizeof(struct multiboot2_mmap_entry)), MULTIBOOT2_TAG_ALIGN) \ + + /* ACPI new */ + + ALIGN_UP(sizeof(struct multiboot2_tag_new_acpi) + rsdp_len, MULTIBOOT2_TAG_ALIGN) \ + + /* EFI64 system table */ + + ALIGN_UP(sizeof(struct multiboot2_tag_efi64), MULTIBOOT2_TAG_ALIGN) \ + + /* EFI memmap: Add an extra page since UEFI can alter the memory map */ + + ALIGN_UP(sizeof(struct multiboot2_tag_efi_mmap) + ALIGN_UP(emi->map_size + 0x1000, 0x1000), MULTIBOOT2_TAG_ALIGN) \ + + /* END */ + + ALIGN_UP(sizeof(struct multiboot2_tag), MULTIBOOT2_TAG_ALIGN); +} + +#define E820_UNDEFINED 0 +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 +#define E820_UNUSABLE 5 + +UINT32 efimmap_to_mb2( + struct efi_memmap_info *emi, + struct multiboot2_mmap_entry *sorted, + UINT32 len) +{ + UINT32 i, j, k, sorted_len = 0; + for (i = 0; i < emi->map_size/emi->desc_size; i++) { + uint32_t e820_type = 0; + EFI_MEMORY_DESCRIPTOR *d = (EFI_MEMORY_DESCRIPTOR *)((UINT64)emi->mmap + i * emi->desc_size); + + switch(d->Type) { + case EfiReservedMemoryType: + case EfiRuntimeServicesCode: + case EfiRuntimeServicesData: + case EfiMemoryMappedIO: + case EfiMemoryMappedIOPortSpace: + case EfiPalCode: + e820_type = E820_RESERVED; + break; + + case EfiUnusableMemory: + e820_type = E820_UNUSABLE; + break; + + case EfiACPIReclaimMemory: + e820_type = E820_ACPI; + break; + + case EfiLoaderCode: + case EfiLoaderData: + case EfiBootServicesCode: + case EfiBootServicesData: + case EfiConventionalMemory: + e820_type = E820_RAM; + break; + + case EfiACPIMemoryNVS: + e820_type = E820_NVS; + break; + + default: + error(L"unknown efi mmap type"); + ;//possible ? + } + struct multiboot2_mmap_entry e; + e.addr = d->PhysicalStart; + e.len = d->NumberOfPages << EFI_PAGE_SHIFT; + e.type = e820_type; + e.zero = 0; + + for (j = 0; j < sorted_len; j++) { + if (e.addr < sorted[j].addr) { + for (k = sorted_len; k > j; k--) { + sorted[k] = sorted[k-1]; + } + sorted[j] = e; + sorted_len++; + break; + } + } + if (j == sorted_len) { + sorted[sorted_len++] = e; + } + if (sorted_len > len) { + error(L"should panic"); + break; + } + } + for (i = sorted_len - 1; i > 0; i--) { + if ((sorted[i].type == sorted[i-1].type) && (sorted[i-1].addr + sorted[i-1].len >= sorted[i].addr)) { + sorted[i-1].len += sorted[i].len; + for (j = i; j < sorted_len -1; j++) { + sorted[j] = sorted[j+1]; + } + sorted_len--; + } + } + for (i = 0; i < sorted_len; i++) { + debug(L"mmap entry: addr: 0x%lx, len: 0x%lx, type: %d", + sorted[i].addr, sorted[i].len, sorted[i].type); + } + return sorted_len; + +} +static EFI_STATUS construct_mbi2( + struct mb2_images *images, + EFI_PHYSICAL_ADDRESS *pmbi) +{ + EFI_STATUS ret; + struct RSDP_TABLE *rsdp; + VOID *mbi; + UINT32 mbi_size, mmap_cnt, sorted_mmap_cnt; + struct efi_memmap_info emi; + struct multiboot2_mmap_entry *sorted_mmap_entries; + + ret = get_acpi_rsdp((VOID **)&rsdp); + if (EFI_ERROR(ret)) { + error(L"fail to get rsdp"); + return ret; + } + + ret = get_efi_memmap(&emi, 0); + if (EFI_ERROR(ret)) { + error(L"fail to get efi memmap"); + return ret; + } + + mmap_cnt = emi.map_size / emi.desc_size; + ret = allocate_pool(EfiLoaderData, mmap_cnt * sizeof(struct multiboot2_mmap_entry), (void **)&sorted_mmap_entries); + if (EFI_ERROR(ret)) { + error(L"fail to alloc buffer for MB2 mmap"); + return ret; + } + sorted_mmap_cnt = efimmap_to_mb2(&emi, sorted_mmap_entries, mmap_cnt); + mbi_size = calc_mbi_size(images, &emi, sorted_mmap_cnt, rsdp->length); + /* This allocation is guaranteed to be 8-bytes aligned */ + ret = allocate_pool(EfiLoaderData, mbi_size, (void **) &mbi); + if (EFI_ERROR(ret)) { + error(L"fail to alloc buffer for MBI"); + return ret; + } + memset(mbi, 0, mbi_size); + + UINT64 *p = mbi; + p += (2 * sizeof(UINT32)) / sizeof(UINT64); + + /* TODO setup MBI per image's request */ + /* Boot command line */ + { + struct multiboot2_tag_string *tag = (struct multiboot2_tag_string *)p; + UINTN cmdline_size = strnlen(images->mods[0].cmdline, images->mods[0].cmdline_buf_size) + 1; + tag->type = MULTIBOOT2_TAG_TYPE_CMDLINE; + tag->size = sizeof(struct multiboot2_tag_string) + cmdline_size; + memcpy(tag->string, images->mods[0].cmdline, cmdline_size); + p += ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / sizeof(uint64_t); + } + + /* Boot loader name */ + { + struct multiboot2_tag_string *tag = (struct multiboot2_tag_string *)p; + tag->type = MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME; + tag->size = sizeof(struct multiboot2_tag_string) + BOOT_LOADER_NAME_SIZE; + memcpy(tag->string, BOOT_LOADER_NAME, BOOT_LOADER_NAME_SIZE); + p += ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / sizeof(uint64_t); + } + + /* Modules */ + { + unsigned i; + uint32_t mod_count = images->cnt; + for (i = 1; i < mod_count; i++) { + struct mb2_module *mod = &images->mods[i]; + struct multiboot2_tag_module *tag = (struct multiboot2_tag_module *)p; + tag->type = MULTIBOOT2_TAG_TYPE_MODULE; + tag->size = sizeof(struct multiboot2_tag_module) + strnlen(mod->cmdline, mod->cmdline_buf_size) + 1; + tag->mod_start = (uint32_t)mod->start; + tag->mod_end = tag->mod_start + mod->size; + memcpy(tag->cmdline, mod->cmdline, strnlen(mod->cmdline, mod->cmdline_buf_size) + 1); + p += ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / sizeof(uint64_t); + } + } + + /* Memory map */ + { + struct multiboot2_tag_mmap *tag = (struct multiboot2_tag_mmap *)p; + tag->type = MULTIBOOT2_TAG_TYPE_MMAP; + tag->size = sizeof(struct multiboot2_tag_mmap) + sizeof(struct multiboot2_mmap_entry) * sorted_mmap_cnt; + tag->entry_size = sizeof(struct multiboot2_mmap_entry); + tag->entry_version = 0; + memcpy(tag->entries, sorted_mmap_entries, sorted_mmap_cnt * sizeof(struct multiboot2_mmap_entry)); + p += ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / sizeof(uint64_t); + } + + /* ACPI new */ + { + struct multiboot2_tag_new_acpi *tag = (struct multiboot2_tag_new_acpi *)p; + tag->type = MULTIBOOT2_TAG_TYPE_ACPI_NEW; + tag->size = sizeof(struct multiboot2_tag_new_acpi) + rsdp->length; + memcpy((char *)tag->rsdp, (char *)rsdp, rsdp->length); + p += ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / sizeof(uint64_t); + } + + /* EFI64 system table */ + { + struct multiboot2_tag_efi64 *tag = (struct multiboot2_tag_efi64 *)p; + tag->type = MULTIBOOT2_TAG_TYPE_EFI64; + tag->size = sizeof(struct multiboot2_tag_efi64); + tag->pointer = (uint64_t)ST; + p += ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / sizeof(uint64_t); + } + + /* EFI memory map */ + { + struct multiboot2_tag_efi_mmap *tag = (struct multiboot2_tag_efi_mmap *)p; + tag->type = MULTIBOOT2_TAG_TYPE_EFI_MMAP; + tag->size = sizeof(struct multiboot2_tag_efi_mmap) + emi.map_size; + tag->descr_size = emi.desc_size; + tag->descr_vers = emi.desc_version; + memcpy((char *)tag->efi_mmap, (char *)emi.mmap, emi.map_size); + p += ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / sizeof(uint64_t); + } + + /* END */ + { + struct multiboot2_tag *tag = (struct multiboot2_tag *)p; + tag->type = MULTIBOOT2_TAG_TYPE_END; + tag->size = sizeof(struct multiboot2_tag); + p += ALIGN_UP(tag->size, MULTIBOOT2_TAG_ALIGN) / sizeof(uint64_t); + } + + ((uint32_t *)mbi)[0] = (uint64_t)((char *)p - (char *)mbi); + ((uint32_t *)mbi)[1] = 0; + + *pmbi = (EFI_PHYSICAL_ADDRESS)mbi; + + return EFI_SUCCESS; +} + +static EFI_STATUS get_mb2_entry(struct mb2_images *images, EFI_PHYSICAL_ADDRESS *entry) +{ + VOID *acrn = images->mods[0].start; + const struct multiboot2_header *mb2header = find_mb2header((uint8_t *)acrn, 4096); + struct mb2header_tag_list tags; + int ret = parse_mb2header(mb2header, &tags); + if (ret) { + error(L"fail to parse multiboot2 header of acrn image"); + return EFI_INVALID_PARAMETER; + } + struct multiboot2_header_tag_address *addr_tag = tags.addr; + struct multiboot2_header_tag_entry_address *entry_tag = tags.entry; + *entry = (EFI_PHYSICAL_ADDRESS)acrn + entry_tag->entry_addr - addr_tag->load_addr; + + return EFI_SUCCESS; +} + +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 acrn_image_start( + IN EFI_HANDLE parent_image, + IN struct mb2_images *images) +{ + EFI_STATUS ret; + EFI_PHYSICAL_ADDRESS mbi, acrn_entry; + UINTN nr_entries, entry_sz, key; + UINT32 entry_ver; + EFI_MEMORY_DESCRIPTOR *mem_entries; + + mb2_images_dump(images); + + ret = construct_mbi2(images, &mbi); + if (EFI_ERROR(ret)) + return ret; + debug(L"constructed mbi at 0x%lx", mbi); + + debug(L"exit boot services"); + mem_entries = LibMemoryMap(&nr_entries, &key, &entry_sz, &entry_ver); + if (!mem_entries) { + error(L"fail to get memmap to exit bootservice"); + return EFI_OUT_OF_RESOURCES; + } + FreePool(mem_entries); + ret = uefi_call_wrapper(BS->ExitBootServices, 2, parent_image, key); + if (!EFI_ERROR(ret)) { + error(L"fail to exit bootservice"); + return ret; + } + + ret = get_mb2_entry(images, &acrn_entry); + if (EFI_ERROR(ret)) { + error(L"fail to get acrn entry point"); + return ret; + } + debug(L"jump to acrn entrypint at 0x%lx", acrn_entry); + hv_jump(acrn_entry, (uint32_t)mbi, MULTIBOOT2_INFO_MAGIC); + + return ret; +} + + From 225b4d0013444464c18bf468056b6f5382bde64a Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Wed, 6 Mar 2024 16:50:48 +0800 Subject: [PATCH 5/6] add ACRN boot policy Signed-off-by: Qiang Zhang --- Android.mk | 4 ++ include/targets.h | 4 +- kernelflinger.c | 102 ++++++++++++++++++++++++++++++++++-- libkernelflinger/Android.mk | 2 + 4 files changed, 108 insertions(+), 4 deletions(-) diff --git a/Android.mk b/Android.mk index f12e51d7..448e910a 100644 --- a/Android.mk +++ b/Android.mk @@ -30,6 +30,10 @@ ifeq ($(TARGET_USE_SBL),true) KERNELFLINGER_CFLAGS += -DUSE_SBL endif +ifeq ($(TARGET_USE_ACRN),true) + KERNELFLINGER_CFLAGS += -DUSE_ACRN -DMB2_PARTS=\"$(MB2_PARTS)\" +endif + ifeq ($(TARGET_USE_TRUSTY),true) KERNELFLINGER_CFLAGS += -DUSE_TRUSTY endif diff --git a/include/targets.h b/include/targets.h index b64786e6..0e92bf8d 100644 --- a/include/targets.h +++ b/include/targets.h @@ -50,7 +50,9 @@ enum boot_target { MEMORY, CHARGER, POWER_OFF, - EXIT_SHELL + EXIT_SHELL, + ASOS, + MAX_BOOT_TARGET, }; #define is_bootimg_target(target) \ diff --git a/kernelflinger.c b/kernelflinger.c index 2744162e..87994aa7 100644 --- a/kernelflinger.c +++ b/kernelflinger.c @@ -79,6 +79,7 @@ BOOLEAN andr_tpm = true; #else BOOLEAN andr_tpm = false; #endif +#include "acrn.h" /* Ensure this is embedded in the EFI binary somewhere */ static const CHAR16 __attribute__((used)) magic[] = L"### kernelflinger ###"; @@ -1057,6 +1058,7 @@ static EFI_STATUS avb_load_verify_boot_image( EFI_STATUS ret; switch (boot_target) { + case ASOS: case NORMAL_BOOT: case CHARGER: if (!slot_data) { @@ -1118,6 +1120,7 @@ static EFI_STATUS avb_load_verify_vendor_boot_image( AvbSlotVerifyData *slot_data; switch (boot_target) { + case ASOS: case NORMAL_BOOT: case CHARGER: case RECOVERY: @@ -1135,6 +1138,50 @@ static EFI_STATUS avb_load_verify_vendor_boot_image( } +/* Use AVB load and verify multiboot2 images into RAM. + * + * boot_target - Boot image to load. Values supported are ASOS so far. + * images - loaded multiboot2 images for acrn and Prelaunched VMs. + * + * Return values: + * EFI_INVALID_PARAMETER - Unsupported boot target type, key is not well-formed, + * or loaded acrn image was missing or corrupt + * EFI_ACCESS_DENIED - Validation failed against OEM or embedded certificate, + * acrn image still usable + */ +EFI_STATUS avb_load_verify_mb2_images( + IN enum boot_target boot_target, + IN struct mb2_images *images) +{ + UINT8 boot_state; + AvbSlotVerifyData *slot_data; // TODO take care for production + struct mb2_image_header *hdr; + EFI_STATUS ret; + CHAR8 *image_names = MB2_PARTS; + + images->cnt = 0; + CHAR16* str = stra_to_str(image_names); + info(L"Multiboot2 Images: %s", str); + FreePool(str); + + if (boot_target == ASOS) { + ret = android_image_load_partition_avb_ab("acrn", (void **)&hdr, &boot_state, &slot_data); + if (EFI_ERROR(ret)) { + error(L"fail to load acrn partition"); + return ret; + } + dump_mb2_partition(hdr); + images->headers[images->cnt] = hdr; + images->names[images->cnt] = "acrn"; + images->cnt++; + + /* TODO add pre launch vms components */ + return EFI_SUCCESS; + } else { + return EFI_INVALID_PARAMETER; + } +} + #define OEMVARS_MAGIC "#OEMVARS\n" #define OEMVARS_MAGIC_SZ 9 @@ -1183,7 +1230,8 @@ static EFI_STATUS set_image_oemvars(VOID *bootimage) return set_image_oemvars_nocheck(bootimage, NULL); } -static EFI_STATUS load_image(VOID *bootimage, VOID *vendorbootimage, UINT8 boot_state, +static EFI_STATUS load_image(struct mb2_images *images, VOID *bootimage, + VOID *vendorbootimage, UINT8 boot_state, enum boot_target boot_target, VBDATA *vb_data ) @@ -1273,6 +1321,35 @@ static EFI_STATUS load_image(VOID *bootimage, VOID *vendorbootimage, UINT8 boot_ else if (andr_tpm) tpm2_end(); +#ifdef USE_ACRN + if (boot_target == ASOS) { + ret = load_mb2_images(images); + if (EFI_ERROR(ret)) + goto failed; + + EFI_PHYSICAL_ADDRESS kernel_start, cmdline_start, ramdisk_start; + UINTN kernel_size, cmdline_size, ramdisk_size; + ret = load_kernel(g_parent_image, bootimage, + vendorbootimage, boot_target, boot_state, NULL, + vb_data, NULL, &kernel_start, &kernel_size, + &ramdisk_start, &ramdisk_size, &cmdline_start, + &cmdline_size); + if (EFI_ERROR(ret)) + goto failed; + + /* add kernel and ramdisk as multiboot2 modules */ + acrn_mb2_add_kernel(images, kernel_start, kernel_size, + cmdline_start, cmdline_size, + ramdisk_start, ramdisk_size); + + debug(L"chainloading acrn image, boot state is %s", boot_state_to_string(boot_state)); + ret = acrn_image_start(g_parent_image, images); + if (EFI_ERROR(ret)) + efi_perror(ret, L"Couldn't load acrn image"); + + } else +#endif + { debug(L"chainloading boot image, boot state is %s", boot_state_to_string(boot_state)); ret = android_image_start_buffer(g_parent_image, bootimage, vendorbootimage, @@ -1281,7 +1358,9 @@ static EFI_STATUS load_image(VOID *bootimage, VOID *vendorbootimage, UINT8 boot_ cmd_buf); if (EFI_ERROR(ret)) efi_perror(ret, L"Couldn't load Boot image"); + } +failed: ret = slot_boot_failed(boot_target); if (EFI_ERROR(ret)) efi_perror(ret, L"Failed to write slot failure"); @@ -1373,7 +1452,7 @@ static VOID enter_fastboot_mode(UINT8 boot_state) if (EFI_ERROR(ret)) efi_perror(ret, L"Fastboot mode fail to load slot data"); set_image_oemvars_nocheck(bootimage, NULL); - load_image(bootimage, NULL, BOOT_STATE_ORANGE, NORMAL_BOOT, slot_data); + load_image(NULL, bootimage, NULL, BOOT_STATE_ORANGE, NORMAL_BOOT, slot_data); } FreePool(bootimage); bootimage = NULL; @@ -1505,6 +1584,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) #ifdef __CRASH_DUMP EFI_GUID dump_partition = { 0xCAB9B00C, 0xCC1B, 0x4C0F, {0xB9, 0x32, 0x82, 0x92, 0x0D, 0xA5, 0x22, 0x51} }; #endif + struct mb2_images mb2_images; + memset(&mb2_images, 0, sizeof(struct mb2_images)); set_boottime_stamp(TM_EFI_MAIN); /* gnu-efi initialization */ @@ -1642,6 +1723,11 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) if (boot_target == DNX || boot_target == CRASHMODE) reboot_to_target(boot_target, EfiResetCold); +#ifdef USE_ACRN + if (boot_target == NORMAL_BOOT) + boot_target = ASOS; +#endif + #ifdef USERDEBUG debug(L"checking device state"); @@ -1713,6 +1799,10 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) disable_slot_if_efi_loaded_slot_failed(); ret = avb_load_verify_boot_image(boot_target, target_path, &bootimage, oneshot, &boot_state, &vb_data); avb_load_verify_vendor_boot_image(boot_target, &vendorbootimage); +#ifdef USE_ACRN + /* just verify images paritions, will load images later */ + avb_load_verify_mb2_images(boot_target, &mb2_images); +#endif set_boottime_stamp(TM_VERIFY_BOOT_DONE); @@ -1734,6 +1824,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) set_image_oemvars_nocheck(bootimage, NULL); set_oemvars_update(TRUE); break; +#ifdef USE_ACRN + case ASOS: +#endif case NORMAL_BOOT: case CHARGER: set_image_oemvars(bootimage); @@ -1742,13 +1835,16 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) break; } - ret = load_image(bootimage, vendorbootimage, boot_state, boot_target, + ret = load_image(&mb2_images, bootimage, vendorbootimage, boot_state, boot_target, vb_data ); if (EFI_ERROR(ret)) efi_perror(ret, L"Failed to start boot image"); switch (boot_target) { +#ifdef USE_ACRN + case ASOS: +#endif case NORMAL_BOOT: case CHARGER: if (slot_get_active()) diff --git a/libkernelflinger/Android.mk b/libkernelflinger/Android.mk index 584638e4..aa0ec6c3 100755 --- a/libkernelflinger/Android.mk +++ b/libkernelflinger/Android.mk @@ -97,6 +97,7 @@ ifeq ($(MULTI_USER_SUPPORT),true) endif LOCAL_SRC_FILES := \ + acrn.c \ android.c \ efilinux.c \ acpi.c \ @@ -111,6 +112,7 @@ LOCAL_SRC_FILES := \ storage.c \ pci.c \ mmc.c \ + multiboot.c \ ufs.c \ sdcard.c \ sdio.c \ From ae955125df1832011db6937f14b170d62cd7a83e Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Wed, 6 Mar 2024 16:51:37 +0800 Subject: [PATCH 6/6] TODO : AVB check on acrn partitions Signed-off-by: Qiang Zhang --- libkernelflinger/android_vb2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libkernelflinger/android_vb2.c b/libkernelflinger/android_vb2.c index c72c46d5..19f7e0db 100644 --- a/libkernelflinger/android_vb2.c +++ b/libkernelflinger/android_vb2.c @@ -416,6 +416,8 @@ EFI_STATUS android_image_load_partition_avb_ab( #endif #ifdef USE_ACPIO "acpio", +#endif +#ifdef USE_ACRN #endif NULL}; bool allow_verification_error = device_is_unlocked();