From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c0c::241; helo=mail-wr0-x241.google.com; envelope-from=leif.lindholm@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wr0-x241.google.com (mail-wr0-x241.google.com [IPv6:2a00:1450:400c:c0c::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 795392034C083 for ; Sun, 22 Oct 2017 07:36:57 -0700 (PDT) Received: by mail-wr0-x241.google.com with SMTP id p96so1099966wrb.7 for ; Sun, 22 Oct 2017 07:40:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=NVKYsWzWFCJx+ijtc54MI1UBZttRRHZrPK4Mw/mQfmM=; b=GDdNBINWQqsrWOy3RLYgIcA/jg5wCWDWFkTJS8wm0fOCn2FA4Bxx5KINQXaA2OcYCB go4Yc9nBtNe2oYDzwufzAlVu8u7mBa5qqQcF9fhipeZYyql0Ygdba4bhcGhO1mQCWkVS 6TVITKLK7Hiux6GUuDohqfo1qx90yGtgocOes= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=NVKYsWzWFCJx+ijtc54MI1UBZttRRHZrPK4Mw/mQfmM=; b=GUp+JEDqTLW7GxAQHFDWZ9LXZL3P7LTQpgXS6X8Ms0BvAkUnp4ujjbIC3o/eOkvYBh wQSx6GPrWHm+4NdqTmqXH/CA0Wa8wElYJEyD+CYO9nO70zsv5hHBQ+YUSBzH43/NqdRt ggjd/m9iF6m8um0m31iR4IJu1padqabFAjYGIXIuBwim6R7JGMHH0h+MXAAuEYnue6ql rfZqCS2TYpmmjEN4u1TbSF1DKE/mip7Gic1cefryxZxJZkgKtJNK2hvPLq3SOscT7WiP zD2zMK359CcDDa5PpfpxumFM8f6rfEZcucRyYV9QRirnQEJ1pRnIcI1lnFrjaayzgOD1 X2bw== X-Gm-Message-State: AMCzsaUY6EPxfMaGWk7nIUr+kcoJTmbgrtfRbZW+fFKU8L0mPbHWxMja keb3prG57nqVP4zcAHadfL6pxw== X-Google-Smtp-Source: ABhQp+TvXHVoz4idF0UAu9U10FhQaSFO/SKIM7ImdpIsu3XTq+Lw3t9zuzdSgkYs7SDQKTMHWbCPJw== X-Received: by 10.223.162.10 with SMTP id p10mr9630088wra.80.1508683236813; Sun, 22 Oct 2017 07:40:36 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id p28sm7034159wmf.2.2017.10.22.07.40.35 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 22 Oct 2017 07:40:35 -0700 (PDT) Date: Sun, 22 Oct 2017 15:40:33 +0100 From: Leif Lindholm To: Ard Biesheuvel Cc: edk2-devel@lists.01.org, lersek@redhat.com, daniel.thompson@linaro.org Message-ID: <20171022144033.rtjlaacp66dvthsk@bivouac.eciton.net> References: <20171021131049.23844-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 In-Reply-To: <20171021131049.23844-1-ard.biesheuvel@linaro.org> User-Agent: NeoMutt/20170113 (1.7.2) Subject: Re: [RFC PATCH] ArmPkg: add driver to add distro installer HTTP boot options X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Oct 2017 14:36:58 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sat, Oct 21, 2017 at 02:10:49PM +0100, Ard Biesheuvel wrote: > To make it easier for power users to provision a 'desktop' system [as > opposed to a VM or server] from scratch, introduce a driver that adds > boot options to the boot menu that can launch network installers over > HTTP straight off the Internet. > > Currently, this only supports the 'mini.iso' style netboot installers > that Debian/Ubuntu provide: larger images that need to be mounted by > the installer when running under the Linux kernel are only supported > on ACPI systems with support for the NFIT table, and this was enabled > only recently (Linux v4.14) for arm64. For DT boot, there is currently > no way at all to expose ramdisks created by UEFI as block devices in > Linux. This is good stuff. > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > --- > > Posted as an RFC because: > a) Where does this belong? Surely not in ArmPkg but I had to put it somewhere Not ArmPkg. EmbeddedPkg would also be wrong. It feels to me like it shares a common thread with the ACPI/DT switcher and the console preference widget. > b) Currently, the way the options are created results in them taking priority > if no real boot options were set (i.e., for GRUB). > c) Is there a use case for downloading 300-500 MB installers off the Internet > for a one shot installation? Or should we just stick to the mini.iso flavors. > d) Did I miss any distros we may care about? I think answers to all three of the above questions can end up being somewhat platform-specific. But I also think figuring out how that may best be implementented can wait. I could see a case here for a new package of UI tweaks and utilities. It would also not be unreasonable to add items like this under MdeModulePkg/{Application|Library}. / Leif > ArmPkg/Drivers/OsInstallerMenuDxe/OsInstallerMenuDxe.c | 228 ++++++++++++++++++++ > ArmPkg/Drivers/OsInstallerMenuDxe/OsInstallerMenuDxe.inf | 42 ++++ > 2 files changed, 270 insertions(+) > > diff --git a/ArmPkg/Drivers/OsInstallerMenuDxe/OsInstallerMenuDxe.c b/ArmPkg/Drivers/OsInstallerMenuDxe/OsInstallerMenuDxe.c > new file mode 100644 > index 000000000000..7c5934935924 > --- /dev/null > +++ b/ArmPkg/Drivers/OsInstallerMenuDxe/OsInstallerMenuDxe.c > @@ -0,0 +1,228 @@ > +/** @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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +typedef struct { > + CONST CHAR16 *Name; > + CONST CHAR8 *Uri; > +} OS_INSTALLER_IMAGE; > + > +STATIC CONST OS_INSTALLER_IMAGE mOsInstallers[] = { > + { L"Install Debian Stretch over HTTP", > + "http://ftp.us.debian.org/debian/dists/stretch/main/installer-arm64/current/images/netboot/mini.iso" }, > + > + { L"Install Ubuntu 17.10 (Artful) over HTTP", > + "http://ports.ubuntu.com/ubuntu-ports/dists/artful/main/installer-arm64/current/images/netboot/mini.iso" }, > + > +// > +// The links below refer to 300-500 MB netboot images that need to be exposed to > +// the OS via a ramdisk after the OS loader boots the installer from it. > +// Currently, this requires ACPI/NFIT support, which was only enabled for arm64 > +// in Linux in version v4.14. For DT boot, there is currently no solution for > +// this. > +// > +// { L"Install openSUSE Tumbleweed over HTTP", > +// "http://download.opensuse.org/ports/aarch64/factory/iso/openSUSE-Tumbleweed-NET-aarch64-Current.iso" }, > +// > +// { L"Install Fedora Server 26 over HTTP", > +// "http://download.fedoraproject.org/pub/fedora-secondary/releases/26/Server/aarch64/iso/Fedora-Server-netinst-aarch64-26-1.5.iso" }, > +// > +// { L"Install Centos 7 over HTTP", > +// "http://mirror.centos.org/altarch/7/isos/aarch64/CentOS-7-aarch64-NetInstall.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, (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/ArmPkg/Drivers/OsInstallerMenuDxe/OsInstallerMenuDxe.inf b/ArmPkg/Drivers/OsInstallerMenuDxe/OsInstallerMenuDxe.inf > new file mode 100644 > index 000000000000..9bc5a81a78a1 > --- /dev/null > +++ b/ArmPkg/Drivers/OsInstallerMenuDxe/OsInstallerMenuDxe.inf > @@ -0,0 +1,42 @@ > +# > +# 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. > +# > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = OsInstallerMenuDxe > + FILE_GUID = 4def5019-3233-4925-98ef-db5c60b2aec4 > + 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 > -- > 2.11.0 >