BDS can find bzimage and initrd volumes now, but not yet start them

This commit is contained in:
Trammell hudson 2018-05-07 17:48:52 -04:00 committed by Trammell Hudson
parent 4cf7d4974a
commit e09b511c29
Failed to extract signature

View File

@ -82,11 +82,81 @@ empty_notify(void* unused1, void* unused2)
#define EFI_END_OF_DXE_EVENT_GROUP_GUID ((EFI_GUID){ 0x02ce967a, 0xdd7e, 0x4ffc, { 0x9e, 0xe7, 0x81, 0x0c, 0xf0, 0x47, 0x08, 0x80 } })
#define EFI_EVENT_GROUP_READY_TO_BOOT ((EFI_GUID){ 0x7ce88fb3, 0x4bd7, 0x4679, { 0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b } })
#define EFI_EVENT_GROUP_READY_TO_BOOT ((EFI_GUID){ 0x7ce88fb3, 0x4bd7, 0x4679, { 0x87, 0xa8, 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b } })
#define EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID ((EFI_GUID){ 0x60ff8964, 0xe906, 0x41d0, { 0xaf, 0xed, 0xf2, 0x41, 0xe9, 0x74, 0xe0, 0x8e } })
#define EFI_BDS_ARCH_PROTOCOL_GUID ((EFI_GUID){ 0x665E3FF6, 0x46CC, 0x11d4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } })
#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;
};
@ -172,29 +242,29 @@ efi_connect_controllers(
static EFI_STATUS EFIAPI
efi_bds_main(void)
static void
efi_final_init(void)
{
// equivilant to PlatformBootManagerBeforeConsole
// connect all the pci root bridges
serial_string("connect pci root brdiges\r\n");
serial_string("LinuxBoot: connect pci root brdiges\r\n");
EFI_GUID pci_protocol = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
efi_visit_handles(&pci_protocol, efi_connect_controllers, (void*) 0);
// signal the acpi platform driver that it can download the ACPI tables
serial_string("signal root bridges connected\r\n");
serial_string("LinuxBoot: signal root bridges connected\r\n");
efi_event_signal(ROOT_BRIDGES_CONNECTED_EVENT_GROUP_GUID);
// signal that dxe is about to end
serial_string("signal dxe end\r\n");
serial_string("LinuxBoot: signal dxe end\r\n");
efi_event_signal(EFI_END_OF_DXE_EVENT_GROUP_GUID);
// Prevent further changes to LockBoxes or SMRAM.
// This should be a configurable option
EFI_HANDLE handle = NULL;
EFI_GUID smm_ready_to_lock = EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID;
serial_string("signal smm ready to lock\r\n");
serial_string("LinuxBoot: signal smm ready to lock\r\n");
gBS->InstallProtocolInterface(
&handle,
@ -216,15 +286,158 @@ efi_bds_main(void)
**/
do {
efi_visit_handles(NULL, efi_connect_controllers, (void*) 1);
serial_string("bds_main dispatch\r\n");
serial_string("LinuxBoot: bds_main dispatch\r\n");
} while(gDXE->Dispatch() == 0);
// signal that we're ready to boot, which will
// cause additional drivers to be loaded
serial_string("bds_main 2\r\n");
serial_string("LinuxBoot: signal ready to boot\r\n");
efi_event_signal(EFI_EVENT_GROUP_READY_TO_BOOT);
}
/*
* Locate a firmware file based on the GUID
*/
static EFI_FIRMWARE_VOLUME2_PROTOCOL *
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 fv;
}
// this leaks the handle buffer.
return NULL;
}
static int
read_ffs(
EFI_GUID * guid,
void ** buffer,
UINTN * size
)
{
EFI_FIRMWARE_VOLUME2_PROTOCOL * fv = find_ffs(guid);
if (!fv)
{
serial_string("LinuxBoot: FFS not found\r\n");
return -1;
}
UINT32 auth_status;
EFI_STATUS status = fv->ReadSection(
fv,
guid,
EFI_SECTION_RAW,
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
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_FIRMWARE_VOLUME2_PROTOCOL * bzimage = find_ffs(&bzimage_guid);
if (!bzimage)
return -1;
void * initrd_buffer = NULL;
UINTN initrd_length = 0;
if (read_ffs(&initrd_guid, &initrd_buffer, &initrd_length) < 0)
return -1;
return 0;
}
static EFI_STATUS EFIAPI
efi_bds_main(void)
{
serial_string("LinuxBoot: BDS time has arrived\r\n");
efi_final_init();
if (linuxboot_start() < 0)
return 0;
serial_string("should locate linux, initrd, etc...\n");
return EFI_NOT_FOUND;
}
@ -295,6 +508,6 @@ efi_main(
&efi_bds_arch_protocol
);
serial_string("waiting for callback\r\n");
serial_string("LinuxBoot: waiting for BDS callback\r\n");
return 0;
}