From patchwork Wed Mar 1 06:36:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 94680 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp1653433qgi; Tue, 28 Feb 2017 22:36:20 -0800 (PST) X-Received: by 10.84.175.132 with SMTP id t4mr8147078plb.38.1488350180400; Tue, 28 Feb 2017 22:36:20 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id g2si3794569plk.70.2017.02.28.22.36.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Feb 2017 22:36:20 -0800 (PST) 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; 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 005E4821D2; Tue, 28 Feb 2017 22:36:20 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pf0-x22d.google.com (mail-pf0-x22d.google.com [IPv6:2607:f8b0:400e:c00::22d]) (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 8620F821D2 for ; Tue, 28 Feb 2017 22:36:18 -0800 (PST) Received: by mail-pf0-x22d.google.com with SMTP id j5so8083259pfb.2 for ; Tue, 28 Feb 2017 22:36:18 -0800 (PST) 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=yefiSav1aCbqlrYDF7pPRJEfgWKSHhqH55MTZVyq4go=; b=EsTw3BzviEpCAHa1MrJxe/o9bUkdwBeWS8s/jEDETh740wXCbSGO9TBzpqXuASpTaC Q2Xx2rU50HQNWDFD3Ki8D0PLmnGOfpTgO7jZLRo/fOoE3UM7E16njx2HDy1thQe8dG8l 2B882An7CXsvqBwBluZREIByZfAvj7l4l4ApQ= 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=yefiSav1aCbqlrYDF7pPRJEfgWKSHhqH55MTZVyq4go=; b=IPKrEOR+6OH0MdKC7n9US11olyQFxmoPeNjV0ws6GaFGsUMLRyFYOI1HfDIgqrTLnf 7G50AobT7IHiR+iI107QXLMdiLrjIZUvTKkZIbkj91/SCff9kWm1z7AxrmqqHCjWo4ID whsSNHFxQ4P+/M4GG9HUMk27xLvC9Wf63dXCs6Nd9awM9835HcDDILX+Umax9/dqzeoS BVX69smSD8Ra0ZSCBN7b7L/DqIug1jDMR3WL0P0lCJCNYMBTL1TeArxlzTM5T0M6L8mP +cd6LBlGhPusTmGq0HQ6HkWhqTXlnoE0yHjqcBXFDX21L80fdQF02TlcARqYxk6W3FcN xIkg== X-Gm-Message-State: AMke39nM+2ZYhZFtsz0TcbOE7QNeOhYUxE0OPlQV4wXu3nM2IR7YIU0eYxwipj4NFdPNJxk/ X-Received: by 10.99.101.67 with SMTP id z64mr2281891pgb.78.1488350178189; Tue, 28 Feb 2017 22:36:18 -0800 (PST) Received: from localhost.localdomain ([45.56.159.97]) by smtp.gmail.com with ESMTPSA id r17sm7910668pgg.19.2017.02.28.22.36.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 28 Feb 2017 22:36:17 -0800 (PST) From: Haojian Zhuang To: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, edk2-devel@lists.01.org, linaro-uefi@lists.linaro.org Date: Wed, 1 Mar 2017 14:36:04 +0800 Message-Id: <1488350167-30752-2-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488350167-30752-1-git-send-email-haojian.zhuang@linaro.org> References: <1488350167-30752-1-git-send-email-haojian.zhuang@linaro.org> Subject: [edk2] [PATCH 1/4] EmbeddedPkg/AndroidFastboot: add the GetKernelArgs interface X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Haojian Zhuang MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Add the GetKernelArgs () interface in FASTBOOT_PLATFORM_PROTOCOL. It's used to load platform command line arguments that could be merged into the command line to boot android kernel. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Haojian Zhuang --- EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h b/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h index a9b4aac..b3c868a 100644 --- a/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h +++ b/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h @@ -133,6 +133,18 @@ EFI_STATUS IN CHAR8 *Command ); +/* + Get platform kernel arguments. + + @retval Null terminated CHAR16 string. + @retval NULL If fail to get platform kernel arguments. + */ +typedef +CHAR16 * +(*FASTBOOT_PLATFORM_GETARGS) ( + VOID + ); + typedef struct _FASTBOOT_PLATFORM_PROTOCOL { FASTBOOT_PLATFORM_INIT Init; FASTBOOT_PLATFORM_UN_INIT UnInit; @@ -140,6 +152,7 @@ typedef struct _FASTBOOT_PLATFORM_PROTOCOL { FASTBOOT_PLATFORM_ERASE ErasePartition; FASTBOOT_PLATFORM_GETVAR GetVar; FASTBOOT_PLATFORM_OEM_COMMAND DoOemCommand; + FASTBOOT_PLATFORM_GETARGS GetKernelArgs; } FASTBOOT_PLATFORM_PROTOCOL; #endif From patchwork Wed Mar 1 06:36:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 94681 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp1653446qgi; Tue, 28 Feb 2017 22:36:23 -0800 (PST) X-Received: by 10.84.224.133 with SMTP id s5mr7981077plj.93.1488350183611; Tue, 28 Feb 2017 22:36:23 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id m8si3796740plk.48.2017.02.28.22.36.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Feb 2017 22:36:23 -0800 (PST) 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; 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 33C47821D5; Tue, 28 Feb 2017 22:36:23 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pf0-x230.google.com (mail-pf0-x230.google.com [IPv6:2607:f8b0:400e:c00::230]) (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 F299281F5C for ; Tue, 28 Feb 2017 22:36:21 -0800 (PST) Received: by mail-pf0-x230.google.com with SMTP id x66so8061266pfb.3 for ; Tue, 28 Feb 2017 22:36:21 -0800 (PST) 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=mSHF+UJ+rU+w/W7BNYtVqxq18M9kIFKVMsaJ2PrluuY=; b=hbA5T6RcxWH41TAbfFqoobSdX93/X1YOiWwGXFUiR3GwVTrJoRw+MK29AlwW/rd9B7 tdibejs7b0o9Yf3dRTPVGkZwdOSJa9MsB+j/Y5NOy8ldeEOjQgAO9PnI2/SWYzBsQDoX 3/aXvvYeKMFsf1YIzApbU6hBANFM15TPUHtc8= 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=mSHF+UJ+rU+w/W7BNYtVqxq18M9kIFKVMsaJ2PrluuY=; b=Gaurh9IXq2cqFn4CVUOC3dCPfrzFMEWR3nnf1D32bWloWz9Q2qmPgzy3NveKbbplpO jJjJcETKAGRrWCvws6eyq8LK7G1zMEcCC1sxMLDrc7fjJVIRjPvhOvnwkfwtvtRexQbj 0wfUaHYDi+pDEr50JQWtTYRUGesdR7xp233OQjr/f2FU+LAts7gMhGtSgGzm61WSeD/W Z9bYRDrHAmJBgtIxb6Ie7RvTk3KLs0km+EPDlw3Ewp1U1aGQ7oKiOx1jXWhSqz6DLm9w bPqhvEsn6gARh0jl5EL2D5pIwJdqUPADwOCFHuWdnPyl5ykAHD6bGk6A+zd5boRfbok2 v2dQ== X-Gm-Message-State: AMke39mv2NGpBlqUoRhJPCzbYZkBQwlIv1HwY9ZyyxhZi5N7859Mri8rvrLzJRjc3lqn0bjZ X-Received: by 10.84.215.15 with SMTP id k15mr8155078pli.58.1488350181416; Tue, 28 Feb 2017 22:36:21 -0800 (PST) Received: from localhost.localdomain ([45.56.159.97]) by smtp.gmail.com with ESMTPSA id r17sm7910668pgg.19.2017.02.28.22.36.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 28 Feb 2017 22:36:20 -0800 (PST) From: Haojian Zhuang To: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, edk2-devel@lists.01.org, linaro-uefi@lists.linaro.org Date: Wed, 1 Mar 2017 14:36:05 +0800 Message-Id: <1488350167-30752-3-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488350167-30752-1-git-send-email-haojian.zhuang@linaro.org> References: <1488350167-30752-1-git-send-email-haojian.zhuang@linaro.org> Subject: [edk2] [PATCH 2/4] EmbeddedPkg/AndroidFastboot: fix to boot android kernel X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Haojian Zhuang MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Fix the issue of booting android kernel since LinuxLoader is broken. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Haojian Zhuang --- .../AndroidFastboot/AndroidFastbootApp.c | 2 +- .../AndroidFastboot/AndroidFastbootApp.h | 21 +- .../AndroidFastboot/AndroidFastbootApp.inf | 4 + .../AndroidFastboot/Arm/BootAndroidBootImg.c | 230 ++++++++++++++++----- 4 files changed, 192 insertions(+), 65 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c index c5e8a7e..204754f 100644 --- a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c +++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c @@ -216,7 +216,7 @@ HandleBoot ( // boot we lose control of the system. SEND_LITERAL ("OKAY"); - Status = BootAndroidBootImg (mNumDataBytes, mDataBuffer); + Status = BootAndroidBootImg (mPlatform, mNumDataBytes, mDataBuffer); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Failed to boot downloaded image: %r\n", Status)); } diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h index f62660f..24d31de 100644 --- a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h +++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h @@ -19,24 +19,27 @@ #include #include -#define BOOTIMG_KERNEL_ARGS_SIZE 512 +#include + +#define BOOTIMG_KERNEL_ARGS_SIZE 1024 #define ANDROID_FASTBOOT_VERSION "0.4" EFI_STATUS BootAndroidBootImg ( - IN UINTN BufferSize, - IN VOID *Buffer + IN FASTBOOT_PLATFORM_PROTOCOL *Platform, + IN UINTN BufferSize, + IN VOID *Buffer ); EFI_STATUS ParseAndroidBootImg ( - IN VOID *BootImg, - OUT VOID **Kernel, - OUT UINTN *KernelSize, - OUT VOID **Ramdisk, - OUT UINTN *RamdiskSize, - OUT CHAR8 *KernelArgs + IN VOID *BootImg, + OUT VOID **Kernel, + OUT UINTN *KernelSize, + OUT VOID **Ramdisk, + OUT UINTN *RamdiskSize, + OUT CHAR8 *KernelArgs ); #endif //ifdef __ANDROID_FASTBOOT_APP_H__ diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf index 3e11517..daf4008 100644 --- a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf +++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf @@ -34,6 +34,7 @@ DebugLib DevicePathLib DxeServicesTableLib + FdtLib MemoryAllocationLib PcdLib PrintLib @@ -56,3 +57,6 @@ [Packages.ARM, Packages.AARCH64] ArmPkg/ArmPkg.dec ArmPlatformPkg/ArmPlatformPkg.dec + +[Guids] + gFdtTableGuid diff --git a/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c b/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c index acedd3e..04d175b 100644 --- a/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c +++ b/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c @@ -15,16 +15,21 @@ #include "AndroidFastbootApp.h" #include +#include #include #include +#include +#include #include #include -#define LINUX_LOADER_COMMAND_LINE L"%s -f %s -c %s" +#include -// This GUID is defined in the INGF file of ArmPkg/Application/LinuxLoader -CONST EFI_GUID mLinuxLoaderAppGuid = { 0x701f54f2, 0x0d70, 0x4b89, { 0xbc, 0x0a, 0xd9, 0xca, 0x25, 0x37, 0x90, 0x59 }}; +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) + +// Additional size that could be used for FDT entries added by the UEFI OS Loader +#define FDT_ADDITIONAL_ENTRIES_SIZE 0x400 // Device Path representing an image in memory #pragma pack(1) @@ -34,6 +39,12 @@ typedef struct { } MEMORY_DEVICE_PATH; #pragma pack() +/* 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 + STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate = { { @@ -56,9 +67,114 @@ STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate = }; EFI_STATUS +PrepareFdt ( + IN EFI_PHYSICAL_ADDRESS FdtBlobBase, + IN UINTN *FdtBlobSize, + IN OUT CHAR16 *KernelArgs + ) +{ + VOID *fdt; + INTN err; + INTN node; + INT32 lenp; + CONST VOID *BootArg; + UINTN OriginalFdtSize; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS NewFdtBlobBase; + UINTN NewFdtBlobSize; + CHAR16 Arg[BOOTIMG_KERNEL_ARGS_SIZE]; + UINTN Size; + + // + // Sanity checks on the original FDT blob. + // + err = fdt_check_header ((VOID*)(UINTN)FdtBlobBase); + if (err != 0) { + Print (L"ERROR: Device Tree header not valid (err:%d)\n", err); + return EFI_INVALID_PARAMETER; + } + + // The original FDT blob might have been loaded partially. + // Check that it is not the case. + OriginalFdtSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)FdtBlobBase); + if (OriginalFdtSize > *FdtBlobSize) { + Print (L"ERROR: Incomplete FDT. Only %d/%d bytes have been loaded.\n", + FdtBlobSize, OriginalFdtSize); + return EFI_INVALID_PARAMETER; + } + + // + // Relocate the FDT to its final location since some platform may update FDT. + // + Size = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE; + NewFdtBlobSize = ALIGN (Size, EFI_PAGE_SIZE); + + // Try anywhere there is available space. + Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, + EFI_SIZE_TO_PAGES (NewFdtBlobSize), &NewFdtBlobBase); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return EFI_OUT_OF_RESOURCES; + } else { + DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", NewFdtBlobBase)); + } + + // Load the Original FDT tree into the new region + err = fdt_open_into ((VOID*)(UINTN) FdtBlobBase, + (VOID*)(UINTN)(NewFdtBlobBase), NewFdtBlobSize); + if (err) { + DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (err))); + gBS->FreePages (NewFdtBlobBase, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); + return EFI_INVALID_PARAMETER; + } + + // If we succeeded to generate the new Device Tree then free the old Device Tree + gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (OriginalFdtSize)); + + fdt = (VOID*)(UINTN)NewFdtBlobBase; + + node = fdt_subnode_offset (fdt, 0, "chosen"); + if (node < 0) { + // The 'chosen' node does not exist, create it + node = fdt_add_subnode (fdt, 0, "chosen"); + if (node < 0) { + DEBUG ((EFI_D_ERROR, "Error on finding 'chosen' node\n")); + Status = EFI_INVALID_PARAMETER; + goto FAIL_COMPLETE_FDT; + } + } + + // Merge bootargs into command line arguments + BootArg = fdt_getprop (fdt, node, "bootargs", &lenp); + if (BootArg != NULL) { + AsciiStrToUnicodeStrS (BootArg, Arg, BOOTIMG_KERNEL_ARGS_SIZE); + // StrCatS() is using the size of CHAR16 + StrCatS (KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE >> 1, L" "); + StrCatS (KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE >> 1, Arg); + } + + // Update the real size of the Device Tree + fdt_pack ((VOID*)(UINTN)(NewFdtBlobBase)); + + *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase)); + + Status = gBS->InstallConfigurationTable ( + &gFdtTableGuid, + (VOID *)(UINTN)NewFdtBlobBase + ); + return Status; + +FAIL_COMPLETE_FDT: + gBS->FreePages (NewFdtBlobBase, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); + + return EFI_SUCCESS; +} + +EFI_STATUS BootAndroidBootImg ( - IN UINTN BufferSize, - IN VOID *Buffer + IN FASTBOOT_PLATFORM_PROTOCOL *Platform, + IN UINTN BufferSize, + IN VOID *Buffer ) { EFI_STATUS Status; @@ -68,11 +184,13 @@ BootAndroidBootImg ( VOID *Ramdisk; UINTN RamdiskSize; MEMORY_DEVICE_PATH KernelDevicePath; - MEMORY_DEVICE_PATH* RamdiskDevicePath; - CHAR16* KernelDevicePathTxt; - CHAR16* RamdiskDevicePathTxt; - EFI_DEVICE_PATH* LinuxLoaderDevicePath; - CHAR16* LoadOptions; + EFI_HANDLE ImageHandle; + EFI_PHYSICAL_ADDRESS FdtBase; + UINTN FdtSize, Index; + UINT8 *FdtPtr; + VOID *NewKernelArg; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + CHAR16 *PlatformKernelArgs; Status = ParseAndroidBootImg ( Buffer, @@ -86,62 +204,64 @@ BootAndroidBootImg ( return Status; } - 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; - - RamdiskDevicePath = NULL; - if (RamdiskSize != 0) { - RamdiskDevicePath = (MEMORY_DEVICE_PATH*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &MemoryDevicePathTemplate); + /* Install Fdt that is attached at the end of kernel */ + KernelSize = *(UINT32 *)((EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KERNEL_IMAGE_STEXT_OFFSET) + + *(UINT32 *)((EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KERNEL_IMAGE_RAW_SIZE_OFFSET); - RamdiskDevicePath->Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk; - RamdiskDevicePath->Node1.EndingAddress = ((EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk) + RamdiskSize; + /* FDT is at the end of kernel image */ + FdtBase = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KernelSize; + FdtPtr = (UINT8 *)(FdtBase + FDT_SIZE_OFFSET); + for (Index = 0, FdtSize = 0; Index < sizeof (UINT32); Index++) { + FdtSize |= *FdtPtr << ((sizeof (UINT32) - 1 - Index) * 8); + FdtPtr++; } - // - // Boot Linux using the Legacy Linux Loader - // - - Status = LocateEfiApplicationInFvByGuid (&mLinuxLoaderAppGuid, &LinuxLoaderDevicePath); - if (EFI_ERROR (Status)) { - Print (L"Couldn't Boot Linux: %d\n", Status); - return EFI_DEVICE_ERROR; - } - - KernelDevicePathTxt = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath, FALSE, FALSE); - if (KernelDevicePathTxt == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - RamdiskDevicePathTxt = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *) RamdiskDevicePath, FALSE, FALSE); - if (RamdiskDevicePathTxt == NULL) { + NewKernelArg = AllocateZeroPool (BOOTIMG_KERNEL_ARGS_SIZE); + if (NewKernelArg == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to allocate memory\n")); return EFI_OUT_OF_RESOURCES; } - // Initialize Legacy Linux loader command line - LoadOptions = CatSPrint (NULL, LINUX_LOADER_COMMAND_LINE, KernelDevicePathTxt, RamdiskDevicePathTxt, KernelArgs); - if (LoadOptions == NULL) { - return EFI_OUT_OF_RESOURCES; + // Set the ramdisk in command line arguments + UnicodeSPrint ( + (CHAR16 *)NewKernelArg, BOOTIMG_KERNEL_ARGS_SIZE, + L"initrd=0x%x,0x%x ", + (UINTN)Ramdisk, (UINTN)RamdiskSize + ); + // Merge kernel arguments from Android boot image into command line arguments + AsciiStrToUnicodeStrS (KernelArgs, NewKernelArg + StrLen (NewKernelArg) * sizeof (CHAR16), BOOTIMG_KERNEL_ARGS_SIZE >> 1); + // StrCatS() is using the size of CHAR16 + StrCatS ((CHAR16 *)NewKernelArg, BOOTIMG_KERNEL_ARGS_SIZE >> 1, L" "); + // Merge platform arguemnts into command line arguments + PlatformKernelArgs = Platform->GetKernelArgs (); + if (PlatformKernelArgs) { + StrCatS ((CHAR16 *)NewKernelArg, BOOTIMG_KERNEL_ARGS_SIZE >> 1, PlatformKernelArgs); } - - Status = BdsStartEfiApplication (gImageHandle, LinuxLoaderDevicePath, StrSize (LoadOptions), LoadOptions); + Status = PrepareFdt (FdtBase, &FdtSize, NewKernelArg); if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status)); - return EFI_DEVICE_ERROR; + FreePool (NewKernelArg); + return EFI_INVALID_PARAMETER; } - if (RamdiskDevicePath) { - FreePool (RamdiskDevicePathTxt); - FreePool (RamdiskDevicePath); - } + 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); - FreePool (KernelDevicePathTxt); + // Set kernel arguments + Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); + ImageInfo->LoadOptions = NewKernelArg; + ImageInfo->LoadOptionsSize = StrLen (NewKernelArg) * sizeof (CHAR16); - // If we got here we do a confused face because BootLinuxFdt returned, - // reporting success. - DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n")); + // 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; } From patchwork Wed Mar 1 06:36:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 94682 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp1653467qgi; Tue, 28 Feb 2017 22:36:27 -0800 (PST) X-Received: by 10.99.153.1 with SMTP id d1mr7033120pge.44.1488350185805; Tue, 28 Feb 2017 22:36:25 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id a14si3784798pgd.80.2017.02.28.22.36.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Feb 2017 22:36:25 -0800 (PST) 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; 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 64063821D9; Tue, 28 Feb 2017 22:36:25 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pg0-x234.google.com (mail-pg0-x234.google.com [IPv6:2607:f8b0:400e:c05::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 A278C821D0 for ; Tue, 28 Feb 2017 22:36:24 -0800 (PST) Received: by mail-pg0-x234.google.com with SMTP id p5so17149635pga.1 for ; Tue, 28 Feb 2017 22:36:24 -0800 (PST) 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=6JDWKthw/mrqzrYE1jiOQ4Vkp15BbGIYtq62EBtsXGI=; b=VVkEM2JkIvERnalyzO835yp9kUQAaqQ6oJebymMnJfNGcHk5RmBYISeJiQVQ8KFylG E0zenlLA0ErOH0zqnRDY3jwGyZ3vA7JXHGSx8TKElE/0mLTqidQVQJHrmNZkwz1sUCED eNBnaj21J6Wa31yVhbGReQSpjL8ic0Jij7aQQ= 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=6JDWKthw/mrqzrYE1jiOQ4Vkp15BbGIYtq62EBtsXGI=; b=o2Aztc4sif+sx1ZpJ0sNwipccA+abEfrUy5mZTdzpNnaztRKcbZaKZGFoOt09GIeoZ Fi0aGSNjhZnhW73puUr7e8P74G1JA9Wx4htdKDZDfLxK2ngmH9Z78w4F6wTc4lsLbpnJ R3xMxovXFJ/G0N8nnVFDYJnwuS+luEl0UQQVQuxnjYwN4jdgmjZM8m7jBizlYqwGzvAc XxDXJPJVFPy9TV6eBxCuSCNW8RajD9q4Gvdf9+UyMcnHL8ZyAalzU/ZVOmDTGZHw8N0R 0+YvZiopNg9+yS+DkX/xFTaZYp76tk3ZQf/m7DVEe/ItOGPZzLRXLHt7yLVWNm6rrIY7 4lXA== X-Gm-Message-State: AMke39nnj6UWaEwHxo9NwdPkuHZ5efFypSacMosRR2kOVmD9kHnktilYHZK60dNgPSPvy+hb X-Received: by 10.84.229.76 with SMTP id d12mr8210678pln.21.1488350184332; Tue, 28 Feb 2017 22:36:24 -0800 (PST) Received: from localhost.localdomain ([45.56.159.97]) by smtp.gmail.com with ESMTPSA id r17sm7910668pgg.19.2017.02.28.22.36.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 28 Feb 2017 22:36:23 -0800 (PST) From: Haojian Zhuang To: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, edk2-devel@lists.01.org, linaro-uefi@lists.linaro.org Date: Wed, 1 Mar 2017 14:36:06 +0800 Message-Id: <1488350167-30752-4-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488350167-30752-1-git-send-email-haojian.zhuang@linaro.org> References: <1488350167-30752-1-git-send-email-haojian.zhuang@linaro.org> Subject: [edk2] [PATCH 3/4] EmbeddedPkg: add Android boot device path X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Haojian Zhuang 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: Haojian Zhuang --- EmbeddedPkg/EmbeddedPkg.dec | 2 ++ 1 file changed, 2 insertions(+) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec index 2c2cf41..7b6f25e 100644 --- a/EmbeddedPkg/EmbeddedPkg.dec +++ b/EmbeddedPkg/EmbeddedPkg.dec @@ -161,6 +161,8 @@ gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId|0xbeef|UINT32|0x00000023 gEmbeddedTokenSpaceGuid.PcdAndroidFastbootTcpPort|1234|UINT32|0x00000024 + gEmbeddedTokenSpaceGuid.PcdAndroidBootDevicePath|L""|VOID*|0x00000057 + [PcdsFixedAtBuild.ARM] gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00000010 From patchwork Wed Mar 1 06:36:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 94683 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp1653481qgi; Tue, 28 Feb 2017 22:36:30 -0800 (PST) X-Received: by 10.84.196.164 with SMTP id l33mr8302928pld.0.1488350190054; Tue, 28 Feb 2017 22:36:30 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id g11si3800543pln.0.2017.02.28.22.36.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Feb 2017 22:36:30 -0800 (PST) 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; 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 991A2821D4; Tue, 28 Feb 2017 22:36:29 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pf0-x232.google.com (mail-pf0-x232.google.com [IPv6:2607:f8b0:400e:c00::232]) (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 67A0781F5C for ; Tue, 28 Feb 2017 22:36:28 -0800 (PST) Received: by mail-pf0-x232.google.com with SMTP id x66so8062030pfb.3 for ; Tue, 28 Feb 2017 22:36:28 -0800 (PST) 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=mswTDVYLvup9MWw4lPnRZ5QzqPmq7KFrUkxIKXmjmiI=; b=ZZ251n155c/thwNBAfle710VoYPLm2Xy5B9eiMp8iV6waCbbZvPdtfN8/1qvkQ5drE WJnaVgaaVsEqsw7lvAZ2qGX6xFvCbdUIZfFunvgtz+c03hR+oCrNM/usCUsNvOw+t9yJ W//6Z8fRx0vILpnBdtJ6buq8zN8wplh7bc/yA= 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=mswTDVYLvup9MWw4lPnRZ5QzqPmq7KFrUkxIKXmjmiI=; b=q7ejaelKyY0CoEjuFA4GRTQDsmP3TCtihIDLSUg93rVkQbqlh8gPGsm4DS/R54eq5N NahMUQ+ujjTqz/dh1jS87kuBnj9KBYVpJ+F1gwxrRW1zpBwM6kRvSSWwkbuKZah0jH+q SokvA8oxJxklKpLT5tTvkT1JeymGns73e8IWopIH067mSAPn77ahHoeaoWaEB4zHe02N 46Vh+1JcKo6KYxigCIGItzmLoes9pBGzQ+srr1ICU8HPHfYXruyct/9ELHax73QqjFdP Oh83FMIVz5DXSMYL2wRF8mYOOvGZwI8oQT3jkAmBKkY0Eg9Ijm2NVRYo5VGlkUsd/g9O Ek5A== X-Gm-Message-State: AMke39l/h+jl60Y+TcjRv94c15kA0rOq2OlEAiWM0RXtOhJuFSIKXdpOQTrlEPsL1n3aDcoz X-Received: by 10.84.196.164 with SMTP id l33mr8302761pld.0.1488350187817; Tue, 28 Feb 2017 22:36:27 -0800 (PST) Received: from localhost.localdomain ([45.56.159.97]) by smtp.gmail.com with ESMTPSA id r17sm7910668pgg.19.2017.02.28.22.36.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 28 Feb 2017 22:36:27 -0800 (PST) From: Haojian Zhuang To: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, edk2-devel@lists.01.org, linaro-uefi@lists.linaro.org Date: Wed, 1 Mar 2017 14:36:07 +0800 Message-Id: <1488350167-30752-5-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488350167-30752-1-git-send-email-haojian.zhuang@linaro.org> References: <1488350167-30752-1-git-send-email-haojian.zhuang@linaro.org> Subject: [edk2] [PATCH 4/4] EmbeddedPkg/AndroidBoot: boot android kernel from storage X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Haojian Zhuang 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. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Haojian Zhuang --- .../Application/AndroidBoot/AndroidBootApp.c | 118 +++++++++ .../Application/AndroidBoot/AndroidBootApp.h | 44 ++++ .../Application/AndroidBoot/AndroidBootApp.inf | 67 ++++++ .../Application/AndroidBoot/AndroidBootImg.c | 91 +++++++ .../AndroidBoot/Arm/BootAndroidBootImg.c | 268 +++++++++++++++++++++ 5 files changed, 588 insertions(+) create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.h create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootImg.c create mode 100644 EmbeddedPkg/Application/AndroidBoot/Arm/BootAndroidBootImg.c -- 2.7.4 _______________________________________________ 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..312bfd7 --- /dev/null +++ b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c @@ -0,0 +1,118 @@ +/** @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 "AndroidBootApp.h" + +#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype))) + +STATIC FASTBOOT_PLATFORM_PROTOCOL *mPlatform; + +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; + HARDDRIVE_DEVICE_PATH *PartitionPath; + UINT32 MediaId, BlockSize; + VOID *Buffer; + EFI_HANDLE Handle; + + 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)) { + PartitionPath = (HARDDRIVE_DEVICE_PATH *)Node; + 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; + /* Both PartitionStart and PartitionSize are counted as block size. */ + Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PartitionPath->PartitionSize)); + if (Buffer == NULL) { + return EFI_BUFFER_TOO_SMALL; + } + + /* Load header of boot.img */ + Status = BlockIo->ReadBlocks ( + BlockIo, + MediaId, + PartitionPath->PartitionStart / BlockSize, + PartitionPath->PartitionSize, + Buffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Failed to read blocks: %r\n", Status)); + goto EXIT; + } + + Status = gBS->LocateProtocol (&gAndroidFastbootPlatformProtocolGuid, NULL, (VOID **) &mPlatform); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Fastboot: Couldn't open Fastboot Platform Protocol: %r\n", Status)); + goto EXIT; + } + + Status = BootAndroidBootImg (mPlatform, PartitionPath->PartitionSize, Buffer); + +EXIT: + FreePages (Buffer, EFI_SIZE_TO_PAGES (PartitionPath->PartitionSize)); + return Status; +} diff --git a/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.h b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.h new file mode 100644 index 0000000..ed7ea6e --- /dev/null +++ b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.h @@ -0,0 +1,44 @@ +/** @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 __ANDROID_BOOT_APP_H__ +#define __ANDROID_BOOT_APP_H__ + +#include +#include +#include + +#include + +#define BOOTIMG_KERNEL_ARGS_SIZE 1024 + +EFI_STATUS +BootAndroidBootImg ( + IN FASTBOOT_PLATFORM_PROTOCOL *Platform, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +EFI_STATUS +ParseAndroidBootImg ( + IN VOID *BootImg, + OUT VOID **Kernel, + OUT UINTN *KernelSize, + OUT VOID **Ramdisk, + OUT UINTN *RamdiskSize, + OUT CHAR8 *KernelArgs + ); + +#endif //ifdef __ANDROID_BOOT_APP_H__ diff --git a/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf new file mode 100644 index 0000000..176f778 --- /dev/null +++ b/EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf @@ -0,0 +1,67 @@ +#/** @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 + AndroidBootImg.c + +[Sources.ARM, Sources.AARCH64] + Arm/BootAndroidBootImg.c + +[LibraryClasses] + 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/Application/AndroidBoot/AndroidBootImg.c b/EmbeddedPkg/Application/AndroidBoot/AndroidBootImg.c new file mode 100644 index 0000000..abfd8c6 --- /dev/null +++ b/EmbeddedPkg/Application/AndroidBoot/AndroidBootImg.c @@ -0,0 +1,91 @@ +/** @file + + Copyright (c) 2013-2014, ARM Ltd. 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 "AndroidBootApp.h" + +#define BOOT_MAGIC "ANDROID!" +#define BOOT_MAGIC_LENGTH sizeof (BOOT_MAGIC) - 1 + +// 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)) + +// No documentation for this really - sizes of fields has been determined +// empirically. +#pragma pack(1) +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; +#pragma pack() + +// Find the kernel and ramdisk in an Android boot.img. +// return EFI_INVALID_PARAMTER if the boot.img is invalid (i.e. doesn't have the +// right magic value), +// return EFI_NOT_FOUND if there was no kernel in the boot.img. +// Note that the Ramdisk is optional - *Ramdisk won't be touched if it isn't +// present, but RamdiskSize will be set to 0. +EFI_STATUS +ParseAndroidBootImg ( + IN VOID *BootImg, + OUT VOID **Kernel, + OUT UINTN *KernelSize, + OUT VOID **Ramdisk, + OUT UINTN *RamdiskSize, + OUT CHAR8 *KernelArgs + ) +{ + 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; + } + + if (Header->KernelSize == 0) { + return EFI_NOT_FOUND; + } + + ASSERT (IS_POWER_OF_2 (Header->PageSize)); + + *KernelSize = Header->KernelSize; + *Kernel = BootImgBytePtr + Header->PageSize; + *RamdiskSize = Header->RamdiskSize; + + if (Header->RamdiskSize != 0) { + *Ramdisk = (VOID *) (BootImgBytePtr + + Header->PageSize + + ALIGN_VALUE (Header->KernelSize, Header->PageSize)); + } + + AsciiStrnCpyS (KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE, Header->KernelArgs, + BOOTIMG_KERNEL_ARGS_SIZE); + + return EFI_SUCCESS; +} diff --git a/EmbeddedPkg/Application/AndroidBoot/Arm/BootAndroidBootImg.c b/EmbeddedPkg/Application/AndroidBoot/Arm/BootAndroidBootImg.c new file mode 100644 index 0000000..87b657d --- /dev/null +++ b/EmbeddedPkg/Application/AndroidBoot/Arm/BootAndroidBootImg.c @@ -0,0 +1,268 @@ +/** @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. + +**/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "AndroidBootApp.h" + +#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) + +// Additional size that could be used for FDT entries added by the UEFI OS Loader +#define FDT_ADDITIONAL_ENTRIES_SIZE 0x400 + +// Device Path representing an image in memory +#pragma pack(1) +typedef struct { + MEMMAP_DEVICE_PATH Node1; + EFI_DEVICE_PATH_PROTOCOL End; +} MEMORY_DEVICE_PATH; +#pragma pack() + +/* 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 + +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 +PrepareFdt ( + IN EFI_PHYSICAL_ADDRESS FdtBlobBase, + IN UINTN *FdtBlobSize, + IN OUT CHAR16 *KernelArgs + ) +{ + VOID *fdt; + INTN err; + INTN node; + INT32 lenp; + CONST VOID *BootArg; + UINTN OriginalFdtSize; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS NewFdtBlobBase; + UINTN NewFdtBlobSize; + CHAR16 Arg[BOOTIMG_KERNEL_ARGS_SIZE]; + UINTN Size; + + // + // Sanity checks on the original FDT blob. + // + err = fdt_check_header ((VOID*)(UINTN)FdtBlobBase); + if (err != 0) { + Print (L"ERROR: Device Tree header not valid (err:%d)\n", err); + return EFI_INVALID_PARAMETER; + } + + // The original FDT blob might have been loaded partially. + // Check that it is not the case. + OriginalFdtSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)FdtBlobBase); + if (OriginalFdtSize > *FdtBlobSize) { + Print (L"ERROR: Incomplete FDT. Only %d/%d bytes have been loaded.\n", + FdtBlobSize, OriginalFdtSize); + return EFI_INVALID_PARAMETER; + } + + // + // Relocate the FDT to its final location since some platform may update FDT. + // + Size = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE; + NewFdtBlobSize = ALIGN (Size, EFI_PAGE_SIZE); + + // Try anywhere there is available space. + Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, + EFI_SIZE_TO_PAGES (NewFdtBlobSize), &NewFdtBlobBase); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return EFI_OUT_OF_RESOURCES; + } else { + DEBUG ((EFI_D_WARN, "WARNING: Loaded FDT at random address 0x%lX.\nWARNING: There is a risk of accidental overwriting by other code/data.\n", NewFdtBlobBase)); + } + + // Load the Original FDT tree into the new region + err = fdt_open_into ((VOID*)(UINTN) FdtBlobBase, + (VOID*)(UINTN)(NewFdtBlobBase), NewFdtBlobSize); + if (err) { + DEBUG ((EFI_D_ERROR, "fdt_open_into(): %a\n", fdt_strerror (err))); + gBS->FreePages (NewFdtBlobBase, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); + return EFI_INVALID_PARAMETER; + } + + // If we succeeded to generate the new Device Tree then free the old Device Tree + gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (OriginalFdtSize)); + + fdt = (VOID*)(UINTN)NewFdtBlobBase; + + node = fdt_subnode_offset (fdt, 0, "chosen"); + if (node < 0) { + // The 'chosen' node does not exist, create it + node = fdt_add_subnode (fdt, 0, "chosen"); + if (node < 0) { + DEBUG ((EFI_D_ERROR, "Error on finding 'chosen' node\n")); + Status = EFI_INVALID_PARAMETER; + goto FAIL_COMPLETE_FDT; + } + } + + // Merge bootargs into command line arguments + BootArg = fdt_getprop (fdt, node, "bootargs", &lenp); + if (BootArg != NULL) { + AsciiStrToUnicodeStrS (BootArg, Arg, BOOTIMG_KERNEL_ARGS_SIZE); + // StrCatS() is using the size of CHAR16 + StrCatS (KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE >> 1, L" "); + StrCatS (KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE >> 1, Arg); + } + + // Update the real size of the Device Tree + fdt_pack ((VOID*)(UINTN)(NewFdtBlobBase)); + + *FdtBlobSize = (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase)); + + Status = gBS->InstallConfigurationTable ( + &gFdtTableGuid, + (VOID *)(UINTN)NewFdtBlobBase + ); + return Status; + +FAIL_COMPLETE_FDT: + gBS->FreePages (NewFdtBlobBase, EFI_SIZE_TO_PAGES (NewFdtBlobSize)); + + return EFI_SUCCESS; +} + +EFI_STATUS +BootAndroidBootImg ( + IN FASTBOOT_PLATFORM_PROTOCOL *Platform, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + CHAR8 KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE]; + VOID *Kernel; + UINTN KernelSize; + VOID *Ramdisk; + UINTN RamdiskSize; + MEMORY_DEVICE_PATH KernelDevicePath; + EFI_HANDLE ImageHandle; + EFI_PHYSICAL_ADDRESS FdtBase; + UINTN FdtSize, Index; + UINT8 *FdtPtr; + VOID *NewKernelArg; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + CHAR16 *PlatformKernelArgs; + + Status = ParseAndroidBootImg ( + Buffer, + &Kernel, + &KernelSize, + &Ramdisk, + &RamdiskSize, + KernelArgs + ); + if (EFI_ERROR (Status)) { + return Status; + } + + /* Install Fdt that is attached at the end of kernel */ + KernelSize = *(UINT32 *)((EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KERNEL_IMAGE_STEXT_OFFSET) + + *(UINT32 *)((EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KERNEL_IMAGE_RAW_SIZE_OFFSET); + + /* FDT is at the end of kernel image */ + FdtBase = (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KernelSize; + FdtPtr = (UINT8 *)(FdtBase + FDT_SIZE_OFFSET); + for (Index = 0, FdtSize = 0; Index < sizeof (UINT32); Index++) { + FdtSize |= *FdtPtr << ((sizeof (UINT32) - 1 - Index) * 8); + FdtPtr++; + } + + NewKernelArg = AllocateZeroPool (BOOTIMG_KERNEL_ARGS_SIZE); + if (NewKernelArg == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to allocate memory\n")); + return EFI_OUT_OF_RESOURCES; + } + + // Set the ramdisk in command line arguments + UnicodeSPrint ( + (CHAR16 *)NewKernelArg, BOOTIMG_KERNEL_ARGS_SIZE, + L"initrd=0x%x,0x%x ", + (UINTN)Ramdisk, (UINTN)RamdiskSize + ); + // Merge kernel arguments from Android boot image into command line arguments + AsciiStrToUnicodeStrS (KernelArgs, NewKernelArg + StrLen (NewKernelArg) * sizeof (CHAR16), BOOTIMG_KERNEL_ARGS_SIZE >> 1); + // StrCatS() is using the size of CHAR16 + StrCatS ((CHAR16 *)NewKernelArg, BOOTIMG_KERNEL_ARGS_SIZE >> 1, L" "); + // Merge platform arguemnts into command line arguments + PlatformKernelArgs = Platform->GetKernelArgs (); + if (PlatformKernelArgs) { + StrCatS ((CHAR16 *)NewKernelArg, BOOTIMG_KERNEL_ARGS_SIZE >> 1, PlatformKernelArgs); + } + Status = PrepareFdt (FdtBase, &FdtSize, 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; +}