Changeset View
Changeset View
Standalone View
Standalone View
stand/efi/loader/bootinfo.c
Show All 25 Lines | |||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <stand.h> | #include <stand.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <stdbool.h> | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/reboot.h> | #include <sys/reboot.h> | ||||
#include <sys/linker.h> | #include <sys/linker.h> | ||||
#include <sys/boot.h> | #include <sys/boot.h> | ||||
#include <machine/cpufunc.h> | #include <machine/cpufunc.h> | ||||
#include <machine/elf.h> | #include <machine/elf.h> | ||||
#include <machine/metadata.h> | #include <machine/metadata.h> | ||||
#include <machine/psl.h> | #include <machine/psl.h> | ||||
#include <efi.h> | #include <efi.h> | ||||
#include <efilib.h> | #include <efilib.h> | ||||
#include <efisec.h> | |||||
#include "bootstrap.h" | #include "bootstrap.h" | ||||
#include "loader_efi.h" | #include "loader_efi.h" | ||||
#include "key_inject.h" | |||||
#if defined(__amd64__) | #if defined(__amd64__) | ||||
#include <machine/specialreg.h> | #include <machine/specialreg.h> | ||||
#endif | #endif | ||||
#include "framebuffer.h" | #include "framebuffer.h" | ||||
#if defined(LOADER_FDT_SUPPORT) | #if defined(LOADER_FDT_SUPPORT) | ||||
#include <fdt_platform.h> | #include <fdt_platform.h> | ||||
#endif | #endif | ||||
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp); | int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp); | ||||
extern EFI_SYSTEM_TABLE *ST; | extern EFI_SYSTEM_TABLE *ST; | ||||
static EFI_GUID EfiKmsProtocolGuid = EFI_KMS_PROTOCOL; | |||||
static EFI_GUID KernelKeyInjectorGuid = KERNEL_KEY_INJECTOR_GUID; | |||||
static const char howto_switches[] = "aCdrgDmphsv"; | static const char howto_switches[] = "aCdrgDmphsv"; | ||||
static int howto_masks[] = { | static int howto_masks[] = { | ||||
RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE, | RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE, | ||||
RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE | RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE | ||||
}; | }; | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 161 Lines • ▼ Show 20 Lines | #endif | ||||
for (md = fp->f_metadata; md != NULL; md = md->md_next) | for (md = fp->f_metadata; md != NULL; md = md->md_next) | ||||
if (!(md->md_type & MODINFOMD_NOCOPY)) | if (!(md->md_type & MODINFOMD_NOCOPY)) | ||||
MOD_METADATA(addr, md, c); | MOD_METADATA(addr, md, c); | ||||
} | } | ||||
MOD_END(addr, c); | MOD_END(addr, c); | ||||
return(addr); | return(addr); | ||||
} | } | ||||
static void | |||||
key_inject_set_client(struct preloaded_file *kfp) | |||||
{ | |||||
EFI_KMS_CLIENT_INFO client; | |||||
EFI_KMS_SERVICE *kms; | |||||
EFI_HANDLE *handles; | |||||
EFI_STATUS status; | |||||
UINTN sz; | |||||
u_int n, nin; | |||||
/* Try and find a usable KMS instance */ | |||||
sz = 0; | |||||
handles = NULL; | |||||
status = BS->LocateHandle(ByProtocol, &EfiKmsProtocolGuid, 0, &sz, 0); | |||||
if (status == EFI_BUFFER_TOO_SMALL) { | |||||
handles = (EFI_HANDLE *)malloc(sz); | |||||
status = BS->LocateHandle(ByProtocol, &EfiKmsProtocolGuid, | |||||
0, &sz, handles); | |||||
if (EFI_ERROR(status)) { | |||||
printf("Error getting handles for kernel KMS %lu\n", | |||||
EFI_ERROR_CODE(status)); | |||||
free(handles); | |||||
} | |||||
} else { | |||||
printf("Error getting handles for kernel KMS %lu\n", | |||||
EFI_ERROR_CODE(status)); | |||||
return; | |||||
} | |||||
nin = sz / sizeof(EFI_HANDLE); | |||||
for (n = 0; n < nin; n++) { | |||||
status = BS->OpenProtocol(handles[n], &EfiKmsProtocolGuid, | |||||
(void**)&kms, IH, handles[n], | |||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL); | |||||
if (EFI_ERROR(status)) { | |||||
printf("Error getting protocol for kernel KMS %lu\n", | |||||
EFI_ERROR_CODE(status)); | |||||
return; | |||||
} | |||||
if (!memcmp(&KernelKeyInjectorGuid, &(kms->ServiceId), | |||||
sizeof(EFI_GUID))) { | |||||
client.ClientIdSize = sizeof(struct preloaded_file *); | |||||
client.ClientId = kfp; | |||||
client.ClientNameType = EFI_KMS_DATA_TYPE_UTF8; | |||||
client.ClientNameCount = strlen(kfp->f_name); | |||||
client.ClientName = kfp->f_name; | |||||
status = kms->RegisterClient(kms, &client, NULL, NULL); | |||||
if (EFI_ERROR(status)) { | |||||
printf("Error registering client for kernel KMS %lu\n", | |||||
EFI_ERROR_CODE(status)); | |||||
} | |||||
BS->CloseProtocol(handles[n], &EfiKmsProtocolGuid, | |||||
IH, handles[n]); | |||||
free(handles); | |||||
return; | |||||
} | |||||
BS->CloseProtocol(handles[n], &EfiKmsProtocolGuid, | |||||
IH, handles[n]); | |||||
} | |||||
} | |||||
static int | static int | ||||
bi_load_efi_data(struct preloaded_file *kfp) | bi_load_efi_data(struct preloaded_file *kfp) | ||||
{ | { | ||||
EFI_MEMORY_DESCRIPTOR *mm; | EFI_MEMORY_DESCRIPTOR *mm; | ||||
EFI_PHYSICAL_ADDRESS addr; | EFI_PHYSICAL_ADDRESS addr; | ||||
EFI_STATUS status; | EFI_STATUS status; | ||||
size_t efisz; | size_t efisz; | ||||
UINTN efi_mapkey; | UINTN efi_mapkey; | ||||
UINTN mmsz, pages, retry, sz; | UINTN mmsz, pages, retry, sz; | ||||
UINT32 mmver; | UINT32 mmver; | ||||
struct efi_map_header *efihdr; | struct efi_map_header *efihdr; | ||||
key_inject_set_client(kfp); | |||||
#if defined(__amd64__) || defined(__aarch64__) | #if defined(__amd64__) || defined(__aarch64__) | ||||
struct efi_fb efifb; | struct efi_fb efifb; | ||||
if (efi_find_framebuffer(&efifb) == 0) { | if (efi_find_framebuffer(&efifb) == 0) { | ||||
printf("EFI framebuffer information:\n"); | printf("EFI framebuffer information:\n"); | ||||
printf("addr, size 0x%jx, 0x%jx\n", efifb.fb_addr, | printf("addr, size 0x%jx, 0x%jx\n", efifb.fb_addr, | ||||
efifb.fb_size); | efifb.fb_size); | ||||
printf("dimensions %d x %d\n", efifb.fb_width, | printf("dimensions %d x %d\n", efifb.fb_width, | ||||
▲ Show 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | #if defined(LOADER_FDT_SUPPORT) | ||||
/* Pad to a page boundary */ | /* Pad to a page boundary */ | ||||
if (dtb_size) | if (dtb_size) | ||||
addr += roundup(dtb_size, PAGE_SIZE); | addr += roundup(dtb_size, PAGE_SIZE); | ||||
#endif | #endif | ||||
kfp = file_findfile(NULL, "elf kernel"); | kfp = file_findfile(NULL, "elf kernel"); | ||||
if (kfp == NULL) | if (kfp == NULL) | ||||
kfp = file_findfile(NULL, "elf64 kernel"); | kfp = file_findfile(NULL, "elf64 kernel"); | ||||
if (kfp == NULL) | if (kfp == NULL) | ||||
panic("can't find kernel file"); | panic("can't find kernel file"); | ||||
kernend = 0; /* fill it in later */ | kernend = 0; /* fill it in later */ | ||||
file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); | file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); | ||||
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); | file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); | ||||
#if defined(LOADER_FDT_SUPPORT) | #if defined(LOADER_FDT_SUPPORT) | ||||
if (dtb_size) | if (dtb_size) | ||||
file_addmetadata(kfp, MODINFOMD_DTBP, sizeof dtbp, &dtbp); | file_addmetadata(kfp, MODINFOMD_DTBP, sizeof dtbp, &dtbp); | ||||
else | else | ||||
printf("WARNING! Trying to fire up the kernel, but no " | printf("WARNING! Trying to fire up the kernel, but no " | ||||
Show All 38 Lines |