From nobody Sat Nov 2 14:39:47 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1488350184667678.6223485999055; Tue, 28 Feb 2017 22:36:24 -0800 (PST) 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) 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) 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) X-Original-To: edk2-devel@lists.01.org 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) 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 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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(-) 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"); =20 - Status =3D BootAndroidBootImg (mNumDataBytes, mDataBuffer); + Status =3D 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 =20 -#define BOOTIMG_KERNEL_ARGS_SIZE 512 +#include + +#define BOOTIMG_KERNEL_ARGS_SIZE 1024 =20 #define ANDROID_FASTBOOT_VERSION "0.4" =20 EFI_STATUS BootAndroidBootImg ( - IN UINTN BufferSize, - IN VOID *Buffer + IN FASTBOOT_PLATFORM_PROTOCOL *Platform, + IN UINTN BufferSize, + IN VOID *Buffer ); =20 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 ); =20 #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" =20 #include +#include =20 #include #include +#include +#include #include #include =20 -#define LINUX_LOADER_COMMAND_LINE L"%s -f %s -c %s" +#include =20 -// This GUID is defined in the INGF file of ArmPkg/Application/LinuxLoader -CONST EFI_GUID mLinuxLoaderAppGuid =3D { 0x701f54f2, 0x0d70, 0x4b89, { 0xb= c, 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 =20 // Device Path representing an image in memory #pragma pack(1) @@ -34,6 +39,12 @@ typedef struct { } MEMORY_DEVICE_PATH; #pragma pack() =20 +/* 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 =3D { { @@ -56,9 +67,114 @@ STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplat= e =3D }; =20 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 =3D fdt_check_header ((VOID*)(UINTN)FdtBlobBase); + if (err !=3D 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 =3D (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 =3D OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE; + NewFdtBlobSize =3D ALIGN (Size, EFI_PAGE_SIZE); + + // Try anywhere there is available space. + Status =3D 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.\nWAR= NING: There is a risk of accidental overwriting by other code/data.\n", New= FdtBlobBase)); + } + + // Load the Original FDT tree into the new region + err =3D 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 Dev= ice Tree + gBS->FreePages (FdtBlobBase, EFI_SIZE_TO_PAGES (OriginalFdtSize)); + + fdt =3D (VOID*)(UINTN)NewFdtBlobBase; + + node =3D fdt_subnode_offset (fdt, 0, "chosen"); + if (node < 0) { + // The 'chosen' node does not exist, create it + node =3D fdt_add_subnode (fdt, 0, "chosen"); + if (node < 0) { + DEBUG ((EFI_D_ERROR, "Error on finding 'chosen' node\n")); + Status =3D EFI_INVALID_PARAMETER; + goto FAIL_COMPLETE_FDT; + } + } + + // Merge bootargs into command line arguments + BootArg =3D fdt_getprop (fdt, node, "bootargs", &lenp); + if (BootArg !=3D 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 =3D (UINTN)fdt_totalsize ((VOID*)(UINTN)(NewFdtBlobBase)); + + Status =3D 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; =20 Status =3D ParseAndroidBootImg ( Buffer, @@ -86,62 +204,64 @@ BootAndroidBootImg ( return Status; } =20 - KernelDevicePath =3D MemoryDevicePathTemplate; - - // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order= to - // appease GCC. - KernelDevicePath.Node1.StartingAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)= Kernel; - KernelDevicePath.Node1.EndingAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)= Kernel + KernelSize; - - RamdiskDevicePath =3D NULL; - if (RamdiskSize !=3D 0) { - RamdiskDevicePath =3D (MEMORY_DEVICE_PATH*)DuplicateDevicePath ((EFI_D= EVICE_PATH_PROTOCOL*) &MemoryDevicePathTemplate); + /* Install Fdt that is attached at the end of kernel */ + KernelSize =3D *(UINT32 *)((EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KERNEL_= IMAGE_STEXT_OFFSET) + + *(UINT32 *)((EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KERNEL_IM= AGE_RAW_SIZE_OFFSET); =20 - RamdiskDevicePath->Node1.StartingAddress =3D (EFI_PHYSICAL_ADDRESS)(UI= NTN) Ramdisk; - RamdiskDevicePath->Node1.EndingAddress =3D ((EFI_PHYSICAL_ADDRESS)(U= INTN) Ramdisk) + RamdiskSize; + /* FDT is at the end of kernel image */ + FdtBase =3D (EFI_PHYSICAL_ADDRESS)(UINTN)Kernel + KernelSize; + FdtPtr =3D (UINT8 *)(FdtBase + FDT_SIZE_OFFSET); + for (Index =3D 0, FdtSize =3D 0; Index < sizeof (UINT32); Index++) { + FdtSize |=3D *FdtPtr << ((sizeof (UINT32) - 1 - Index) * 8); + FdtPtr++; } =20 - // - // Boot Linux using the Legacy Linux Loader - // - - Status =3D LocateEfiApplicationInFvByGuid (&mLinuxLoaderAppGuid, &LinuxL= oaderDevicePath); - if (EFI_ERROR (Status)) { - Print (L"Couldn't Boot Linux: %d\n", Status); - return EFI_DEVICE_ERROR; - } - - KernelDevicePathTxt =3D ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOC= OL *) &KernelDevicePath, FALSE, FALSE); - if (KernelDevicePathTxt =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - RamdiskDevicePathTxt =3D ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTO= COL *) RamdiskDevicePath, FALSE, FALSE); - if (RamdiskDevicePathTxt =3D=3D NULL) { + NewKernelArg =3D AllocateZeroPool (BOOTIMG_KERNEL_ARGS_SIZE); + if (NewKernelArg =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Fail to allocate memory\n")); return EFI_OUT_OF_RESOURCES; } =20 - // Initialize Legacy Linux loader command line - LoadOptions =3D CatSPrint (NULL, LINUX_LOADER_COMMAND_LINE, KernelDevice= PathTxt, RamdiskDevicePathTxt, KernelArgs); - if (LoadOptions =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + // Set the ramdisk in command line arguments + UnicodeSPrint ( + (CHAR16 *)NewKernelArg, BOOTIMG_KERNEL_ARGS_SIZE, + L"initrd=3D0x%x,0x%x ", + (UINTN)Ramdisk, (UINTN)RamdiskSize + ); + // Merge kernel arguments from Android boot image into command line argu= ments + 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 =3D Platform->GetKernelArgs (); + if (PlatformKernelArgs) { + StrCatS ((CHAR16 *)NewKernelArg, BOOTIMG_KERNEL_ARGS_SIZE >> 1, Platfo= rmKernelArgs); } - - Status =3D BdsStartEfiApplication (gImageHandle, LinuxLoaderDevicePath, = StrSize (LoadOptions), LoadOptions); + Status =3D 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; } =20 - if (RamdiskDevicePath) { - FreePool (RamdiskDevicePathTxt); - FreePool (RamdiskDevicePath); - } + KernelDevicePath =3D MemoryDevicePathTemplate; + + // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order= to + // appease GCC. + KernelDevicePath.Node1.StartingAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)= Kernel; + KernelDevicePath.Node1.EndingAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN)= Kernel + KernelSize; + + Status =3D gBS->LoadImage (TRUE, gImageHandle, (EFI_DEVICE_PATH *)&Kerne= lDevicePath, (VOID*)(UINTN)Kernel, KernelSize, &ImageHandle); =20 - FreePool (KernelDevicePathTxt); + // Set kernel arguments + Status =3D gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGui= d, (VOID **) &ImageInfo); + ImageInfo->LoadOptions =3D NewKernelArg; + ImageInfo->LoadOptionsSize =3D StrLen (NewKernelArg) * sizeof (CHAR16); =20 - // 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 =3D gBS->StartImage (ImageHandle, NULL, NULL); + // Clear the Watchdog Timer after the image returns + gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); return EFI_SUCCESS; } --=20 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel