Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save paigeadelethompson/4b6253bed79999e46c90f0d85e593958 to your computer and use it in GitHub Desktop.

Select an option

Save paigeadelethompson/4b6253bed79999e46c90f0d85e593958 to your computer and use it in GitHub Desktop.
#define EFI_GLOBAL_VARIABLE_GUID \
{ 0x8B843E20, 0x8110, 0x4318, { 0xCC, 0x69, 0x87, 0xCE, 0x47, 0x46, 0x61, 0x03 } }
// Standard UEFI Terminal Type GUIDs used by BIOS redirection
static EFI_GUID gEfiPcAnsiGuid = { 0xE0C1ECE1, 0x5544, 0x11D4, { 0x9A, 0x39, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } };
static EFI_GUID gEfiVt100Guid = { 0xDFA666B1, 0x1E59, 0x11D4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } };
static EFI_GUID gEfiVt100PlusGuid = { 0x7BA0BCC0, 0x1B58, 0x4114, { 0xA7, 0xA9, 0x54, 0x90, 0xA3, 0x84, 0x2B, 0x8B } };
static EFI_GUID gEfiVtUtf8Guid = { 0xAD15A0D6, 0x8BEC, 0x4B4A, { 0xBA, 0x20, 0x00, 0x80, 0xC7, 0x7E, 0x59, 0x37 } };
EFI_STATUS FilterConsoleVariable(CHAR16 *VarName) {
EFI_GUID GlobalGuid = EFI_GLOBAL_VARIABLE_GUID;
UINTN Size = 0;
EFI_DEVICE_PATH_PROTOCOL *DevicePathList = NULL;
EFI_STATUS Status;
// Determine required buffer size
Status = gRT->GetVariable(VarName, &GlobalGuid, NULL, &Size, NULL);
if (Status == EFI_BUFFER_TOO_SMALL) {
DevicePathList = AllocatePool(Size);
Status = gRT->GetVariable(VarName, &GlobalGuid, NULL, &Size, DevicePathList);
}
if (EFI_ERROR(Status) || !DevicePathList) return Status;
// Proceed to parse and strip nodes...
}
EFI_DEVICE_PATH_PROTOCOL *CurrentPath = DevicePathList;
EFI_DEVICE_PATH_PROTOCOL *NewPathList = NULL;
while (!IsDevicePathEnd(CurrentPath)) {
BOOLEAN IsSerialRedirection = FALSE;
EFI_DEVICE_PATH_PROTOCOL *Node = CurrentPath;
// Inspect nodes within the current instance channel
while (!IsDevicePathEndType(Node)) {
if (Node->Type == MESSAGING_DEVICE_PATH) {
if (Node->SubType == MSG_UART_DP) {
IsSerialRedirection = TRUE;
}
else if (Node->SubType == MSG_VENDOR_DP) {
VENDOR_DEVICE_PATH *VendorNode = (VENDOR_DEVICE_PATH *)Node;
if (CompareGuid(&VendorNode->Guid, &gEfiPcAnsiGuid) ||
CompareGuid(&VendorNode->Guid, &gEfiVt100Guid) ||
CompareGuid(&VendorNode->Guid, &gEfiVt100PlusGuid) ||
CompareGuid(&VendorNode->Guid, &gEfiVtUtf8Guid)) {
IsSerialRedirection = TRUE;
}
}
}
Node = NextDevicePathNode(Node);
}
// If it's a clean graphic/keyboard node, append it to our new safe path list
if (!IsSerialRedirection) {
NewPathList = AppendDevicePathInstance(NewPathList, CurrentPath);
}
CurrentPath = NextDevicePathInstance(CurrentPath);
}
// Update NVRAM
UINTN NewSize = GetDevicePathSize(NewPathList);
Status = gRT->SetVariable(VarName, &GlobalGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
NewSize, NewPathList);
// Re-evaluate the active interfaces
if (!EFI_ERROR(Status)) {
// Disconnect and reconnect system console handles to apply modifications
gBS->DisconnectController(gST->ConsoleOutHandle, NULL, NULL);
gBS->ConnectController(gST->ConsoleOutHandle, NULL, NULL, TRUE);
}
FreePool(DevicePathList);
if (NewPathList) FreePool(NewPathList);
return Status;
@paigeadelethompson

Copy link
Copy Markdown
Author

To detect if the BIOS is performing serial console redirection and to control it from the FreeBSD bootloader, you must interact with the UEFI ⁠EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL⁠ and the ⁠EFI_CONSOLE_CONTROL_PROTOCOL⁠ (where supported).

@paigeadelethompson

Copy link
Copy Markdown
Author

ConOut

@paigeadelethompson

Copy link
Copy Markdown
Author

MSG_UART_DP

@paigeadelethompson

Copy link
Copy Markdown
Author

Goal: if in comconsole both aerial and efi are set at the same time, check if bios is redirecting efi to serial itself, if it is interrupt it at this point and let the bootloader write to efi and serial for itself.

@paigeadelethompson

Copy link
Copy Markdown
Author

Question: why does the bios know when the boot loader has started the kernel, maybe tje bios just needs to reinitialize the serial port to take ownership of it and this abort console redirection by the bios?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment