mirror of
https://github.com/linuxboot/linuxboot
synced 2024-11-21 15:50:58 +00:00
118 lines
1.9 KiB
C
118 lines
1.9 KiB
C
#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;
|
|
}
|