mirror of
https://github.com/linuxboot/linuxboot
synced 2024-11-21 15:50:58 +00:00
split fv/ffs code into separate file
This commit is contained in:
parent
3cd19d2121
commit
06c8c0f78b
@ -6,7 +6,7 @@ EFI_ARCH = x86_64
|
||||
#EFI_ARCH = x86
|
||||
|
||||
|
||||
TARGETS += fvloader.ffs
|
||||
#TARGETS += fvloader.ffs
|
||||
TARGETS += linuxboot.ffs
|
||||
TARGETS += hello.ffs
|
||||
|
||||
@ -15,19 +15,18 @@ all: $(TARGETS)
|
||||
clean: FORCE
|
||||
$(RM) *.efi *.exe *.rom *.o .*.d $(TARGETS)
|
||||
|
||||
linuxboot.exe: linuxboot.o efifv.o
|
||||
hello.exe: hello.o
|
||||
|
||||
FORCE:
|
||||
|
||||
%.exe: %.o
|
||||
%.exe:
|
||||
$(CROSS)ld \
|
||||
$(LDFLAGS) \
|
||||
-T elf_x86_64_efi.lds \
|
||||
-o $@ \
|
||||
$^
|
||||
|
||||
%.efi-wrap: %.exe
|
||||
./efi-wrap $^ > $@
|
||||
|
||||
%.efi: %.exe
|
||||
objcopy \
|
||||
-j .text -j .sdata -j .data -j .dynamic \
|
||||
|
117
dxe/efifv.c
Normal file
117
dxe/efifv.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include "efifv.h"
|
||||
#include "serial.h"
|
||||
|
||||
/*
|
||||
* Locate a firmware file based on the GUID
|
||||
*/
|
||||
static EFI_FIRMWARE_VOLUME2_PROTOCOL *
|
||||
find_ffs(
|
||||
EFI_BOOT_SERVICES * gBS,
|
||||
EFI_GUID * guid
|
||||
)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
EFI_HANDLE * handles = NULL;
|
||||
UINTN handle_count;
|
||||
EFI_GUID fv_proto = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
|
||||
|
||||
status = gBS->LocateHandleBuffer(
|
||||
ByProtocol,
|
||||
&fv_proto,
|
||||
NULL,
|
||||
&handle_count,
|
||||
&handles
|
||||
);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
serial_string("LinuxBoot: locate_handle rc=");
|
||||
serial_hex(status, 8);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(unsigned i = 0 ; i < handle_count ; i++)
|
||||
{
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL * fv = NULL;
|
||||
|
||||
serial_string("handle=");
|
||||
serial_hex((unsigned long) handles[i], 16);
|
||||
|
||||
status = gBS->HandleProtocol(
|
||||
handles[i],
|
||||
&fv_proto,
|
||||
(void**) &fv
|
||||
);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
serial_string("handle proto rc=");
|
||||
serial_hex(status, 8);
|
||||
continue;
|
||||
}
|
||||
|
||||
UINTN size;
|
||||
UINT32 auth_status;
|
||||
EFI_FV_FILETYPE type;
|
||||
EFI_FV_FILE_ATTRIBUTES attributes;
|
||||
|
||||
status = fv->ReadFile(
|
||||
fv,
|
||||
guid,
|
||||
NULL,
|
||||
&size,
|
||||
&type,
|
||||
&attributes,
|
||||
&auth_status
|
||||
);
|
||||
if (status != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
serial_string("LinuxBoot: fv=");
|
||||
serial_hex((unsigned long) fv, 16);
|
||||
|
||||
return fv;
|
||||
}
|
||||
|
||||
// this leaks the handle buffer.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
read_ffs(
|
||||
EFI_BOOT_SERVICES * gBS,
|
||||
EFI_GUID * guid,
|
||||
void ** buffer,
|
||||
UINTN * size,
|
||||
EFI_SECTION_TYPE section_type
|
||||
)
|
||||
{
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL * fv = find_ffs(gBS, guid);
|
||||
if (!fv)
|
||||
return -1;
|
||||
|
||||
UINT32 auth_status;
|
||||
EFI_STATUS status = fv->ReadSection(
|
||||
fv,
|
||||
guid,
|
||||
section_type,
|
||||
0,
|
||||
buffer,
|
||||
size,
|
||||
&auth_status
|
||||
);
|
||||
if (status != 0)
|
||||
{
|
||||
serial_string("LinuxBoot: read section rc=");
|
||||
serial_hex(status, 8);
|
||||
return -1;
|
||||
}
|
||||
|
||||
serial_string("LinuxBoot: FFS buffer=");
|
||||
serial_hex((unsigned long) *buffer, 16);
|
||||
serial_string("LinuxBoot: FFS length=");
|
||||
serial_hex(*size, 8);
|
||||
|
||||
return 0;
|
||||
}
|
91
dxe/efifv.h
Normal file
91
dxe/efifv.h
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* \file
|
||||
* EFI Firmware Volume protocol.
|
||||
*
|
||||
*/
|
||||
#ifndef _efi_fv_h_
|
||||
#define _efi_fv_h_
|
||||
|
||||
#include <efi/efi.h>
|
||||
|
||||
#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID ((EFI_GUID){ 0x220e73b6, 0x6bdb, 0x4413, { 0x84, 0x05, 0xb9, 0x74, 0xb1, 0x08, 0x61, 0x9a } })
|
||||
|
||||
typedef UINT8 EFI_FV_FILETYPE;
|
||||
#define EFI_FV_FILETYPE_RAW 0x01
|
||||
#define EFI_FV_FILETYPE_FREEFORM 0x02
|
||||
#define EFI_FV_FILETYPE_SECURITY_CORE 0x03
|
||||
#define EFI_FV_FILETYPE_PEI_CORE 0x04
|
||||
#define EFI_FV_FILETYPE_DXE_CORE 0x05
|
||||
#define EFI_FV_FILETYPE_PEIM 0x06
|
||||
#define EFI_FV_FILETYPE_DRIVER 0x07
|
||||
#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08
|
||||
#define EFI_FV_FILETYPE_APPLICATION 0x09
|
||||
#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0b
|
||||
#define EFI_FV_FILETYPE_FFS_PAD 0xf0
|
||||
|
||||
typedef UINT32 EFI_FV_FILE_ATTRIBUTES;
|
||||
#define EFI_FV_FILE_ATTRIB_ALIGNMENT 0x0000001F
|
||||
|
||||
typedef UINT8 EFI_SECTION_TYPE;
|
||||
#define EFI_SECTION_ALL 0x00
|
||||
#define EFI_SECTION_COMPRESSION 0x01
|
||||
#define EFI_SECTION_GUID_DEFINED 0x02
|
||||
#define EFI_SECTION_DISPOSABLE 0x03
|
||||
#define EFI_SECTION_PE32 0x10
|
||||
#define EFI_SECTION_PIC 0x11
|
||||
#define EFI_SECTION_DXE_DEPEX 0x13
|
||||
#define EFI_SECTION_COMPATIBILITY16 0x16
|
||||
#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17
|
||||
#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18
|
||||
#define EFI_SECTION_RAW 0x19
|
||||
#define EFI_SECTION_PEI_DEPEX 0x1B
|
||||
|
||||
|
||||
typedef struct _EFI_FIRMWARE_VOLUME2_PROTOCOL EFI_FIRMWARE_VOLUME2_PROTOCOL;
|
||||
|
||||
typedef EFI_STATUS
|
||||
(EFIAPI * EFI_FV_READ_FILE) (
|
||||
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT EFI_FV_FILETYPE *FoundType,
|
||||
OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
);
|
||||
|
||||
typedef EFI_STATUS
|
||||
(EFIAPI * EFI_FV_READ_SECTION) (
|
||||
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN SectionInstance,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
);
|
||||
|
||||
struct _EFI_FIRMWARE_VOLUME2_PROTOCOL {
|
||||
uint64_t GetVolumeAttributes;
|
||||
uint64_t SetVolumeAttributes;
|
||||
EFI_FV_READ_FILE ReadFile;
|
||||
EFI_FV_READ_SECTION ReadSection;
|
||||
uint64_t WriteFile;
|
||||
uint64_t GetNextFile;
|
||||
uint32_t KeySize;
|
||||
uint64_t ParentHandle;
|
||||
uint64_t GetInfo;
|
||||
uint64_t SetInfo;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
read_ffs(
|
||||
EFI_BOOT_SERVICES * gBS,
|
||||
EFI_GUID * guid,
|
||||
void ** buffer,
|
||||
UINTN * size,
|
||||
EFI_SECTION_TYPE section_type
|
||||
);
|
||||
|
||||
#endif
|
212
dxe/linuxboot.c
212
dxe/linuxboot.c
@ -19,12 +19,13 @@
|
||||
#include "serial.h"
|
||||
#include <efi/efi.h>
|
||||
#include "efidxe.h"
|
||||
#include "efifv.h"
|
||||
|
||||
static EFI_HANDLE gImage;
|
||||
static EFI_SYSTEM_TABLE * gST;
|
||||
static EFI_BOOT_SERVICES * gBS;
|
||||
static EFI_RUNTIME_SERVICES * gRT;
|
||||
static EFI_DXE_SERVICES * gDXE;
|
||||
EFI_HANDLE gImage;
|
||||
EFI_SYSTEM_TABLE * gST;
|
||||
EFI_BOOT_SERVICES * gBS;
|
||||
EFI_RUNTIME_SERVICES * gRT;
|
||||
EFI_DXE_SERVICES * gDXE;
|
||||
|
||||
static void hexdump(uint64_t p, unsigned len)
|
||||
{
|
||||
@ -89,77 +90,6 @@ empty_notify(void* unused1, void* unused2)
|
||||
|
||||
#define EFI_BDS_ARCH_PROTOCOL_GUID ((EFI_GUID){ 0x665E3FF6, 0x46CC, 0x11d4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } })
|
||||
|
||||
#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID ((EFI_GUID){ 0x220e73b6, 0x6bdb, 0x4413, { 0x84, 0x05, 0xb9, 0x74, 0xb1, 0x08, 0x61, 0x9a } })
|
||||
|
||||
typedef UINT8 EFI_FV_FILETYPE;
|
||||
#define EFI_FV_FILETYPE_RAW 0x01
|
||||
#define EFI_FV_FILETYPE_FREEFORM 0x02
|
||||
#define EFI_FV_FILETYPE_SECURITY_CORE 0x03
|
||||
#define EFI_FV_FILETYPE_PEI_CORE 0x04
|
||||
#define EFI_FV_FILETYPE_DXE_CORE 0x05
|
||||
#define EFI_FV_FILETYPE_PEIM 0x06
|
||||
#define EFI_FV_FILETYPE_DRIVER 0x07
|
||||
#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08
|
||||
#define EFI_FV_FILETYPE_APPLICATION 0x09
|
||||
#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0b
|
||||
#define EFI_FV_FILETYPE_FFS_PAD 0xf0
|
||||
|
||||
typedef UINT32 EFI_FV_FILE_ATTRIBUTES;
|
||||
#define EFI_FV_FILE_ATTRIB_ALIGNMENT 0x0000001F
|
||||
|
||||
typedef UINT8 EFI_SECTION_TYPE;
|
||||
#define EFI_SECTION_ALL 0x00
|
||||
#define EFI_SECTION_COMPRESSION 0x01
|
||||
#define EFI_SECTION_GUID_DEFINED 0x02
|
||||
#define EFI_SECTION_DISPOSABLE 0x03
|
||||
#define EFI_SECTION_PE32 0x10
|
||||
#define EFI_SECTION_PIC 0x11
|
||||
#define EFI_SECTION_DXE_DEPEX 0x13
|
||||
#define EFI_SECTION_COMPATIBILITY16 0x16
|
||||
#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17
|
||||
#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18
|
||||
#define EFI_SECTION_RAW 0x19
|
||||
#define EFI_SECTION_PEI_DEPEX 0x1B
|
||||
|
||||
|
||||
typedef struct _EFI_FIRMWARE_VOLUME2_PROTOCOL EFI_FIRMWARE_VOLUME2_PROTOCOL;
|
||||
|
||||
typedef EFI_STATUS
|
||||
(EFIAPI * EFI_FV_READ_FILE) (
|
||||
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT EFI_FV_FILETYPE *FoundType,
|
||||
OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
);
|
||||
|
||||
typedef EFI_STATUS
|
||||
(EFIAPI * EFI_FV_READ_SECTION) (
|
||||
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
|
||||
IN EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN SectionInstance,
|
||||
IN OUT VOID **Buffer,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT32 *AuthenticationStatus
|
||||
);
|
||||
|
||||
struct _EFI_FIRMWARE_VOLUME2_PROTOCOL {
|
||||
uint64_t GetVolumeAttributes;
|
||||
uint64_t SetVolumeAttributes;
|
||||
EFI_FV_READ_FILE ReadFile;
|
||||
EFI_FV_READ_SECTION ReadSection;
|
||||
uint64_t WriteFile;
|
||||
uint64_t GetNextFile;
|
||||
uint32_t KeySize;
|
||||
uint64_t ParentHandle;
|
||||
uint64_t GetInfo;
|
||||
uint64_t SetInfo;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void
|
||||
efi_event_signal(
|
||||
@ -297,125 +227,6 @@ efi_final_init(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Locate a firmware file based on the GUID
|
||||
*/
|
||||
static EFI_HANDLE
|
||||
find_ffs(
|
||||
EFI_GUID * guid
|
||||
)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
EFI_HANDLE * handles = NULL;
|
||||
UINTN handle_count;
|
||||
EFI_GUID fv_proto = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
|
||||
|
||||
status = gBS->LocateHandleBuffer(
|
||||
ByProtocol,
|
||||
&fv_proto,
|
||||
NULL,
|
||||
&handle_count,
|
||||
&handles
|
||||
);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
serial_string("LinuxBoot: locate_handle rc=");
|
||||
serial_hex(status, 8);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(unsigned i = 0 ; i < handle_count ; i++)
|
||||
{
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL * fv = NULL;
|
||||
|
||||
serial_string("handle=");
|
||||
serial_hex((unsigned long) handles[i], 16);
|
||||
|
||||
status = gBS->HandleProtocol(
|
||||
handles[i],
|
||||
&fv_proto,
|
||||
(void**) &fv
|
||||
);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
serial_string("handle proto rc=");
|
||||
serial_hex(status, 8);
|
||||
continue;
|
||||
}
|
||||
|
||||
UINTN size;
|
||||
UINT32 auth_status;
|
||||
EFI_FV_FILETYPE type;
|
||||
EFI_FV_FILE_ATTRIBUTES attributes;
|
||||
|
||||
status = fv->ReadFile(
|
||||
fv,
|
||||
guid,
|
||||
NULL,
|
||||
&size,
|
||||
&type,
|
||||
&attributes,
|
||||
&auth_status
|
||||
);
|
||||
if (status != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
serial_string("LinuxBoot: fv=");
|
||||
serial_hex((unsigned long) fv, 16);
|
||||
|
||||
return handles[i];
|
||||
}
|
||||
|
||||
// this leaks the handle buffer.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
read_ffs(
|
||||
EFI_HANDLE fv_handle,
|
||||
EFI_GUID * guid,
|
||||
void ** buffer,
|
||||
UINTN * size,
|
||||
EFI_SECTION_TYPE section_type
|
||||
)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL * fv = NULL;
|
||||
|
||||
status = gBS->HandleProtocol(
|
||||
fv_handle,
|
||||
&EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID,
|
||||
(void**) &fv
|
||||
);
|
||||
if (status != 0)
|
||||
return -1;
|
||||
|
||||
UINT32 auth_status;
|
||||
status = fv->ReadSection(
|
||||
fv,
|
||||
guid,
|
||||
section_type,
|
||||
0,
|
||||
buffer,
|
||||
size,
|
||||
&auth_status
|
||||
);
|
||||
if (status != 0)
|
||||
{
|
||||
serial_string("LinuxBoot: read section rc=");
|
||||
serial_hex(status, 8);
|
||||
return -1;
|
||||
}
|
||||
|
||||
serial_string("LinuxBoot: FFS buffer=");
|
||||
serial_hex((unsigned long) *buffer, 16);
|
||||
serial_string("LinuxBoot: FFS length=");
|
||||
serial_hex(*size, 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// code in MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
|
||||
static int
|
||||
@ -425,16 +236,9 @@ linuxboot_start()
|
||||
EFI_GUID bzimage_guid = { 0xDECAFBAD, 0x6548, 0x6461, { 0x73, 0x2d, 0x2f, 0x2d, 0x4e, 0x45, 0x52, 0x46 }};
|
||||
EFI_GUID initrd_guid = { 0x74696e69, 0x6472, 0x632e, { 0x70, 0x69, 0x6f, 0x2f, 0x62, 0x69, 0x6f, 0x73 }};
|
||||
|
||||
EFI_HANDLE bzimage_handle = find_ffs(&bzimage_guid);
|
||||
if (!bzimage_handle)
|
||||
{
|
||||
serial_string("LinuxBoot: bzImage FFS not found\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void * bzimage_buffer = NULL;
|
||||
UINTN bzimage_length = 0;
|
||||
if (read_ffs(bzimage_handle, &bzimage_guid, &bzimage_buffer, &bzimage_length, EFI_SECTION_PE32) < 0)
|
||||
if (read_ffs(gBS, &bzimage_guid, &bzimage_buffer, &bzimage_length, EFI_SECTION_PE32) < 0)
|
||||
return -1;
|
||||
|
||||
// convert the firmware volume protocol to a loaded image
|
||||
@ -480,7 +284,7 @@ linuxboot_start()
|
||||
#if 0
|
||||
void * initrd_buffer = NULL;
|
||||
UINTN initrd_length = 0;
|
||||
if (read_ffs(&initrd_guid, &initrd_buffer, &initrd_length, EFI_SECTION_RAW) < 0)
|
||||
if (read_ffs(gBS, &initrd_guid, &initrd_buffer, &initrd_length, EFI_SECTION_RAW) < 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user