mirror of
https://github.com/linuxboot/linuxboot
synced 2024-11-21 23:59:59 +00:00
BDS can find bzimage and initrd volumes now, but not yet start them
This commit is contained in:
parent
4cf7d4974a
commit
e09b511c29
237
dxe/linuxboot.c
237
dxe/linuxboot.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user