summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2017-10-23 13:24:47 +0100
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2018-06-01 12:13:28 +0200
commit0a4791eea9bb3d3bcb61b72a23ea7e6835eab928 (patch)
tree2b77c1cfa329d65bf44833fb7735c06a0ad8f405
parentba32985a0631ef371b06cdbfe53f4dd6d11557ba (diff)
Platform/DeveloperBox: add menu option to HTTP boot the ERP Debian installer
Make it easier for the user to find the correct Debian network installer, by automatically adding a boot option that has the correct HTTP link. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-rw-r--r--Platform/Socionext/DeveloperBox/DeveloperBox.dsc2
-rw-r--r--Platform/Socionext/DeveloperBox/DeveloperBox.fdf2
-rw-r--r--Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.c208
-rw-r--r--Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.inf42
4 files changed, 254 insertions, 0 deletions
diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
index 3decc22e..3a397c17 100644
--- a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
+++ b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
@@ -708,3 +708,5 @@
<BuildOptions>
*_*_*_CC_FLAGS = -DFIRMWARE_VENDOR=\"$(FIRMWARE_VENDOR)\" -DBUILD_NUMBER=\"$(BUILD_NUMBER)\"
}
+
+ Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.inf
diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.fdf b/Platform/Socionext/DeveloperBox/DeveloperBox.fdf
index c36104da..434ff2d9 100644
--- a/Platform/Socionext/DeveloperBox/DeveloperBox.fdf
+++ b/Platform/Socionext/DeveloperBox/DeveloperBox.fdf
@@ -268,6 +268,8 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
INF Platform/Socionext/DeveloperBox/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+ INF Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.inf
+
[FV.FVMAIN_COMPACT]
FvAlignment = 16
BlockSize = 0x10000
diff --git a/Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.c b/Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.c
new file mode 100644
index 00000000..dcd5159b
--- /dev/null
+++ b/Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.c
@@ -0,0 +1,208 @@
+/** @file
+ *
+ * Copyright (c) 2016-2017, Linaro Limited. All rights reserved.
+ *
+ * This program and the accompanying materials are licensed and made available
+ * under the terms and conditions of the BSD License which accompanies this
+ * distribution. The full text of the license may be found at
+ * http://opensource.org/licenses/bsd-license.php
+ *
+ * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ */
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/SimpleNetwork.h>
+
+typedef struct {
+ CONST CHAR16 *Name;
+ CONST CHAR8 *Uri;
+} OS_INSTALLER_IMAGE;
+
+STATIC CONST OS_INSTALLER_IMAGE mOsInstallers[] = {
+ { L"Install Debian Stretch (Linaro ERP) over HTTP",
+ "http://people.linaro.org/~ard.biesheuvel/devbox/mini.iso" },
+};
+
+STATIC EFI_EVENT mRegisterProtocolEvent;
+STATIC VOID *mRegistration;
+
+STATIC
+EFI_STATUS
+CreateOsInstallerBootOptions (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_STATUS Status;
+ UINTN Idx;
+ EFI_DEV_PATH *Node;
+ UINTN Length;
+ EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ INTN OptionIndex;
+
+ BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
+ LoadOptionTypeBoot);
+ ASSERT (BootOptions != NULL);
+
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid,
+ (VOID **)&ParentDevicePath);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a: gBS->HandleProtocol returned %r\n",
+ __FUNCTION__, Status));
+ return Status;
+ }
+
+ for (Idx = 0; Idx < ARRAY_SIZE (mOsInstallers); Idx++) {
+ Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
+ if (Node == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeBootOptions;
+ }
+ Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
+ Node->Ipv4.Header.SubType = MSG_IPv4_DP;
+ SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
+
+ TmpDevicePath = AppendDevicePathNode (ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL*) Node);
+ FreePool (Node);
+ if (TmpDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeBootOptions;
+ }
+
+ //
+ // Update the URI node with the input boot file URI.
+ //
+ Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) +
+ AsciiStrSize (mOsInstallers[Idx].Uri);
+ Node = AllocatePool (Length);
+ if (Node == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ FreePool (TmpDevicePath);
+ goto FreeBootOptions;
+ }
+ Node->DevPath.Type = MESSAGING_DEVICE_PATH;
+ Node->DevPath.SubType = MSG_URI_DP;
+ SetDevicePathNodeLength (Node, Length);
+ CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ mOsInstallers[Idx].Uri, AsciiStrSize (mOsInstallers[Idx].Uri));
+ NewDevicePath = AppendDevicePathNode (TmpDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL*) Node);
+ FreePool (Node);
+ FreePool (TmpDevicePath);
+ if (NewDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeBootOptions;
+ }
+
+ //
+ // Create a new load option.
+ //
+ Status = EfiBootManagerInitializeLoadOption (&NewOption,
+ LoadOptionNumberUnassigned, LoadOptionTypeBoot,
+ LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_APP,
+ (CHAR16 *)mOsInstallers[Idx].Name, NewDevicePath, NULL, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ OptionIndex = EfiBootManagerFindLoadOption (&NewOption, BootOptions,
+ BootOptionCount);
+ if (OptionIndex == -1) {
+ //
+ // Add the new load option if it did not exist already
+ //
+ EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
+ }
+ EfiBootManagerFreeLoadOption (&NewOption);
+ FreePool (NewDevicePath);
+ }
+
+FreeBootOptions:
+
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+ return Status;
+}
+
+STATIC
+BOOLEAN
+MediaDisconnected (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid,
+ (VOID **)&Snp);
+ if (EFI_ERROR (Status) || !Snp->Mode->MediaPresentSupported) {
+ return FALSE;
+ }
+
+ Snp->GetStatus (Snp, NULL, NULL);
+
+ return !Snp->Mode->MediaPresent;
+}
+
+STATIC
+VOID
+OnRegisterProtocol (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Idx;
+
+ Status = gBS->LocateHandleBuffer (ByRegisterNotify,
+ &gEfiHttpServiceBindingProtocolGuid, mRegistration,
+ &HandleCount, &HandleBuffer);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ for (Idx = 0; Idx < HandleCount; Idx++) {
+ if (MediaDisconnected (HandleBuffer[Idx])) {
+ continue;
+ }
+
+ CreateOsInstallerBootOptions (HandleBuffer[Idx]);
+
+ //
+ // Create the options only a single time - we take care to only install
+ // them for a network interface that has a link, and we should try not to
+ // confuse the user by having 10 identical options when the system has 10
+ // network interfaces.
+ //
+ gBS->CloseEvent (Event);
+ break;
+ }
+ FreePool (HandleBuffer);
+}
+
+EFI_STATUS
+EFIAPI
+OsInstallerMenuDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ mRegisterProtocolEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiHttpServiceBindingProtocolGuid, TPL_CALLBACK,
+ OnRegisterProtocol, NULL, &mRegistration);
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.inf b/Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.inf
new file mode 100644
index 00000000..642d073f
--- /dev/null
+++ b/Platform/Socionext/DeveloperBox/OsInstallerMenuDxe/OsInstallerMenuDxe.inf
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2017, Linaro Limited. All rights reserved.
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = OsInstallerMenuDxe
+ FILE_GUID = fc4b3b8c-2a0b-47a2-8a95-affa51a01593
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 0.1
+ ENTRY_POINT = OsInstallerMenuDxeEntryPoint
+
+[Sources]
+ OsInstallerMenuDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ UefiBootManagerLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiHttpServiceBindingProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiSimpleNetworkProtocolGuid