From patchwork Thu Jul 6 13:29:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jun Nie X-Patchwork-Id: 107143 Delivered-To: patch@linaro.org Received: by 10.182.135.102 with SMTP id pr6csp2169984obb; Thu, 6 Jul 2017 06:29:28 -0700 (PDT) X-Received: by 10.101.86.8 with SMTP id l8mr71688pgs.271.1499347767877; Thu, 06 Jul 2017 06:29:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499347767; cv=none; d=google.com; s=arc-20160816; b=L92lPch1+JoHN6gfcZbyl7DH1/2hlSFlA1nfI/bjEu+4Mp4QdH80Om/GV7R7bimqJ0 kafGgPJEhJv2IJ1BTV9+lRdozjLKeuQuyre9wMJQ05G8Z6PAEZwgG91WyqM6I6LLaOjO SfVJhU13K8q0vTFgIUb5MbAgeK10FQr9fFnLxD21jgtRSiqRkF/CxvWABw3G827QbhK2 kP8sqiU4y2PGshpFTCslKUOC+Io9N6GCQXPJ9bYAJuUQ6oKBpMEXwwuR4DtCL/MO+Umf MjKYG/GBkB70RtuTcZ2HH5Jc++pFXislnL+dsEndUykSf3Z7mD3Wn05Tt8pDhXe3t4kh +9hw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=vLXuUy+95o2I4hc5eOSjIpJoFuLhQ2qc2k6Z35FZwkM=; b=bu7KMkgzvzXnA+7a9tKdDNThSOzofU2P+iToSlgWqDDHry/ux3NCya9aszaCrkLCui So7gTXyk8UeLwbw4kIcbkiZh/HUDEZsHCMGgPTZMkj7QnS/xPwDLGJITECW7LtESfXIj eDtcETK9FYUer1Rl502srjnPuT5DMOb0Z4qmeBvFhI6Fwv4RrK/mdFy6OcDBQ7n8cEE1 MFY49qgedRhPMjx7mgu5f5AyCrZZ6h6412Ua6MuI1NgI+/tTd3UElWjS6Zyweb2Gnn7c aQel7CIWH1jjz2X7A4TnhHiudotMK4pqZSfsznmqI1VVHO5jXsbR9g9R5Dp+tLhBPUJU o+gw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.b=j6ptpfAi; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id b61si142336plc.101.2017.07.06.06.29.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 06 Jul 2017 06:29:27 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.b=j6ptpfAi; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 0F2D521CC535D; Thu, 6 Jul 2017 06:27:46 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pf0-x22f.google.com (mail-pf0-x22f.google.com [IPv6:2607:f8b0:400e:c00::22f]) (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 A2E9421CC5353 for ; Thu, 6 Jul 2017 06:27:44 -0700 (PDT) Received: by mail-pf0-x22f.google.com with SMTP id c73so1055526pfk.2 for ; Thu, 06 Jul 2017 06:29:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=XaSZqoaL5MlzN8KvYL05RYtXrEIeDgmcZaHxqZmrUM8=; b=j6ptpfAiWVqwYpVhfZMFcIwYBh3j8T/I0i3L+EeAbMBcNu1WhQJAE5ccy+DQ0p3hn8 4wn1lKgzTJMUgR1YYN/mKwS0gfHaC4KVUYvyySKDn5pyvO07TTembFHEMRs7bmqL5Byj ongbxFZ863c7FZdWbeAdsYDOQgx7d7VYbV5r8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=XaSZqoaL5MlzN8KvYL05RYtXrEIeDgmcZaHxqZmrUM8=; b=dAoJ1fXjcPJTsb4v8qu4Ryy/YJAOrQElfgU1v/T0L6lnYrecOrpnIMDwvl/NjU22IC ZZQ5wS2WyB9PNXX8Las6a/qycCvfP1JiHyOU86STg7/FEzlqRdSJZkgIizeiLdOnYEf2 a67XyCphUce10Cv4SHEnpH/ZBae5AfbEVxqKQHeQFhuUzDaLwf+RStBmw4xPBqKL61oV 9i079a6OhMU9BzSibccErPkbkBrUfFgq7/6ma3+z8pdZFuOlMmtWxhYLaixSosDdZ5vj 0vK+ZUdYeecSaizgvzVWwQWHS4ZOV1gv86K5RG9urU/ci4aQ/bcmt+JReD5z7uiyN4gr jyBw== X-Gm-Message-State: AIVw113dg3TnFS4AoZ6JbdzogSrb0lSc3vnfod2JEAyyKW65k/oZEPNP nU5sYjxzDWW9o3qJ X-Received: by 10.99.105.200 with SMTP id e191mr26068260pgc.215.1499347764612; Thu, 06 Jul 2017 06:29:24 -0700 (PDT) Received: from localhost.localdomain ([113.53.228.78]) by smtp.gmail.com with ESMTPSA id 197sm253754pga.58.2017.07.06.06.29.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 06 Jul 2017 06:29:23 -0700 (PDT) From: Jun Nie To: haojian.zhuang@linaro.org, leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, edk2-devel@lists.01.org, linaro-uefi@lists.linaro.org Date: Thu, 6 Jul 2017 21:29:05 +0800 Message-Id: <1499347746-16786-1-git-send-email-jun.nie@linaro.org> X-Mailer: git-send-email 1.9.1 Subject: [edk2] [PATCH v2 1/2] EmbeddedPkg/AndroidBoot: boot android kernel from storage 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: , Cc: jason.liu@linaro.org, shawn.guo@linaro.org MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Add an android kernel loader that could load kernel from storage device. This patch is from Haojian's code. The minor change is that alternative dtb is searched in second loader binary of Android bootimage if dtb is not found after Linux kernel. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jun Nie --- .../Application/AndroidBoot/AndroidBootApp.c | 129 ++++++++ .../Application/AndroidBoot/AndroidBootApp.inf | 64 ++++ EmbeddedPkg/Include/Library/AbootimgLib.h | 65 ++++ EmbeddedPkg/Include/Protocol/Abootimg.h | 47 +++ EmbeddedPkg/Library/AbootimgLib/AbootimgLib.c | 350 +++++++++++++++++++++ EmbeddedPkg/Library/AbootimgLib/AbootimgLib.inf | 48 +++ 6 files changed, 703 insertions(+) create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf create mode 100644 EmbeddedPkg/Include/Library/AbootimgLib.h create mode 100644 EmbeddedPkg/Include/Protocol/Abootimg.h create mode 100644 EmbeddedPkg/Library/AbootimgLib/AbootimgLib.c create mode 100644 EmbeddedPkg/Library/AbootimgLib/AbootimgLib.inf -- 1.9.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c new file mode 100644 index 0000000..9ed931b --- /dev/null +++ b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c @@ -0,0 +1,129 @@ +/** @file + + Copyright (c) 2013-2014, ARM Ltd. All rights reserved.
+ Copyright (c) 2017, Linaro. 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 + +#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype))) + +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) + +EFI_STATUS +EFIAPI +AndroidBootAppEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + CHAR16 *BootPathStr; + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; + EFI_DEVICE_PATH *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *Node, *NextNode; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + UINT32 MediaId, BlockSize; + VOID *Buffer; + EFI_HANDLE Handle; + UINTN Size; + + BootPathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath); + ASSERT (BootPathStr != NULL); + Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); + ASSERT_EFI_ERROR(Status); + DevicePath = (EFI_DEVICE_PATH *)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (BootPathStr); + ASSERT (DevicePath != NULL); + + /* Find DevicePath node of Partition */ + NextNode = DevicePath; + while (1) { + Node = NextNode; + if (IS_DEVICE_PATH_NODE (Node, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP)) { + break; + } + NextNode = NextDevicePathNode (Node); + } + + Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &Handle); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->OpenProtocol ( + Handle, + &gEfiBlockIoProtocolGuid, + (VOID **) &BlockIo, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Failed to get BlockIo: %r\n", Status)); + return Status; + } + + MediaId = BlockIo->Media->MediaId; + BlockSize = BlockIo->Media->BlockSize; + Buffer = AllocatePages (1); + if (Buffer == NULL) { + return EFI_BUFFER_TOO_SMALL; + } + /* Load header of boot.img */ + Status = BlockIo->ReadBlocks ( + BlockIo, + MediaId, + 0, + BlockSize, + Buffer + ); + Status = AbootimgGetImgSize (Buffer, &Size); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Failed to get Abootimg Size: %r\n", Status)); + return Status; + } + Size = ALIGN (Size, BlockSize); + FreePages (Buffer, 1); + + /* Both PartitionStart and PartitionSize are counted as block size. */ + Buffer = AllocatePages (EFI_SIZE_TO_PAGES (Size)); + if (Buffer == NULL) { + return EFI_BUFFER_TOO_SMALL; + } + + /* Load header of boot.img */ + Status = BlockIo->ReadBlocks ( + BlockIo, + MediaId, + 0, + Size, + Buffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Failed to read blocks: %r\n", Status)); + goto EXIT; + } + + Status = AbootimgBoot (Buffer, Size); + +EXIT: + return Status; +} diff --git a/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf new file mode 100644 index 0000000..8f6c8186 --- /dev/null +++ b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf @@ -0,0 +1,64 @@ +#/** @file +# +# Copyright (c) 2013-2015, ARM Ltd. All rights reserved.
+# Copyright (c) 2017, Linaro. 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 = AndroidBootApp + FILE_GUID = 3a738b36-b9c5-4763-abbd-6cbd4b25f9ff + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = AndroidBootAppEntryPoint + +[Sources.common] + AndroidBootApp.c + +[LibraryClasses] + AbootimgLib + BaseLib + BaseMemoryLib + BdsLib + DebugLib + DevicePathLib + DxeServicesTableLib + FdtLib + MemoryAllocationLib + PcdLib + PrintLib + UefiApplicationEntryPoint + UefiBootServicesTableLib + UefiLib + UefiRuntimeServicesTableLib + +[Protocols] + gAndroidFastbootPlatformProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathFromTextProtocolGuid + gEfiSimpleTextOutProtocolGuid + gEfiSimpleTextInProtocolGuid + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[Packages.ARM, Packages.AARCH64] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[Guids] + gFdtTableGuid + +[Pcd] + gEmbeddedTokenSpaceGuid.PcdAndroidBootDevicePath diff --git a/EmbeddedPkg/Include/Library/AbootimgLib.h b/EmbeddedPkg/Include/Library/AbootimgLib.h new file mode 100644 index 0000000..c0372d4 --- /dev/null +++ b/EmbeddedPkg/Include/Library/AbootimgLib.h @@ -0,0 +1,65 @@ +/** @file + + Copyright (c) 2013-2014, ARM Ltd. All rights reserved.
+ Copyright (c) 2017, Linaro. + + 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. + +**/ + +#ifndef __ABOOTIMG_H__ +#define __ABOOTIMG_H__ + +#include +#include +#include + +#include +#include + +#define BOOTIMG_KERNEL_ARGS_SIZE 512 + +#define BOOT_MAGIC "ANDROID!" +#define BOOT_MAGIC_LENGTH (sizeof (BOOT_MAGIC) - 1) + +/* It's the value of arm64 efi stub kernel */ +#define KERNEL_IMAGE_STEXT_OFFSET 0x12C +#define KERNEL_IMAGE_RAW_SIZE_OFFSET 0x130 + +#define FDT_SIZE_OFFSET 0x4 + +typedef struct { + CHAR8 BootMagic[BOOT_MAGIC_LENGTH]; + UINT32 KernelSize; + UINT32 KernelAddress; + UINT32 RamdiskSize; + UINT32 RamdiskAddress; + UINT32 SecondStageBootloaderSize; + UINT32 SecondStageBootloaderAddress; + UINT32 KernelTaggsAddress; + UINT32 PageSize; + UINT32 Reserved[2]; + CHAR8 ProductName[16]; + CHAR8 KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE]; + UINT32 Id[32]; +} ANDROID_BOOTIMG_HEADER; + +EFI_STATUS +AbootimgGetImgSize ( + IN VOID *BootImg, + OUT UINTN *ImgSize + ); + +EFI_STATUS +AbootimgBoot ( + IN VOID *Buffer, + IN UINTN BufferSize + ); + +#endif /* __ABOOTIMG_H__ */ diff --git a/EmbeddedPkg/Include/Protocol/Abootimg.h b/EmbeddedPkg/Include/Protocol/Abootimg.h new file mode 100644 index 0000000..c85dad2 --- /dev/null +++ b/EmbeddedPkg/Include/Protocol/Abootimg.h @@ -0,0 +1,47 @@ +/** @file + + Copyright (c) 2017, Linaro. 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. + +**/ + +#ifndef __ABOOTIMG_PROTOCOL_H__ +#define __ABOOTIMG_PROTOCOL_H__ + +// +// Protocol interface structure +// +typedef struct _ABOOTIMG_PROTOCOL ABOOTIMG_PROTOCOL; + +// +// Function Prototypes +// +typedef +EFI_STATUS +(EFIAPI *ABOOTIMG_APPEND_KERNEL_ARGS) ( + IN CHAR16 *Args, + IN UINTN Size + ); + +typedef +EFI_STATUS +(EFIAPI *ABOOTIMG_UPDATE_DTB) ( + IN EFI_PHYSICAL_ADDRESS OrigDtbBase; + OUT EFI_PHYSICAL_ADDRESS *NewDtbBase; + ); + +struct _ABOOTIMG_PROTOCOL { + ABOOTIMG_APPEND_KERNEL_ARGS AppendArgs; + ABOOTIMG_UPDATE_DTB UpdateDtb; +}; + +extern EFI_GUID gAbootimgProtocolGuid; + +#endif /* __ABOOTIMG_PROTOCOL_H__ */ diff --git a/EmbeddedPkg/Library/AbootimgLib/AbootimgLib.c b/EmbeddedPkg/Library/AbootimgLib/AbootimgLib.c new file mode 100644 index 0000000..ea30a01 --- /dev/null +++ b/EmbeddedPkg/Library/AbootimgLib/AbootimgLib.c @@ -0,0 +1,350 @@ +/** @file + + Copyright (c) 2013-2014, ARM Ltd. All rights reserved.
+ Copyright (c) 2017, Linaro. 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 + +// Check Val (unsigned) is a power of 2 (has only one bit set) +#define IS_POWER_OF_2(Val) (Val != 0 && ((Val & (Val - 1)) == 0)) + +typedef struct { + MEMMAP_DEVICE_PATH Node1; + EFI_DEVICE_PATH_PROTOCOL End; +} MEMORY_DEVICE_PATH; + +STATIC ABOOTIMG_PROTOCOL *mAbootimg; + +STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate = +{ + { + { + HARDWARE_DEVICE_PATH, + HW_MEMMAP_DP, + { + (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), + (UINT8)((sizeof (MEMMAP_DEVICE_PATH)) >> 8), + }, + }, // Header + 0, // StartingAddress (set at runtime) + 0 // EndingAddress (set at runtime) + }, // Node1 + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } + } // End +}; + +EFI_STATUS +AbootimgGetImgSize ( + IN VOID *BootImg, + OUT UINTN *ImgSize + ) +{ + ANDROID_BOOTIMG_HEADER *Header; + + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; + + if (AsciiStrnCmp (Header->BootMagic, BOOT_MAGIC, BOOT_MAGIC_LENGTH) != 0) { + return EFI_INVALID_PARAMETER; + } + + ASSERT (IS_POWER_OF_2 (Header->PageSize)); + + /* Get real size of abootimg */ + *ImgSize = ALIGN_VALUE (Header->KernelSize, Header->PageSize) + + ALIGN_VALUE (Header->RamdiskSize, Header->PageSize) + + ALIGN_VALUE (Header->SecondStageBootloaderSize, Header->PageSize) + + Header->PageSize; + return EFI_SUCCESS; +} + +EFI_STATUS +AbootimgGetKernelInfo ( + IN VOID *BootImg, + OUT VOID **Kernel, + OUT UINTN *KernelSize + ) +{ + ANDROID_BOOTIMG_HEADER *Header; + + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; + + if (AsciiStrnCmp (Header->BootMagic, BOOT_MAGIC, BOOT_MAGIC_LENGTH) != 0) { + return EFI_INVALID_PARAMETER; + } + + if (Header->KernelSize == 0) { + return EFI_NOT_FOUND; + } + + ASSERT (IS_POWER_OF_2 (Header->PageSize)); + + *KernelSize = Header->KernelSize; + *Kernel = BootImg + Header->PageSize; + return EFI_SUCCESS; +} + +EFI_STATUS +AbootimgGetRamdiskInfo ( + IN VOID *BootImg, + OUT VOID **Ramdisk, + OUT UINTN *RamdiskSize + ) +{ + ANDROID_BOOTIMG_HEADER *Header; + UINT8 *BootImgBytePtr; + + // Cast to UINT8 so we can do pointer arithmetic + BootImgBytePtr = (UINT8 *) BootImg; + + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; + + if (AsciiStrnCmp (Header->BootMagic, BOOT_MAGIC, BOOT_MAGIC_LENGTH) != 0) { + return EFI_INVALID_PARAMETER; + } + + ASSERT (IS_POWER_OF_2 (Header->PageSize)); + + *RamdiskSize = Header->RamdiskSize; + + if (Header->RamdiskSize != 0) { + *Ramdisk = (VOID *) (BootImgBytePtr + + Header->PageSize + + ALIGN_VALUE (Header->KernelSize, Header->PageSize)); + } + return EFI_SUCCESS; +} + +EFI_STATUS +AbootimgGetSecondBootLoaderInfo ( + IN VOID *BootImg, + OUT VOID **Second, + OUT UINTN *SecondSize + ) +{ + ANDROID_BOOTIMG_HEADER *Header; + UINT8 *BootImgBytePtr; + + // Cast to UINT8 so we can do pointer arithmetic + BootImgBytePtr = (UINT8 *) BootImg; + + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; + + if (AsciiStrnCmp (Header->BootMagic, BOOT_MAGIC, BOOT_MAGIC_LENGTH) != 0) { + return EFI_INVALID_PARAMETER; + } + + ASSERT (IS_POWER_OF_2 (Header->PageSize)); + + *SecondSize = Header->SecondStageBootloaderSize; + + if (Header->SecondStageBootloaderSize != 0) { + *Second = (VOID *) (BootImgBytePtr + + Header->PageSize + + ALIGN_VALUE (Header->KernelSize, Header->PageSize) + + ALIGN_VALUE (Header->RamdiskSize, Header->PageSize)); + } + return EFI_SUCCESS; +} + +EFI_STATUS +AbootimgGetKernelArgs ( + IN VOID *BootImg, + OUT CHAR8 *KernelArgs + ) +{ + ANDROID_BOOTIMG_HEADER *Header; + + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; + AsciiStrnCpyS (KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE, Header->KernelArgs, + BOOTIMG_KERNEL_ARGS_SIZE); + + return EFI_SUCCESS; +} + +EFI_STATUS +AbootimgInstallFdt ( + IN VOID *BootImg, + IN EFI_PHYSICAL_ADDRESS FdtBase, + OUT VOID *KernelArgs + ) +{ + VOID *Ramdisk; + UINTN RamdiskSize; + CHAR8 ImgKernelArgs[BOOTIMG_KERNEL_ARGS_SIZE]; + INTN err; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS NewFdtBase; + + Status = gBS->LocateProtocol (&gAbootimgProtocolGuid, NULL, (VOID **) &mAbootimg); + if (EFI_ERROR (Status)) { + return Status; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = AbootimgGetRamdiskInfo ( + BootImg, + &Ramdisk, + &RamdiskSize + ); + if (EFI_ERROR (Status)) { + return Status; + } + Status = AbootimgGetKernelArgs ( + BootImg, + ImgKernelArgs + ); + if (EFI_ERROR (Status)) { + return Status; + } + // Get kernel arguments from Android boot image + AsciiStrToUnicodeStrS (ImgKernelArgs, KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE >> 1); + // Set the ramdisk in command line arguments + UnicodeSPrint ( + (CHAR16 *)KernelArgs + StrLen (KernelArgs), BOOTIMG_KERNEL_ARGS_SIZE, + L" initrd=0x%x,0x%x", + (UINTN)Ramdisk, (UINTN)RamdiskSize + ); + + // Append platform kernel arguments + Status = mAbootimg->AppendArgs (KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = mAbootimg->UpdateDtb (FdtBase, &NewFdtBase); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Sanity checks on the new FDT blob. + // + err = fdt_check_header ((VOID*)(UINTN)NewFdtBase); + if (err != 0) { + Print (L"ERROR: Device Tree header not valid (err:%d)\n", err); + return EFI_INVALID_PARAMETER; + } + + Status = gBS->InstallConfigurationTable ( + &gFdtTableGuid, + (VOID *)(UINTN)NewFdtBase + ); + return Status; +} + +EFI_STATUS +AbootimgBoot ( + IN VOID *Buffer, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + VOID *Kernel; + UINTN KernelSize; + VOID *SecondLoader; + UINTN SecondLoaderSize; + MEMORY_DEVICE_PATH KernelDevicePath; + EFI_HANDLE ImageHandle; + EFI_PHYSICAL_ADDRESS FdtBase; + VOID *NewKernelArg; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + INTN Err; + + Status = AbootimgGetKernelInfo ( + Buffer, + &Kernel, + &KernelSize + ); + if (EFI_ERROR (Status)) { + return Status; + } + + /* For flatten image, Fdt is attached at the end of kernel. + Get real kernel size. + */ + KernelSize = *(UINT32 *)((EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KERNEL_IMAGE_STEXT_OFFSET) + + *(UINT32 *)((EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KERNEL_IMAGE_RAW_SIZE_OFFSET); + + NewKernelArg = AllocateZeroPool (BOOTIMG_KERNEL_ARGS_SIZE); + if (NewKernelArg == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + + /* FDT is at the end of kernel image */ + FdtBase = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KernelSize; + // + // Sanity checks on the original FDT blob. + // + Err = fdt_check_header ((VOID*)(UINTN)FdtBase); + if (Err != 0) { + /* Check whether FDT is located in second boot loader */ + Status = AbootimgGetSecondBootLoaderInfo ( + Buffer, + &SecondLoader, + &SecondLoaderSize + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Err = fdt_check_header ((VOID*)(UINTN)SecondLoader); + if (Err != 0) { + DEBUG ((DEBUG_ERROR, "ERROR: Device Tree header not valid (Err:%d)\n", Err)); + return EFI_INVALID_PARAMETER; + } + FdtBase = (EFI_PHYSICAL_ADDRESS)SecondLoader; + } + + Status = AbootimgInstallFdt (Buffer, FdtBase, NewKernelArg); + if (EFI_ERROR (Status)) { + FreePool (NewKernelArg); + return EFI_INVALID_PARAMETER; + } + + KernelDevicePath = MemoryDevicePathTemplate; + + // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to + // appease GCC. + KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel; + KernelDevicePath.Node1.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize; + + Status = gBS->LoadImage (TRUE, gImageHandle, (EFI_DEVICE_PATH *)&KernelDevicePath, (VOID*)(UINTN)Kernel, KernelSize, &ImageHandle); + + // Set kernel arguments + Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); + ImageInfo->LoadOptions = NewKernelArg; + ImageInfo->LoadOptionsSize = StrLen (NewKernelArg) * sizeof (CHAR16); + + // Before calling the image, enable the Watchdog Timer for the 5 Minute period + gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL); + // Start the image + Status = gBS->StartImage (ImageHandle, NULL, NULL); + // Clear the Watchdog Timer after the image returns + gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); + return EFI_SUCCESS; +} diff --git a/EmbeddedPkg/Library/AbootimgLib/AbootimgLib.inf b/EmbeddedPkg/Library/AbootimgLib/AbootimgLib.inf new file mode 100644 index 0000000..461dcb8 --- /dev/null +++ b/EmbeddedPkg/Library/AbootimgLib/AbootimgLib.inf @@ -0,0 +1,48 @@ +#/** @file +# +# Copyright (c) 2013-2015, ARM Ltd. All rights reserved.
+# Copyright (c) 2017, Linaro. 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 = AbootimgLib + FILE_GUID = ed3b8739-6fa7-4cb1-8aeb-2496f8fcaefa + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = AbootimgLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = ARM AARCH64 +# + +[Sources] + AbootimgLib.c + +[LibraryClasses] + DebugLib + FdtLib + PrintLib + UefiBootServicesTableLib + UefiLib + +[Packages] + MdePkg/MdePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + +[Protocols] + gAbootimgProtocolGuid + +[Guids] + gFdtTableGuid From patchwork Thu Jul 6 13:29:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jun Nie X-Patchwork-Id: 107144 Delivered-To: patch@linaro.org Received: by 10.182.135.102 with SMTP id pr6csp2170089obb; Thu, 6 Jul 2017 06:29:33 -0700 (PDT) X-Received: by 10.99.97.76 with SMTP id v73mr26198088pgb.188.1499347773208; Thu, 06 Jul 2017 06:29:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499347773; cv=none; d=google.com; s=arc-20160816; b=xssPTD+woY3o33xcyH6TSoqO32wz7R0lRIxmwO6N3BeE8oMWpQISYkgZfskn3oDlb/ v7qEtenpWodhJp0A+i5PcYTXQRWEo6sGzuPI7AC7W3kFQS4zUuCpSQSq05KW/90pRypF RB56OUKDVQRsMjLowb0xf9o6rCiHI42JC+1l+D3OTRNDNevpSJvAEz8H+YXfohKG7WYq r7F8yWOi5iqP3JmcoG+8FlkJBw+7bc0h2TQWx9qvod4DeYeViKxMklSYA5I/H/LKyLLa 2WeTjKMTBfOUu+usBNgDrEeTtnN3dfFXCjA9QKljYTCKgFn8JHBUo0vW95NyIoygkE7m 917A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=kHs4DPpbvHxp0cVV5Ae31uMiKfpAfzzXJgOzp3MyqQM=; b=KWF2rgu1XyF1862jMsU7zobsW/79AqF2DtRQ+d1LFviyDTa+0WEQpZqpJ5o2OZryQK 7lk63fvkHnMyJ8o11NjhmJ1Ct9Ivm0Ii1/pbTlp+ZpSMzIBgbNTnLxY7xD9j9MrtHsH+ EMqkoxSsDTr0qu3iGoCUsNkyuivkcTjcRkIEogxNs9gaVWyhMZmROvBVFeJGpkxX8j2N 4AOZ76d9aq+hK+OmVboQB9UPhN+sDKfyoePZE/MX5tt/NBDC+lySbvU20Bs3gqGcrU3v UvPDQ4CfOTuLJwE0cICW4qFXdGqG2fkKeAm0mfdTlZXv7m8rNrknhPLGtAwQOMgVuMzT GJcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.b=G00OTCUB; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id f73si4682pff.143.2017.07.06.06.29.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 06 Jul 2017 06:29:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.b=G00OTCUB; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 502F421CC5362; Thu, 6 Jul 2017 06:27:52 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pf0-x234.google.com (mail-pf0-x234.google.com [IPv6:2607:f8b0:400e:c00::234]) (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 0DFEC21CC5353 for ; Thu, 6 Jul 2017 06:27:51 -0700 (PDT) Received: by mail-pf0-x234.google.com with SMTP id e7so1103183pfk.0 for ; Thu, 06 Jul 2017 06:29:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xPbrk7KsEpdvoZsJo7k6Av0f+24AIl4BJHHq76me8IE=; b=G00OTCUBZDLL5Zzt2wVzt34Xj+OFDAEDe8VygmAUSM3oLZ5DgjZqhpF1h4yj8BEaCb bhitiIY71nhEDlZV3WxFk790fLemgNi2Wlg4FE+EhXQQSKEBkkQr868hesgz9D6UFDcf ZJs+1JgKw9Mh4ElWO+2eDl85K2Rc+7qGv0yLc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xPbrk7KsEpdvoZsJo7k6Av0f+24AIl4BJHHq76me8IE=; b=rTSsqv3abg1akOHkSEqHDm7sGPRio/jlFf0EYjXiqfQrdrS5zA3nCjnYIJ5sOUk1c8 cbfeR8MMqfS8xosezHOQ1xEz8gP72fAYTmOcSK3RuTgntBx32of09BMIiI8qd89UV9jl N1QXbMbWN9YrLWbAD9+vO9+ohtxAbtc6CRuh8My5lMZ5xYMiFjxJTLexP/2oh9vFqJmC 4gle2NxrDFtDcZ4ricsg0W3yMv9Ja1GgCbTaIZkkqdjrIxuaOcETCSAYSNRs9zoA6My+ d7bv1+M6jtTIIngHV3lOXKgxQp6B4aGOoX9A7QsPVV5PPlTWkymTSZYVgcAm4MC+UTDr nACA== X-Gm-Message-State: AIVw111V9vkTBdJhaOGykRIZZzyQxTstKZICp9gENdCGzWbkrQWp4bMf ujGtiwnBK6YSROtA X-Received: by 10.84.248.66 with SMTP id e2mr28630504pln.118.1499347771347; Thu, 06 Jul 2017 06:29:31 -0700 (PDT) Received: from localhost.localdomain ([113.53.228.78]) by smtp.gmail.com with ESMTPSA id 197sm253754pga.58.2017.07.06.06.29.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 06 Jul 2017 06:29:30 -0700 (PDT) From: Jun Nie To: haojian.zhuang@linaro.org, leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, edk2-devel@lists.01.org, linaro-uefi@lists.linaro.org Date: Thu, 6 Jul 2017 21:29:06 +0800 Message-Id: <1499347746-16786-2-git-send-email-jun.nie@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1499347746-16786-1-git-send-email-jun.nie@linaro.org> References: <1499347746-16786-1-git-send-email-jun.nie@linaro.org> Subject: [edk2] [PATCH v2 2/2] EmbeddedPkg: add Android boot device path and guid 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: , Cc: jason.liu@linaro.org, shawn.guo@linaro.org MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" The device path specifies where to load android boot image. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jun Nie --- EmbeddedPkg/EmbeddedPkg.dec | 2 ++ 1 file changed, 2 insertions(+) -- 1.9.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Reviewed-by: Leif Lindholm diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec index 4cd528a..cf89af2 100644 --- a/EmbeddedPkg/EmbeddedPkg.dec +++ b/EmbeddedPkg/EmbeddedPkg.dec @@ -80,6 +80,7 @@ gAndroidFastbootPlatformProtocolGuid = { 0x524685a0, 0x89a0, 0x11e3, {0x9d, 0x4d, 0xbf, 0xa9, 0xf6, 0xa4, 0x03, 0x08}} gUsbDeviceProtocolGuid = { 0x021bd2ca, 0x51d2, 0x11e3, {0x8e, 0x56, 0xb7, 0x54, 0x17, 0xc7, 0x0b, 0x44 }} gPlatformGpioProtocolGuid = { 0x52ce9845, 0x5af4, 0x43e2, {0xba, 0xfd, 0x23, 0x08, 0x12, 0x54, 0x7a, 0xc2 }} + gAbootimgProtocolGuid = { 0x9859bb19, 0x407c, 0x4f8b, {0xbc, 0xe1, 0xf8, 0xda, 0x65, 0x65, 0xf4, 0xa5 }} [PcdsFeatureFlag.common] gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|FALSE|BOOLEAN|0x00000001 @@ -181,6 +182,7 @@ gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId|0xbeef|UINT32|0x00000023 gEmbeddedTokenSpaceGuid.PcdAndroidFastbootTcpPort|1234|UINT32|0x00000024 + gEmbeddedTokenSpaceGuid.PcdAndroidBootDevicePath|L""|VOID*|0x00000025 [PcdsFixedAtBuild.ARM] gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00000010