From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-x236.google.com (mail-wm0-x236.google.com [IPv6:2a00:1450:400c:c09::236]) (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 4111F2095DE5D for ; Thu, 10 Aug 2017 04:10:49 -0700 (PDT) Received: by mail-wm0-x236.google.com with SMTP id m85so16997545wma.0 for ; Thu, 10 Aug 2017 04:13:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=WQaEnthJXMxI4AjFvKFI+twmQkt1pZku40acZG28FGA=; b=N5up57meZDAvYLXMn/wzed4RlGxH0GnsQ+E/XOx6mw4dlILrptg6sEY0er4WcgXIdI KhoyJjn+6ujCc9+mjDC7kxDeJJI46U+/i4ij1NScJIYwmMG0eiMUn1jAMc6Qfi9tvVt0 YRmApLn9Z/7onVa21AnQe2JkJJsv/l5tQxlAY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=WQaEnthJXMxI4AjFvKFI+twmQkt1pZku40acZG28FGA=; b=Qmooc8+teWNKeueKA0KQPX5p0M21xO7tz33Vg5c5GSWEbR3trFQM55d7IEraVDak3I Qw0MJkqMYQ+PMRiL7v0DehdUIMXuOewLTPs561zT++nlGnJlkuphOB7q02/YtFgYXz0u l1Pr0Q+7Rda9SJyIMws5KCaMuFVfChj2msys9xWj2aLuKnpfjdDeXZ5EJ7fd/uRb/GZc aKYRPP85JGaYos4wchLJSSGeEXyTp866Gd9qUgWrKR1C2JLeHsPL+K4zj/C/C4hrLID/ ikvH/WCUUuMBwoBYGPDW0eZUUZG2E306LyMvYXeYusZIk9c2vl75ZwecR/oyZTPkawGD nkhg== X-Gm-Message-State: AHYfb5gmMSu5UDZETnt4I2pntyFoCIJZsmob7A+ygKlVGZG7K0Be2U+0 ExHV0ihHB+JRSLsy X-Received: by 10.28.92.143 with SMTP id q137mr7349807wmb.167.1502363586583; Thu, 10 Aug 2017 04:13:06 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id o30sm8311756wrb.76.2017.08.10.04.13.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 10 Aug 2017 04:13:05 -0700 (PDT) Date: Thu, 10 Aug 2017 12:13:04 +0100 From: Leif Lindholm To: Jun Nie Cc: haojian.zhuang@linaro.org, ard.biesheuvel@linaro.org, edk2-devel@lists.01.org, linaro-uefi@lists.linaro.org, shawn.guo@linaro.org, jason.liu@linaro.org Message-ID: <20170810111303.x3mgaplnopqrv6bl@bivouac.eciton.net> References: <1502275163-3690-1-git-send-email-jun.nie@linaro.org> <1502275163-3690-2-git-send-email-jun.nie@linaro.org> MIME-Version: 1.0 In-Reply-To: <1502275163-3690-2-git-send-email-jun.nie@linaro.org> User-Agent: NeoMutt/20170113 (1.7.2) Subject: Re: [PATCH v6 2/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: , X-List-Received-Date: Thu, 10 Aug 2017 11:10:49 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Aug 09, 2017 at 06:39:23PM +0800, Jun Nie wrote: > Add an android kernel loader that could load kernel from storage > device. > This android boot image BDS add addtitional cmdline/dtb/ramfs > support besides kernel that is introduced by Android boot header. > > This patch is derived from Haojian's code as below link. > https://patches.linaro.org/patch/94683/ > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Jun Nie > --- > .../Application/AndroidBoot/AndroidBootApp.c | 140 ++++++ > .../Application/AndroidBoot/AndroidBootApp.inf | 64 +++ > EmbeddedPkg/EmbeddedPkg.dec | 2 + > EmbeddedPkg/EmbeddedPkg.dsc | 2 + > EmbeddedPkg/Include/Library/AndroidBootImgLib.h | 13 + > EmbeddedPkg/Include/Protocol/AndroidBootImg.h | 47 ++ > .../Library/AndroidBootImgLib/AndroidBootImgLib.c | 471 +++++++++++++++++++++ > .../AndroidBootImgLib/AndroidBootImgLib.inf | 48 +++ > 8 files changed, 787 insertions(+) > create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.c > create mode 100644 EmbeddedPkg/Application/AndroidBoot/AndroidBootApp.inf > create mode 100644 EmbeddedPkg/Include/Protocol/AndroidBootImg.h > create mode 100644 EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c > create mode 100644 EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf > > diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c > new file mode 100644 > index 0000000..cb4fb67 > --- /dev/null > +++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c > @@ -0,0 +1,471 @@ > +/** @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 > + > +#define FDT_ADDITIONAL_ENTRIES_SIZE 0x400 > + > +typedef struct { > + MEMMAP_DEVICE_PATH Node1; > + EFI_DEVICE_PATH_PROTOCOL End; > +} MEMORY_DEVICE_PATH; > + > +STATIC ANDROID_BOOTIMG_PROTOCOL *mAndroidBootImg; > + > +STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate = > +{ > + { > + { > + 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 > +AndroidBootImgGetImgSize ( > + IN VOID *BootImg, > + OUT UINTN *ImgSize > + ) > +{ > + ANDROID_BOOTIMG_HEADER *Header; > + > + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; > + > + if (AsciiStrnCmp ((CONST CHAR8 *)Header->BootMagic, ANDROID_BOOT_MAGIC, > + ANDROID_BOOT_MAGIC_LENGTH) != 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + /* The page size is not specified, but it should be power of 2 at least */ > + ASSERT (IS_VALID_ANDROID_PAGE_SIZE (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 > +AndroidBootImgGetKernelInfo ( > + IN VOID *BootImg, > + OUT VOID **Kernel, > + OUT UINTN *KernelSize > + ) > +{ > + ANDROID_BOOTIMG_HEADER *Header; > + > + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; > + > + if (AsciiStrnCmp ((CONST CHAR8 *)Header->BootMagic, ANDROID_BOOT_MAGIC, > + ANDROID_BOOT_MAGIC_LENGTH) != 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (Header->KernelSize == 0) { > + return EFI_NOT_FOUND; > + } > + > + ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize)); > + > + *KernelSize = Header->KernelSize; > + *Kernel = BootImg + Header->PageSize; > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +AndroidBootImgGetRamdiskInfo ( > + 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 ((CONST CHAR8 *)Header->BootMagic, ANDROID_BOOT_MAGIC, > + ANDROID_BOOT_MAGIC_LENGTH) != 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + ASSERT (IS_VALID_ANDROID_PAGE_SIZE (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 > +AndroidBootImgGetSecondBootLoaderInfo ( > + IN VOID *BootImg, > + OUT VOID **Second, > + OUT UINTN *SecondSize > + ) > +{ > + ANDROID_BOOTIMG_HEADER *Header; > + UINTN BootImgBytePtr; > + > + // Cast to UINT8 so we can do pointer arithmetic > + BootImgBytePtr = (UINTN) BootImg; Why is this BootImgBytePtr kept around? It is completely redundant. Using special pointers to avoid dealing with pointer arithmetic is an antipattern, and although the actual pointer was removed here, the same antipattern is followed. Please change as I asked last time around - DELETE BootImgBytePtr completely... > + > + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; > + > + if (AsciiStrnCmp ((CONST CHAR8 *)Header->BootMagic, ANDROID_BOOT_MAGIC, > + ANDROID_BOOT_MAGIC_LENGTH) != 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + ASSERT (IS_VALID_ANDROID_PAGE_SIZE (Header->PageSize)); > + > + *SecondSize = Header->SecondStageBootloaderSize; > + > + if (Header->SecondStageBootloaderSize != 0) { > + *Second = (VOID *) (BootImgBytePtr ... and use (UINTN)BootImg here. > + + Header->PageSize > + + ALIGN_VALUE (Header->KernelSize, Header->PageSize) > + + ALIGN_VALUE (Header->RamdiskSize, Header->PageSize)); > + } > + return EFI_SUCCESS; > +} Now, before I noticed this I was just running some final sanity checks and noticed this code is not 32-bit safe. If you can also fold in the following: <<< diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c index cb4fb6740a..bf33c64d25 100644 --- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c +++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c @@ -259,7 +259,7 @@ AndroidBootImgLocateFdt ( INTN AndroidBootImgGetChosenNode ( - IN EFI_PHYSICAL_ADDRESS UpdatedFdtBase + IN UINTN UpdatedFdtBase ) { IN INTN ChosenNode; @@ -277,10 +277,10 @@ AndroidBootImgGetChosenNode ( EFI_STATUS AndroidBootImgSetProperty64 ( - IN EFI_PHYSICAL_ADDRESS UpdatedFdtBase, - IN INTN ChosenNode, - IN CHAR8 *PropertyName, - IN UINT64 Val + IN UINTN UpdatedFdtBase, + IN INTN ChosenNode, + IN CHAR8 *PropertyName, + IN UINT64 Val ) { INTN Err; @@ -334,7 +334,7 @@ AndroidBootImgUpdateFdt ( } // Load the Original FDT tree into the new region - Err = fdt_open_into(FdtBase, (VOID*)UpdatedFdtBase, NewFdtSize); + Err = fdt_open_into(FdtBase, (VOID*)(UINTN)UpdatedFdtBase, NewFdtSize); if (Err) { DEBUG ((DEBUG_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Err))); Status = EFI_INVALID_PARAMETER; @@ -348,14 +348,14 @@ AndroidBootImgUpdateFdt ( Status = AndroidBootImgSetProperty64 (UpdatedFdtBase, ChosenNode, "linux,initrd-start", - (UINT64)RamdiskData); + (UINTN)RamdiskData); if (EFI_ERROR (Status)) { goto Fdt_Exit; } Status = AndroidBootImgSetProperty64 (UpdatedFdtBase, ChosenNode, "linux,initrd-end", - (UINT64)(RamdiskData + RamdiskSize)); + (UINTN)(RamdiskData + RamdiskSize)); if (EFI_ERROR (Status)) { goto Fdt_Exit; } >>> we can go ahead and commit this patch. Note that 1/2 has already been pushed, so no need to resend. Regards, Leif > + > +EFI_STATUS > +AndroidBootImgGetKernelArgs ( > + IN VOID *BootImg, > + OUT CHAR8 *KernelArgs > + ) > +{ > + ANDROID_BOOTIMG_HEADER *Header; > + > + Header = (ANDROID_BOOTIMG_HEADER *) BootImg; > + AsciiStrnCpyS (KernelArgs, ANDROID_BOOTIMG_KERNEL_ARGS_SIZE, Header->KernelArgs, > + ANDROID_BOOTIMG_KERNEL_ARGS_SIZE); > + > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +AndroidBootImgGetFdt ( > + IN VOID *BootImg, > + IN VOID **FdtBase > + ) > +{ > + UINTN SecondLoaderSize; > + EFI_STATUS Status; > + > + /* Check whether FDT is located in second boot region as some vendor do so, > + * because second loader is never used as far as I know. */ > + Status = AndroidBootImgGetSecondBootLoaderInfo ( > + BootImg, > + FdtBase, > + &SecondLoaderSize > + ); > + return Status; > +} > + > +EFI_STATUS > +AndroidBootImgUpdateArgs ( > + IN VOID *BootImg, > + OUT VOID *KernelArgs > + ) > +{ > + CHAR8 ImageKernelArgs[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE]; > + EFI_STATUS Status; > + > + // Get kernel arguments from Android boot image > + Status = AndroidBootImgGetKernelArgs (BootImg, ImageKernelArgs); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + AsciiStrToUnicodeStrS (ImageKernelArgs, KernelArgs, > + ANDROID_BOOTIMG_KERNEL_ARGS_SIZE >> 1); > + // Append platform kernel arguments > + if(mAndroidBootImg->AppendArgs) { > + Status = mAndroidBootImg->AppendArgs (KernelArgs, > + ANDROID_BOOTIMG_KERNEL_ARGS_SIZE); > + } > + return Status; > +} > + > +EFI_STATUS > +AndroidBootImgLocateFdt ( > + IN VOID *BootImg, > + IN VOID **FdtBase > + ) > +{ > + INTN Err; > + EFI_STATUS Status; > + > + Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, FdtBase); > + if (!EFI_ERROR (Status)) { > + return EFI_SUCCESS; > + } > + > + Status = AndroidBootImgGetFdt (BootImg, FdtBase); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + Err = fdt_check_header (*FdtBase); > + if (Err != 0) { > + DEBUG ((DEBUG_ERROR, "ERROR: Device Tree header not valid (Err:%d)\n", > + Err)); > + return EFI_INVALID_PARAMETER; > + } > + return EFI_SUCCESS; > +} > + > +INTN > +AndroidBootImgGetChosenNode ( > + IN EFI_PHYSICAL_ADDRESS UpdatedFdtBase > + ) > +{ > + IN INTN ChosenNode; > + > + ChosenNode = fdt_subnode_offset ((CONST VOID *)UpdatedFdtBase, 0, "chosen"); > + if (ChosenNode < 0) { > + ChosenNode = fdt_add_subnode((VOID *)UpdatedFdtBase, 0, "chosen"); > + if (ChosenNode < 0) { > + DEBUG ((DEBUG_ERROR, "Fail to find fdt node chosen!\n")); > + return 0; > + } > + } > + return ChosenNode; > +} > + > +EFI_STATUS > +AndroidBootImgSetProperty64 ( > + IN EFI_PHYSICAL_ADDRESS UpdatedFdtBase, > + IN INTN ChosenNode, > + IN CHAR8 *PropertyName, > + IN UINT64 Val > + ) > +{ > + INTN Err; > + struct fdt_property *Property; > + int Len; > + > + Property = fdt_get_property_w((VOID *)UpdatedFdtBase, ChosenNode, > + PropertyName, &Len); > + if (NULL == Property && Len == -FDT_ERR_NOTFOUND) { > + Val = cpu_to_fdt64(Val); > + Err = fdt_appendprop ((VOID *)UpdatedFdtBase, ChosenNode, > + PropertyName, &Val, sizeof (UINT64)); > + if (Err) { > + DEBUG ((DEBUG_ERROR, "fdt_appendprop() fail: %a\n", fdt_strerror (Err))); > + return EFI_INVALID_PARAMETER; > + } > + } else if (Property != NULL) { > + Err = fdt_setprop_u64((VOID *)UpdatedFdtBase, ChosenNode, > + PropertyName, Val); > + if (Err) { > + DEBUG ((DEBUG_ERROR, "fdt_setprop_u64() fail: %a\n", fdt_strerror (Err))); > + return EFI_INVALID_PARAMETER; > + } > + } else { > + DEBUG ((DEBUG_ERROR, "Failed to set fdt Property %a\n", PropertyName)); > + return EFI_INVALID_PARAMETER; > + } > + return EFI_SUCCESS; > +} > + > +EFI_STATUS > +AndroidBootImgUpdateFdt ( > + IN VOID *BootImg, > + IN VOID *FdtBase, > + IN VOID *RamdiskData, > + IN UINTN RamdiskSize > + ) > +{ > + INTN ChosenNode, Err, NewFdtSize; > + EFI_STATUS Status; > + EFI_PHYSICAL_ADDRESS UpdatedFdtBase, NewFdtBase; > + > + NewFdtSize = (UINTN)fdt_totalsize (FdtBase) > + + FDT_ADDITIONAL_ENTRIES_SIZE; > + Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, > + EFI_SIZE_TO_PAGES (NewFdtSize), &UpdatedFdtBase); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_WARN, "Warning: Failed to reallocate FDT, err %d.\n", > + Status)); > + return Status; > + } > + > + // Load the Original FDT tree into the new region > + Err = fdt_open_into(FdtBase, (VOID*)UpdatedFdtBase, NewFdtSize); > + if (Err) { > + DEBUG ((DEBUG_ERROR, "fdt_open_into(): %a\n", fdt_strerror (Err))); > + Status = EFI_INVALID_PARAMETER; > + goto Fdt_Exit; > + } > + > + ChosenNode = AndroidBootImgGetChosenNode(UpdatedFdtBase); > + if (!ChosenNode) { > + goto Fdt_Exit; > + } > + > + Status = AndroidBootImgSetProperty64 (UpdatedFdtBase, ChosenNode, > + "linux,initrd-start", > + (UINT64)RamdiskData); > + if (EFI_ERROR (Status)) { > + goto Fdt_Exit; > + } > + > + Status = AndroidBootImgSetProperty64 (UpdatedFdtBase, ChosenNode, > + "linux,initrd-end", > + (UINT64)(RamdiskData + RamdiskSize)); > + if (EFI_ERROR (Status)) { > + goto Fdt_Exit; > + } > + > + if (mAndroidBootImg->UpdateDtb) { > + Status = mAndroidBootImg->UpdateDtb (UpdatedFdtBase, &NewFdtBase); > + if (EFI_ERROR (Status)) { > + goto Fdt_Exit; > + } > + } > + > + Status = gBS->InstallConfigurationTable ( > + &gFdtTableGuid, > + (VOID *)(UINTN)NewFdtBase > + ); > + if (!EFI_ERROR (Status)) { > + return EFI_SUCCESS; > + } > + > +Fdt_Exit: > + gBS->FreePages (UpdatedFdtBase, EFI_SIZE_TO_PAGES (NewFdtSize)); > + return Status; > +} > + > +EFI_STATUS > +AndroidBootImgBoot ( > + IN VOID *Buffer, > + IN UINTN BufferSize > + ) > +{ > + EFI_STATUS Status; > + VOID *Kernel; > + UINTN KernelSize; > + MEMORY_DEVICE_PATH KernelDevicePath; > + EFI_HANDLE ImageHandle; > + VOID *NewKernelArg; > + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; > + VOID *RamdiskData; > + UINTN RamdiskSize; > + IN VOID *FdtBase; > + > + Status = gBS->LocateProtocol (&gAndroidBootImgProtocolGuid, NULL, > + (VOID **) &mAndroidBootImg); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = AndroidBootImgGetKernelInfo ( > + Buffer, > + &Kernel, > + &KernelSize > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + NewKernelArg = AllocateZeroPool (ANDROID_BOOTIMG_KERNEL_ARGS_SIZE); > + if (NewKernelArg == NULL) { > + DEBUG ((DEBUG_ERROR, "Fail to allocate memory\n")); > + return EFI_OUT_OF_RESOURCES; > + } > + > + Status = AndroidBootImgUpdateArgs (Buffer, NewKernelArg); > + if (EFI_ERROR (Status)) { > + FreePool (NewKernelArg); > + return Status; > + } > + > + Status = AndroidBootImgGetRamdiskInfo ( > + Buffer, > + &RamdiskData, > + &RamdiskSize > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = AndroidBootImgLocateFdt (Buffer, &FdtBase); > + if (EFI_ERROR (Status)) { > + FreePool (NewKernelArg); > + return Status; > + } > + > + Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize); > + if (EFI_ERROR (Status)) { > + FreePool (NewKernelArg); > + return Status; > + } > + > + KernelDevicePath = mMemoryDevicePathTemplate; > + > + 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, 0x10000, 0, NULL); > + // Start the image > + Status = gBS->StartImage (ImageHandle, NULL, NULL); > + // Clear the Watchdog Timer if the image returns > + gBS->SetWatchdogTimer (0, 0x10000, 0, NULL); > + return EFI_SUCCESS; > +} > diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf > new file mode 100644 > index 0000000..c92bac0 > --- /dev/null > +++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.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 = AndroidBootImgLib > + FILE_GUID = ed3b8739-6fa7-4cb1-8aeb-2496f8fcaefa > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = AndroidBootImgLib > + > +# > +# The following information is for reference only and not required by the build tools. > +# > +# VALID_ARCHITECTURES = ARM AARCH64 > +# > + > +[Sources] > + AndroidBootImgLib.c > + > +[LibraryClasses] > + DebugLib > + FdtLib > + PrintLib > + UefiBootServicesTableLib > + UefiLib > + > +[Packages] > + EmbeddedPkg/EmbeddedPkg.dec > + MdePkg/MdePkg.dec > + > +[Protocols] > + gAndroidBootImgProtocolGuid > + > +[Guids] > + gFdtTableGuid > -- > 1.9.1 >