mirror of https://github.com/wolfSSL/wolfBoot.git
support booting EFI application on x86_64 architecture
Co-authored-by: Daniele Lacamera <daniele@wolfssl.com>pull/156/head
parent
62132201bf
commit
a187442455
|
@ -37,6 +37,7 @@
|
|||
*.hex
|
||||
*.rom
|
||||
*.bin
|
||||
*.efi
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
|
|
25
Makefile
25
Makefile
|
@ -39,10 +39,12 @@ CFLAGS+= \
|
|||
-D"PLATFORM_$(TARGET)"
|
||||
|
||||
# Setup default optimizations (for GCC)
|
||||
ifeq ($(USE_GCC),1)
|
||||
CFLAGS+=-Wall -Wextra -Wno-main -ffreestanding -Wno-unused -nostartfiles
|
||||
CFLAGS+=-ffunction-sections -fdata-sections
|
||||
LDFLAGS+=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=wolfboot.map -ffreestanding -nostartfiles
|
||||
ifneq ($(TARGET),x86_64_efi)
|
||||
ifeq ($(USE_GCC),1)
|
||||
CFLAGS+=-Wall -Wextra -Wno-main -ffreestanding -Wno-unused -nostartfiles
|
||||
CFLAGS+=-ffunction-sections -fdata-sections
|
||||
LDFLAGS+=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=wolfboot.map -ffreestanding -nostartfiles
|
||||
endif
|
||||
endif
|
||||
|
||||
MAIN_TARGET=factory.bin
|
||||
|
@ -52,12 +54,27 @@ ifeq ($(TARGET),stm32l5)
|
|||
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),x86_64_efi)
|
||||
MAIN_TARGET:=wolfboot.efi
|
||||
endif
|
||||
|
||||
ASFLAGS:=$(CFLAGS)
|
||||
|
||||
BOOTLOADER_PARTITION_SIZE?=$$(( $(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET)))
|
||||
|
||||
all: $(MAIN_TARGET)
|
||||
|
||||
wolfboot.efi: wolfboot.elf
|
||||
@echo "\t[BIN] $@"
|
||||
$(Q)$(OBJCOPY) -j .text -j .sdata -j .data \
|
||||
-j .dynamic -j .dynsym -j .rel \
|
||||
-j .rela -j .reloc -j .eh_frame \
|
||||
--target=efi-app-x86_64 --subsystem=10 $^ $@
|
||||
@echo
|
||||
@echo "\t[SIZE]"
|
||||
$(Q)$(SIZE) wolfboot.efi
|
||||
@echo
|
||||
|
||||
wolfboot.bin: wolfboot.elf
|
||||
@echo "\t[BIN] $@"
|
||||
$(Q)$(OBJCOPY) -O binary $^ $@
|
||||
|
|
22
arch.mk
22
arch.mk
|
@ -21,6 +21,13 @@ UART_TARGET=$(TARGET)
|
|||
# Include SHA256 module because it's implicitly needed by RSA
|
||||
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/sha256.o
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
OBJS+=src/boot_x86_64.o
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS+=-DWOLFBOOT_DEBUG_EFI=1
|
||||
endif
|
||||
endif
|
||||
|
||||
## ARM
|
||||
ifeq ($(ARCH),AARCH64)
|
||||
CROSS_COMPILE:=aarch64-none-elf-
|
||||
|
@ -299,6 +306,21 @@ ifeq ($(USE_GCC),1)
|
|||
OUTPUT_FLAG=-o
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(TARGET),x86_64_efi)
|
||||
GNU_EFI_LIB_PATH?=/usr/lib
|
||||
GNU_EFI_CRT0=$(GNU_EFI_LIB_PATH)/crt0-efi-x86_64.o
|
||||
GNU_EFI_LSCRIPT=$(GNU_EFI_LIB_PATH)/elf_x86_64_efi.lds
|
||||
CFLAGS += -fpic -ffreestanding -fno-stack-protector -fno-stack-check \
|
||||
-fshort-wchar -mno-red-zone -maccumulate-outgoing-args
|
||||
CFLAGS += -I/usr/include/efi -DPLATFORM_X86_64_EFI
|
||||
LDFLAGS = -shared -Bsymbolic -L/usr/lib -T$(GNU_EFI_LSCRIPT)
|
||||
LD_START_GROUP = $(GNU_EFI_CRT0)
|
||||
LD_END_GROUP = -lgnuefi -lefi
|
||||
LD = ld
|
||||
UPDATE_OBJS:=src/update_ram.o
|
||||
endif
|
||||
|
||||
BOOT_IMG?=test-app/image.bin
|
||||
|
||||
## Update mechanism
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
ARCH=x86_64
|
||||
TARGET=x86_64_efi
|
||||
WOLFBOOT_SMALL_STACK=1
|
||||
SIGN?=ED25519
|
||||
HASH?=SHA256
|
||||
IMAGE_HEADER_SIZE?=0x100
|
||||
DEBUG=0
|
||||
SPMATH=0
|
|
@ -21,6 +21,7 @@ This README describes configuration of supported targets.
|
|||
* [STM32WB55](#stm32wb55)
|
||||
* [TI Hercules TMS570LC435](#ti-hercules-tms570lc435)
|
||||
* [Xilinx Zynq UltraScale](#xilinx-zynq-ultrascale)
|
||||
* [Qemu x86_64 UEFI](#qemu-x86_64-uefi)
|
||||
|
||||
## STM32F4
|
||||
|
||||
|
@ -930,3 +931,52 @@ to compile.
|
|||
## TI Hercules TMS570LC435
|
||||
|
||||
See [/config/examples/ti-tms570lc435.config](/config/examples/ti-tms570lc435.config) for example configuration.
|
||||
|
||||
|
||||
## Qemu x86-64 UEFI
|
||||
|
||||
x86-64bit machine with UEFI bios can run wolfBoot as EFI application.
|
||||
|
||||
### Prerequisites:
|
||||
|
||||
* qemu-system-x86_64
|
||||
* [GNU-EFI] (https://sourceforge.net/projects/gnu-efi/)
|
||||
* Open Virtual Machine firmware bios images (OVMF) by [Tianocore](https://tianocore.org)
|
||||
|
||||
On a debian-like system it is sufficient to install the packages as follows:
|
||||
|
||||
`apt install qemu ovmf gnu-efi`
|
||||
|
||||
### Configuration
|
||||
|
||||
An example configuration is provided in [config/examples/x86_64_efi.config](config/examples/x86_64_efi.config)
|
||||
|
||||
### Building and running on qemu
|
||||
|
||||
The bootloader and the initialization script `startup.nsh` for execution in the EFI environment are stored in a loopback FAT partition.
|
||||
|
||||
The script [tools/efi/prepare_uefi_partition.sh](tools/efi/prepare_uefi_partition.sh) creates a new empty
|
||||
FAT loopback partitions and adds `startup.nsh`.
|
||||
|
||||
A kernel with an embedded rootfs partition can be now created and added to the image, via the
|
||||
script [tools/efi/compile_efi_linux.sh](tools/efi/compile_efi_linux.sh). The script actually adds two instances
|
||||
of the target systems: `kernel.img` and `update.img`, both signed for authentication, and tagged with version
|
||||
`1` and `2` respectively.
|
||||
|
||||
Compiling with `make` will produce the bootloader image in `wolfboot.efi`.
|
||||
|
||||
|
||||
The script [tools/efi/run_efi.sh](tools/efi/run_efi.sh) will add `wolfboot.efi` to the bootloader loopback
|
||||
partition, and run the system on qemu. If both kernel images are present and valid, wolfBoot will choose the image
|
||||
with the higher version number, so `update.img` will be staged as it's tagged with version `2`.
|
||||
|
||||
The sequence is summarized below:
|
||||
|
||||
```
|
||||
cp config/examples/x86_64_efi.config .config
|
||||
tools/efi/prepare_efi_partition.sh
|
||||
make
|
||||
tools/efi/compile_efi_linux.sh
|
||||
tools/efi/run_efi.sh
|
||||
```
|
||||
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
|
||||
/* x86_64_efi.c
|
||||
*
|
||||
* Copyright (C) 2021 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <target.h>
|
||||
|
||||
#include "image.h"
|
||||
#include "loader.h"
|
||||
#include "printf.h"
|
||||
|
||||
#ifdef PLATFORM_X86_64_EFI
|
||||
|
||||
#include <efi/efi.h>
|
||||
#include <efi/efilib.h>
|
||||
|
||||
#ifdef __WOLFBOOT
|
||||
void hal_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void hal_prepare_boot(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
#define EFI_DEVICE_PATH_PROTOCOL_HW_TYPE 0x01
|
||||
#define EFI_DEVICE_PATH_PROTOCOL_MEM_SUBTYPE 0x03
|
||||
|
||||
static EFI_SYSTEM_TABLE *gSystemTable;
|
||||
static EFI_HANDLE *gImageHandle;
|
||||
EFI_PHYSICAL_ADDRESS kernel_addr;
|
||||
EFI_PHYSICAL_ADDRESS update_addr;
|
||||
|
||||
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RAMFUNCTION hal_flash_unlock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void RAMFUNCTION hal_flash_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void panic()
|
||||
{
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
void RAMFUNCTION x86_64_efi_do_boot(uint8_t *kernel)
|
||||
{
|
||||
MEMMAP_DEVICE_PATH mem_path_device[2];
|
||||
EFI_HANDLE kernelImageHandle;
|
||||
EFI_STATUS status;
|
||||
uint32_t *size;
|
||||
|
||||
size = (uint32_t *)(kernel + 4);
|
||||
kernel += IMAGE_HEADER_SIZE;
|
||||
|
||||
mem_path_device->Header.Type = EFI_DEVICE_PATH_PROTOCOL_HW_TYPE;
|
||||
mem_path_device->Header.SubType = EFI_DEVICE_PATH_PROTOCOL_MEM_SUBTYPE;
|
||||
mem_path_device->MemoryType = EfiLoaderData;
|
||||
mem_path_device->StartingAddress = (EFI_PHYSICAL_ADDRESS)kernel;
|
||||
mem_path_device->EndingAddress = (EFI_PHYSICAL_ADDRESS)(kernel+*size);
|
||||
SetDevicePathNodeLength(&mem_path_device->Header,
|
||||
sizeof(MEMMAP_DEVICE_PATH));
|
||||
|
||||
SetDevicePathEndNode(&mem_path_device[1].Header);
|
||||
|
||||
wolfBoot_printf("Staging kernel at address %x, size: %u\n", kernel, *size);
|
||||
status = uefi_call_wrapper(gSystemTable->BootServices->LoadImage,
|
||||
6,
|
||||
0, /* bool */
|
||||
gImageHandle,
|
||||
(EFI_DEVICE_PATH*)mem_path_device,
|
||||
kernel,
|
||||
*size,
|
||||
&kernelImageHandle);
|
||||
if (status != EFI_SUCCESS) {
|
||||
wolfBoot_printf("can't load kernel image from memory\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
status = uefi_call_wrapper(gSystemTable->BootServices->StartImage,
|
||||
3,
|
||||
kernelImageHandle, 0, NULL);
|
||||
if (status != EFI_SUCCESS) {
|
||||
wolfBoot_printf("can't load kernel image from memory\n");
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
static UINT64 FileSize(EFI_FILE_HANDLE FileHandle)
|
||||
{
|
||||
EFI_FILE_INFO *FileInfo;
|
||||
UINT64 ret;
|
||||
|
||||
FileInfo = LibFileInfo(FileHandle);
|
||||
if (FileInfo == NULL)
|
||||
panic();
|
||||
|
||||
ret = FileInfo->FileSize;
|
||||
FreePool(FileInfo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static EFI_FILE_HANDLE GetVolume(EFI_HANDLE image)
|
||||
{
|
||||
EFI_GUID fsGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
|
||||
EFI_GUID lipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
EFI_LOADED_IMAGE *loaded_image = NULL;
|
||||
EFI_FILE_IO_INTERFACE *IOVolume;
|
||||
EFI_FILE_HANDLE Volume;
|
||||
EFI_STATUS status;
|
||||
|
||||
status = uefi_call_wrapper(BS->HandleProtocol, 3,
|
||||
image, &lipGuid, (void **) &loaded_image);
|
||||
if (status != EFI_SUCCESS)
|
||||
panic();
|
||||
|
||||
status = uefi_call_wrapper(BS->HandleProtocol, 3,
|
||||
loaded_image->DeviceHandle,
|
||||
&fsGuid, (VOID*)&IOVolume);
|
||||
if (status != EFI_SUCCESS)
|
||||
panic();
|
||||
|
||||
status = uefi_call_wrapper(IOVolume->OpenVolume, 2, IOVolume, &Volume);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
panic();
|
||||
|
||||
return Volume;
|
||||
}
|
||||
|
||||
static EFI_FILE_HANDLE openFile(CHAR16 *file, EFI_FILE_HANDLE volume)
|
||||
{
|
||||
EFI_FILE_HANDLE file_handle;
|
||||
EFI_STATUS status;
|
||||
|
||||
status = uefi_call_wrapper(volume->Open, 5,
|
||||
volume,
|
||||
&file_handle,
|
||||
file,
|
||||
EFI_FILE_MODE_READ,
|
||||
EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
file_handle = NULL;
|
||||
|
||||
return file_handle;
|
||||
}
|
||||
|
||||
static int open_kernel_image(EFI_FILE_HANDLE vol, CHAR16 *filename,
|
||||
EFI_PHYSICAL_ADDRESS *_addr, uint32_t *sz)
|
||||
{
|
||||
EFI_FILE_HANDLE file;
|
||||
EFI_STATUS status;
|
||||
|
||||
file = openFile(filename, vol);
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
|
||||
*sz = FileSize(file);
|
||||
wolfBoot_printf("Opening file: %s, size: %u\n", filename, *sz);
|
||||
status = uefi_call_wrapper(BS->AllocatePages,
|
||||
4,
|
||||
AllocateAnyPages,
|
||||
EfiLoaderData,
|
||||
(*sz/PAGE_SIZE) + 1, _addr);
|
||||
if (status != EFI_SUCCESS) {
|
||||
wolfBoot_printf("can't get memory at specified address %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = uefi_call_wrapper(file->Read, 3, file, sz, *_addr);
|
||||
if (status != EFI_SUCCESS) {
|
||||
wolfBoot_printf("can't read kernel image %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (*sz < IMAGE_HEADER_SIZE) {
|
||||
wolfBoot_printf("Image smaller than the header\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
CHAR16 *kernel_filename = L"kernel.img";
|
||||
CHAR16 *update_filename = L"update.img";
|
||||
EFI_LOADED_IMAGE *loaded_image = NULL;
|
||||
EFI_FILE_HANDLE vol;
|
||||
EFI_STATUS status;
|
||||
uint8_t *mem;
|
||||
UINT64 size;
|
||||
UINT64 r;
|
||||
uint32_t kernel_size, update_size;
|
||||
|
||||
InitializeLib(ImageHandle, SystemTable);
|
||||
gSystemTable = SystemTable;
|
||||
gImageHandle = ImageHandle;
|
||||
|
||||
status = uefi_call_wrapper(SystemTable->BootServices->HandleProtocol,
|
||||
3,
|
||||
ImageHandle,
|
||||
&LoadedImageProtocol,
|
||||
(void **)&loaded_image);
|
||||
|
||||
if (status == EFI_SUCCESS)
|
||||
wolfBoot_printf("Image base: 0x%lx\n", loaded_image->ImageBase);
|
||||
vol = GetVolume(ImageHandle);
|
||||
open_kernel_image(vol, kernel_filename, &kernel_addr, &kernel_size);
|
||||
open_kernel_image(vol, update_filename, &update_addr, &update_size);
|
||||
|
||||
if (kernel_addr == 0 && update_addr == 0) {
|
||||
wolfBoot_printf("No image to load\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
wolfBoot_start();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_X86_64_EFI */
|
|
@ -0,0 +1 @@
|
|||
# efi target uses the linker script provided by gnu-efi. This is an empty file to appease Makefile.
|
|
@ -28,11 +28,18 @@
|
|||
# define PRINTF_ENABLED
|
||||
#endif
|
||||
|
||||
#if defined(WOLFBOOT_DEBUG_EFI) && !defined(PRINTF_ENABLED)
|
||||
# define PRINTF_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef PRINTF_ENABLED
|
||||
# include <stdio.h>
|
||||
# if defined(DEBUG_ZYNQ) && !defined(USE_QNX)
|
||||
# include "xil_printf.h"
|
||||
# define wolfBoot_printf(_f_, ...) xil_printf(_f_, ##__VA_ARGS__)
|
||||
# elif defined(WOLFBOOT_DEBUG_EFI)
|
||||
/* NOTE: %s arguments will not work as EFI uses widechar string */
|
||||
# define wolfBoot_printf(_f_, ...) Print(L##_f_, ##__VA_ARGS__)
|
||||
# else
|
||||
# define wolfBoot_printf(_f_, ...) printf(_f_, ##__VA_ARGS__)
|
||||
# endif
|
||||
|
|
|
@ -27,16 +27,27 @@
|
|||
#ifndef H_TARGETS_TARGET_
|
||||
#define H_TARGETS_TARGET_
|
||||
|
||||
#define WOLFBOOT_SECTOR_SIZE ##WOLFBOOT_SECTOR_SIZE##
|
||||
#define WOLFBOOT_PARTITION_BOOT_ADDRESS ##WOLFBOOT_PARTITION_BOOT_ADDRESS##
|
||||
#define WOLFBOOT_PARTITION_SIZE ##WOLFBOOT_PARTITION_SIZE##
|
||||
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS ##WOLFBOOT_PARTITION_UPDATE_ADDRESS##
|
||||
#define WOLFBOOT_PARTITION_SWAP_ADDRESS ##WOLFBOOT_PARTITION_SWAP_ADDRESS##
|
||||
#ifndef PLATFORM_X86_64_EFI
|
||||
#define WOLFBOOT_SECTOR_SIZE ##WOLFBOOT_SECTOR_SIZE##
|
||||
#define WOLFBOOT_PARTITION_BOOT_ADDRESS ##WOLFBOOT_PARTITION_BOOT_ADDRESS##
|
||||
#define WOLFBOOT_PARTITION_SIZE ##WOLFBOOT_PARTITION_SIZE##
|
||||
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS ##WOLFBOOT_PARTITION_UPDATE_ADDRESS##
|
||||
#define WOLFBOOT_PARTITION_SWAP_ADDRESS ##WOLFBOOT_PARTITION_SWAP_ADDRESS##
|
||||
|
||||
/* Load address in RAM for staged OS (update_ram only) */
|
||||
#define WOLFBOOT_DTS_BOOT_ADDRESS ##WOLFBOOT_DTS_BOOT_ADDRESS##
|
||||
#define WOLFBOOT_DTS_UPDATE_ADDRESS ##WOLFBOOT_DTS_UPDATE_ADDRESS##
|
||||
#define WOLFBOOT_LOAD_ADDRESS ##WOLFBOOT_LOAD_ADDRESS##
|
||||
#define WOLFBOOT_LOAD_DTS_ADDRESS ##WOLFBOOT_LOAD_DTS_ADDRESS##
|
||||
/* Load address in RAM for staged OS (update_ram only) */
|
||||
#define WOLFBOOT_DTS_BOOT_ADDRESS ##WOLFBOOT_DTS_BOOT_ADDRESS##
|
||||
#define WOLFBOOT_DTS_UPDATE_ADDRESS ##WOLFBOOT_DTS_UPDATE_ADDRESS##
|
||||
#define WOLFBOOT_LOAD_ADDRESS ##WOLFBOOT_LOAD_ADDRESS##
|
||||
#define WOLFBOOT_LOAD_DTS_ADDRESS ##WOLFBOOT_LOAD_DTS_ADDRESS##
|
||||
#else
|
||||
#include "efi/efi.h"
|
||||
extern EFI_PHYSICAL_ADDRESS kernel_addr;
|
||||
extern EFI_PHYSICAL_ADDRESS update_addr;
|
||||
#define WOLFBOOT_PARTITION_BOOT_ADDRESS (kernel_addr)
|
||||
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS (update_addr)
|
||||
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0
|
||||
#define WOLFBOOT_SECTOR_SIZE 0x1000
|
||||
#define WOLFBOOT_PARTITION_SIZE (2 * 1024 * 1024 * 1024ULL)
|
||||
#endif
|
||||
|
||||
#endif /* !H_TARGETS_TARGET_ */
|
||||
|
|
|
@ -185,7 +185,7 @@ endif
|
|||
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS+=-O0 -g -ggdb3 -D"DEBUG=1"
|
||||
CFLAGS+=-O0 -g -ggdb3
|
||||
else
|
||||
ifeq ($(OPTIMIZATION_LEVEL),)
|
||||
CFLAGS+=-Os
|
||||
|
@ -247,6 +247,9 @@ ifeq ($(WOLFTPM),1)
|
|||
endif
|
||||
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/aes.o
|
||||
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/hmac.o
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS+=-DWOLFBOOT_DEBUG_TPM=1
|
||||
endif
|
||||
endif
|
||||
|
||||
## Hash settings
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/* boot_x86_64.c
|
||||
*
|
||||
* Copyright (C) 2021 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "image.h"
|
||||
#include "loader.h"
|
||||
#include "wolfboot/wolfboot.h"
|
||||
|
||||
#ifdef PLATFORM_X86_64_EFI
|
||||
|
||||
#include <efi/efi.h>
|
||||
#include <efi/efilib.h>
|
||||
|
||||
extern unsigned int __bss_start__;
|
||||
extern unsigned int __bss_end__;
|
||||
static volatile unsigned int cpu_id;
|
||||
extern unsigned int *END_STACK;
|
||||
|
||||
extern void RAMFUNCTION x86_64_efi_do_boot(uint8_t *kernel);
|
||||
|
||||
#ifdef MMU
|
||||
void RAMFUNCTION do_boot(const uint32_t *app_offset, const uint32_t* dts_offset)
|
||||
#else
|
||||
void RAMFUNCTION do_boot(const uint32_t *app_offset)
|
||||
#endif
|
||||
{
|
||||
x86_64_efi_do_boot((uint8_t *)app_offset);
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_X86_64_EFI */
|
14
src/image.c
14
src/image.c
|
@ -69,7 +69,7 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
|||
int ret, verify_res = 0;
|
||||
#ifdef WOLFBOOT_TPM
|
||||
WOLFTPM2_KEY tpmKey;
|
||||
#ifdef DEBUG
|
||||
#ifdef WOLFBOOT_DEBUG_TPM
|
||||
const char* errStr;
|
||||
#endif
|
||||
|
||||
|
@ -87,7 +87,7 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
|||
verify_res = 1; /* TPM does hash verify compare */
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
#ifdef WOLFBOOT_DEBUG_TPM
|
||||
/* retrieve error string (for debugging) */
|
||||
errStr = wolfTPM2_GetRCString(ret);
|
||||
(void)errStr;
|
||||
|
@ -212,7 +212,7 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
|||
WOLFTPM2_KEY tpmKey;
|
||||
const byte *n = NULL, *e = NULL;
|
||||
word32 nSz = 0, eSz = 0, inOutIdx = 0;
|
||||
#ifdef DEBUG
|
||||
#ifdef WOLFBOOT_DEBUG_TPM
|
||||
const char* errStr;
|
||||
#endif
|
||||
|
||||
|
@ -226,7 +226,7 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
|||
ret = wolfTPM2_LoadRsaPublicKey_ex(&wolftpm_dev, &tpmKey, n, nSz,
|
||||
*((word32*)e), TPM_ALG_NULL, TPM_ALG_SHA256);
|
||||
if (ret != 0) {
|
||||
#ifdef DEBUG
|
||||
#ifdef WOLFBOOT_DEBUG_TPM
|
||||
/* retrieve error string (for debugging) */
|
||||
errStr = wolfTPM2_GetRCString(ret);
|
||||
(void)errStr;
|
||||
|
@ -240,7 +240,7 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
|||
sig, IMAGE_SIGNATURE_SIZE,
|
||||
output, &output_sz);
|
||||
if (ret != 0) {
|
||||
#ifdef DEBUG
|
||||
#ifdef WOLFBOOT_DEBUG_TPM
|
||||
/* retrieve error string (for debugging) */
|
||||
errStr = wolfTPM2_GetRCString(ret);
|
||||
(void)errStr;
|
||||
|
@ -564,7 +564,7 @@ static int measure_boot(uint8_t *hash)
|
|||
{
|
||||
int rc = -1;
|
||||
PCR_Extend_In pcrExtend;
|
||||
#ifdef DEBUG
|
||||
#ifdef WOLFBOOT_DEBUG_TPM
|
||||
PCR_Read_In pcrReadCmd;
|
||||
PCR_Read_Out pcrReadResp;
|
||||
#endif
|
||||
|
@ -580,7 +580,7 @@ static int measure_boot(uint8_t *hash)
|
|||
rc = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef WOLFBOOT_DEBUG_TPM
|
||||
/* Test prcRead helps debug TPM communication and print PCR value in gdb */
|
||||
XMEMSET(&pcrReadCmd, 0, sizeof(pcrReadCmd));
|
||||
TPM2_SetupPCRSel(&pcrReadCmd.pcrSelectionIn, TPM_ALG_SHA256,
|
||||
|
|
|
@ -646,7 +646,8 @@ uint16_t wolfBoot_get_image_type(uint8_t part)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(ARCH_AARCH64) || defined(DUALBANK_SWAP)
|
||||
#if defined(ARCH_AARCH64) || defined(DUALBANK_SWAP) || defined(PLATFORM_X86_64_EFI)
|
||||
|
||||
int wolfBoot_fallback_is_possible(void)
|
||||
{
|
||||
uint32_t boot_v, update_v;
|
||||
|
|
|
@ -51,7 +51,7 @@ int isalpha(int c)
|
|||
return (isupper(c) || islower(c));
|
||||
}
|
||||
|
||||
#ifndef __IAR_SYSTEMS_ICC__
|
||||
#if !defined(__IAR_SYSTEMS_ICC__) && !defined(PLATFORM_X86_64_EFI)
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *d = (unsigned char *)s;
|
||||
|
@ -168,7 +168,7 @@ int strncmp(const char *s1, const char *s2, size_t n)
|
|||
return diff;
|
||||
}
|
||||
|
||||
#ifndef __IAR_SYSTEMS_ICC__
|
||||
#if !defined(__IAR_SYSTEMS_ICC__) && !defined(PLATFORM_X86_64_EFI)
|
||||
void *memcpy(void *dst, const void *src, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
|
|
@ -30,6 +30,13 @@
|
|||
#include "wolfboot/wolfboot.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef PLATFORM_X86_64_EFI
|
||||
#include "efi/efi.h"
|
||||
#include "efi/efilib.h"
|
||||
extern EFI_PHYSICAL_ADDRESS kernel_addr;
|
||||
extern EFI_PHYSICAL_ADDRESS update_addr;
|
||||
#endif
|
||||
|
||||
extern void hal_flash_dualbank_swap(void);
|
||||
|
||||
static inline void boot_panic(void)
|
||||
|
@ -42,7 +49,12 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
{
|
||||
int active, ret = 0;
|
||||
struct wolfBoot_image os_image;
|
||||
#ifdef PLATFORM_X86_64_EFI
|
||||
uint32_t* load_address = (uint32_t*)kernel_addr;
|
||||
#else
|
||||
uint32_t* load_address = (uint32_t*)WOLFBOOT_LOAD_ADDRESS;
|
||||
#endif
|
||||
|
||||
uint8_t* image_ptr;
|
||||
uint8_t p_state;
|
||||
#ifdef MMU
|
||||
|
@ -56,6 +68,11 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
if (active < 0) /* panic if no images available */
|
||||
boot_panic();
|
||||
|
||||
#ifdef PLATFORM_X86_64_EFI
|
||||
if (active == 1)
|
||||
load_address = (uint32_t *)update_addr;
|
||||
#endif
|
||||
|
||||
/* Check current status for failure (image still in TESTING), and fall-back
|
||||
* if an alternative is available
|
||||
*/
|
||||
|
@ -143,11 +160,14 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
hal_prepare_boot();
|
||||
|
||||
wolfBoot_printf("Booting at %08lx\n", load_address);
|
||||
hal_prepare_boot();
|
||||
|
||||
#ifdef MMU
|
||||
#ifdef PLATFORM_X86_64_EFI
|
||||
extern void x86_64_efi_do_boot(uint8_t *);
|
||||
x86_64_efi_do_boot((uint8_t*)load_address);
|
||||
#elif defined MMU
|
||||
do_boot((uint32_t*)load_address, (uint32_t*)dts_address);
|
||||
#else
|
||||
do_boot((uint32_t*)load_address);
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
BR2_x86_64=y
|
||||
BR2_x86_corei7=y
|
||||
# BR2_STRIP_strip is not set
|
||||
# BR2_COMPILER_PARANOID_UNSAFE_PATH is not set
|
||||
BR2_TOOLCHAIN_EXTERNAL=y
|
||||
# BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set
|
||||
# BR2_ENABLE_LOCALE_PURGE is not set
|
||||
BR2_LINUX_KERNEL=y
|
||||
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
||||
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_TINY_PATH)/linux.config"
|
||||
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
|
||||
# BR2_PACKAGE_URANDOM_SCRIPTS is not set
|
||||
BR2_TARGET_ROOTFS_INITRAMFS=y
|
||||
# BR2_TARGET_ROOTFS_TAR is not set
|
|
@ -0,0 +1,2 @@
|
|||
name: TINY
|
||||
desc: configuration for building a tiny kernel+initramfs image
|
|
@ -0,0 +1,31 @@
|
|||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_INITRAMFS_SOURCE="${BR_BINARIES_DIR}/rootfs.cpio"
|
||||
CONFIG_EXPERT=y
|
||||
CONFIG_EFI=y
|
||||
CONFIG_EFI_STUB=y
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
CONFIG_CMDLINE="console=ttyS0"
|
||||
# CONFIG_EFI_CUSTOM_SSDT_OVERLAYS is not set
|
||||
# CONFIG_GCC_PLUGINS is not set
|
||||
# CONFIG_BLOCK is not set
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_TTY_PRINTK=y
|
||||
CONFIG_TCG_TPM=y
|
||||
CONFIG_TCG_TIS=y
|
||||
CONFIG_TCG_TIS_SPI=y
|
||||
CONFIG_TCG_TIS_SPI_CR50=y
|
||||
CONFIG_TCG_NSC=y
|
||||
CONFIG_TCG_ATMEL=y
|
||||
CONFIG_TCG_INFINEON=y
|
||||
CONFIG_TCG_CRB=y
|
||||
CONFIG_TCG_VTPM_PROXY=y
|
||||
CONFIG_TCG_TIS_ST33ZP24_SPI=y
|
||||
CONFIG_SPI=y
|
||||
# CONFIG_SECURITYFS is not set
|
||||
CONFIG_CRYPTO_SHA1=y
|
||||
CONFIG_UNWINDER_GUESS=y
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/sh
|
||||
|
||||
WORK_DIR=/tmp/wolfBoot_efi
|
||||
BR_VER=2021.08.2
|
||||
BR_DIR=buildroot-$BR_VER
|
||||
IMAGE_DIR=$WORK_DIR/output
|
||||
|
||||
if (test ! -d $WORK_DIR);then
|
||||
mkdir -p $WORK_DIR
|
||||
fi
|
||||
|
||||
if (test ! -d $WORK_DIR/$BR_DIR);then
|
||||
curl https://buildroot.org/downloads/$BR_DIR.tar.gz -o $WORK_DIR/$BR_DIR.tar.gz
|
||||
tar xvf $WORK_DIR/$BR_DIR.tar.gz -C $WORK_DIR
|
||||
fi
|
||||
|
||||
BR2_EXTERNAL=$(pwd)/tools/efi/br_ext_dir make -C $WORK_DIR/$BR_DIR tiny_defconfig O=$IMAGE_DIR
|
||||
make -C $WORK_DIR/$BR_DIR O=$IMAGE_DIR
|
||||
|
||||
SIGN_TOOL="python3 ./tools/keytools/sign.py"
|
||||
if [ -f "./tools/keytools/sign" ]; then
|
||||
SIGN_TOOL="./tools/keytools/sign"
|
||||
fi
|
||||
|
||||
$SIGN_TOOL --ed25519 $IMAGE_DIR/images/bzImage ed25519.der 1
|
||||
$SIGN_TOOL --ed25519 $IMAGE_DIR/images/bzImage ed25519.der 2
|
||||
|
||||
mkdir -p /tmp/efi
|
||||
sudo mount /tmp/efi.disk /tmp/efi
|
||||
sudo cp $IMAGE_DIR/images/bzImage_v1_signed.bin /tmp/efi/kernel.img
|
||||
sudo cp $IMAGE_DIR/images/bzImage_v2_signed.bin /tmp/efi/update.img
|
||||
sudo cp wolfboot.efi /tmp/efi
|
||||
sudo umount /tmp/efi
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
dd if=/dev/zero of=/tmp/efi.disk bs=256M count=1
|
||||
sudo mkfs.vfat /tmp/efi.disk
|
||||
mkdir -p /tmp/efi
|
||||
sudo mount /tmp/efi.disk /tmp/efi -oloop
|
||||
cat <<EOF > /tmp/startup.nsh
|
||||
@echo -off
|
||||
echo Starting wolfBoot EFI...
|
||||
fs0:
|
||||
wolfboot.efi
|
||||
EOF
|
||||
sudo mv /tmp/startup.nsh /tmp/efi/ 2>/dev/null
|
||||
sudo umount /tmp/efi
|
|
@ -0,0 +1,50 @@
|
|||
#!/bin/sh
|
||||
|
||||
## TPM emulator:
|
||||
# https://github.com/stefanberger/swtpm
|
||||
|
||||
if (test -z $OVMF_PATH); then
|
||||
if (test -f /usr/share/edk2-ovmf/x64/OVMF.fd); then
|
||||
OVMF_PATH=/usr/share/edk2-ovmf/x64
|
||||
elif (test -f /usr/share/qemu/OVMF.fd); then
|
||||
OVMF_PATH=/usr/share/qemu
|
||||
else
|
||||
OVMF_PATH=/
|
||||
fi
|
||||
fi
|
||||
|
||||
QEMU_OPTIONS=" \
|
||||
-m 256M \
|
||||
-net none \
|
||||
-bios ${OVMF_PATH}/OVMF.fd \
|
||||
-drive file=/tmp/efi.disk,index=0,media=disk,format=raw \
|
||||
-vga none \
|
||||
-serial stdio \
|
||||
-display none"
|
||||
|
||||
|
||||
QEMU_TPM_OPTIONS=" \
|
||||
-chardev socket,id=chrtpm,path=/tmp/swtpm/swtpm-sock \
|
||||
-tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
-device tpm-tis,tpmdev=tpm0"
|
||||
|
||||
if (which swtpm); then
|
||||
killall swtpm
|
||||
sleep 1
|
||||
QEMU_EXTRA=$QEMU_TPM_OPTIONS
|
||||
echo TPM Emulation ON
|
||||
mkdir -p /tmp/swtpm
|
||||
swtpm socket --tpm2 --tpmstate dir=/tmp/swtpm \
|
||||
--ctrl type=unixio,path=/tmp/swtpm/swtpm-sock --log level=20 &
|
||||
else
|
||||
echo TPM Emulation OFF
|
||||
fi
|
||||
|
||||
mkdir -p /tmp/efi
|
||||
sudo mount /tmp/efi.disk /tmp/efi
|
||||
sudo cp wolfboot.efi /tmp/efi
|
||||
sudo umount /tmp/efi
|
||||
|
||||
echo $QEMU_OPTIONS $QEMU_EXTRA
|
||||
|
||||
qemu-system-x86_64 $QEMU_OPTIONS $QEMU_EXTRA
|
Loading…
Reference in New Issue