From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-x230.google.com (mail-wr0-x230.google.com [IPv6:2a00:1450:400c:c0c::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 A113F21A134AC for ; Thu, 4 May 2017 03:48:47 -0700 (PDT) Received: by mail-wr0-x230.google.com with SMTP id w50so5576796wrc.0 for ; Thu, 04 May 2017 03:48:47 -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=hj41k9BOeat4hgBpPb4copHE+c5D+1iT6TzgFhi39j4=; b=eiCIvLe9s4VORPbSz5twH1mWg+UqSv4WHX4jz1wDEFHGlHwKURaRATk7+a8IXCVsjK vOGflf22xnL6Ko6gcCWHByYpIfoDEl9quNafM/xt/OmTUucx5lr8N7JEsHbj8MXhnT4s umGyLjYpKtZzRrt/9JzIDcgStHEiAL0kp1T6U= 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=hj41k9BOeat4hgBpPb4copHE+c5D+1iT6TzgFhi39j4=; b=QFoTqzs5hg7lxmyGR2YJEUkhQwJQW9qtO80kqy21V0BHrR+VHHmUX747QAnDKCHLlq yUarR2bh9nYkw7AtCWQDGPVeVl8RBahFZYyr1VpUtrUOfJoQWswvhC/D9P7w8lUGUXAA tFMuGW4ejK583C4sfqorq+on5PZU+LZmkx1KPdlGW6LdU0hAiV3ddpJaeLy135LOleV3 Pi000PM20xtctHz/pc66xYOjDTcyJWHxP/KcDis4lPFz/hT8lZ9EwVT0CO+ao9EccCdO GKlj2RhpWy515x12Io768jSAU2lWYXXBJFG7Y0qZVRIt31SlmKgIW8hPkPzJw9J4D2th ZvRA== X-Gm-Message-State: AN3rC/6ZvtEq3Gh2uU3O8FuLsDUD6S2pK6RazIyhKUMeZnYAsmm3FsYH y/ApcZk72cTeBWA/ X-Received: by 10.223.179.93 with SMTP id k29mr26185483wrd.23.1493894925895; Thu, 04 May 2017 03:48:45 -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 188sm1327241wmf.29.2017.05.04.03.48.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 04 May 2017 03:48:45 -0700 (PDT) Date: Thu, 4 May 2017 11:48:43 +0100 From: Leif Lindholm To: Haojian Zhuang Cc: ard.biesheuvel@linaro.org, edk2-devel@lists.01.org Message-ID: <20170504104843.GT1657@bivouac.eciton.net> References: <1492163732-3264-1-git-send-email-haojian.zhuang@linaro.org> MIME-Version: 1.0 In-Reply-To: <1492163732-3264-1-git-send-email-haojian.zhuang@linaro.org> User-Agent: Mutt/1.5.23 (2014-03-12) Subject: Re: [PATCH] EmbeddedPkg/AndroidFastbootApp: support sparse image 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, 04 May 2017 10:48:48 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Apr 14, 2017 at 05:55:32PM +0800, Haojian Zhuang wrote: > Support sparse image that is reformatted from large raw image and > splitted into a few smaller images. The sparse image follows the > rule of Android Sparse Image format. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Haojian Zhuang > --- > .../AndroidFastboot/AndroidFastbootApp.c | 127 +++++++++++++++++++-- > .../Include/Protocol/AndroidFastbootPlatform.h | 23 ++++ > 2 files changed, 142 insertions(+), 8 deletions(-) > > diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c > index 61abc67..4883a77 100644 > --- a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c > +++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c > @@ -25,7 +25,34 @@ > #include > #include > > -#define ANDROID_FASTBOOT_VERSION "0.4" > +#define ANDROID_FASTBOOT_VERSION "0.5" Could this #define, as well as the ones below, and the typedefs, and the macros, all be moved into AndroidFastbootApp.h? Actually, I'm confused. In current upstream EDK2, this #define _is_ in AndroidFastbootApp.h. What is this patch against? > + > +#define SPARSE_HEADER_MAGIC 0xED26FF3A > +#define CHUNK_TYPE_RAW 0xCAC1 > +#define CHUNK_TYPE_FILL 0xCAC2 > +#define CHUNK_TYPE_DONT_CARE 0xCAC3 > +#define CHUNK_TYPE_CRC32 0xCAC4 > + > +#define FILL_BUF_SIZE 1024 Is this meeting some specification limit, or an arbitrary value? > + > +typedef struct _SPARSE_HEADER { > + UINT32 Magic; > + UINT16 MajorVersion; > + UINT16 MinorVersion; > + UINT16 FileHeaderSize; > + UINT16 ChunkHeaderSize; > + UINT32 BlockSize; > + UINT32 TotalBlocks; > + UINT32 TotalChunks; > + UINT32 ImageChecksum; > +} SPARSE_HEADER; > + > +typedef struct _CHUNK_HEADER { > + UINT16 ChunkType; > + UINT16 Reserved1; > + UINT32 ChunkSize; > + UINT32 TotalSize; > +} CHUNK_HEADER; > > /* > * UEFI Application using the FASTBOOT_TRANSPORT_PROTOCOL and > @@ -139,13 +166,83 @@ HandleDownload ( > } > > STATIC > +EFI_STATUS > +FlashSparseImage ( > + IN CHAR8 *PartitionName, > + IN SPARSE_HEADER *SparseHeader > + ) > +{ > + EFI_STATUS Status; > + UINTN Chunk, Offset = 0, Index; > + VOID *Image; > + CHUNK_HEADER *ChunkHeader; > + UINT32 FillBuf[FILL_BUF_SIZE]; > + CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH]; > + > + Image = (VOID *)SparseHeader; > + Image += SparseHeader->FileHeaderSize; > + for (Chunk = 0; Chunk < SparseHeader->TotalChunks; Chunk++) { > + ChunkHeader = (CHUNK_HEADER *)Image; > + DEBUG ((DEBUG_INFO, "Chunk #%d - Type: 0x%x Size: %d TotalSize: %d Offset %d\n", > + (Chunk+1), ChunkHeader->ChunkType, ChunkHeader->ChunkSize, > + ChunkHeader->TotalSize, Offset)); > + Image += sizeof (CHUNK_HEADER); > + switch (ChunkHeader->ChunkType) { > + case CHUNK_TYPE_RAW: > + Status = mPlatform->FlashPartitionEx ( > + PartitionName, > + Offset, > + ChunkHeader->ChunkSize * SparseHeader->BlockSize, > + Image > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + Image += ChunkHeader->ChunkSize * SparseHeader->BlockSize; > + Offset += ChunkHeader->ChunkSize * SparseHeader->BlockSize; > + break; > + case CHUNK_TYPE_FILL: > + SetMem32 (FillBuf, FILL_BUF_SIZE * sizeof (UINT32), *(UINT32 *)Image); It's in scope, "sizeof (FillBuf)" would be more clear (and less error prone). > + Image += sizeof (UINT32); > + for (Index = 0; Index < ChunkHeader->ChunkSize; Index++) { > + Status = mPlatform->FlashPartitionEx ( > + PartitionName, > + Offset, > + SparseHeader->BlockSize, > + FillBuf > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + Offset += SparseHeader->BlockSize; > + } > + break; > + case CHUNK_TYPE_DONT_CARE: > + Offset += ChunkHeader->ChunkSize * SparseHeader->BlockSize; > + break; > + default: > + UnicodeSPrint ( > + OutputString, > + sizeof (OutputString), > + L"Unsupported Chunk Type:0x%x\n", > + ChunkHeader->ChunkType > + ); > + mTextOut->OutputString (mTextOut, OutputString); > + break; > + } > + } > + return Status; > +} > + > +STATIC > VOID > HandleFlash ( > IN CHAR8 *PartitionName > ) > { > - EFI_STATUS Status; > - CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH]; > + EFI_STATUS Status; > + CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH]; > + SPARSE_HEADER *SparseHeader; > > // Build output string > UnicodeSPrint (OutputString, sizeof (OutputString), L"Flashing partition %a\r\n", PartitionName); > @@ -157,11 +254,25 @@ HandleFlash ( > return; > } > > - Status = mPlatform->FlashPartition ( > - PartitionName, > - mNumDataBytes, > - mDataBuffer > - ); > + SparseHeader = (SPARSE_HEADER *)mDataBuffer; > + if (SparseHeader->Magic == SPARSE_HEADER_MAGIC) { > + DEBUG ((DEBUG_INFO, "Sparse Magic: 0x%x Major: %d Minor: %d fhs: %d chs: %d bs: %d tbs: %d tcs: %d checksum: %d \n", > + SparseHeader->Magic, SparseHeader->MajorVersion, SparseHeader->MinorVersion, SparseHeader->FileHeaderSize, > + SparseHeader->ChunkHeaderSize, SparseHeader->BlockSize, SparseHeader->TotalBlocks, > + SparseHeader->TotalChunks, SparseHeader->ImageChecksum)); > + if (SparseHeader->MajorVersion != 1) { > + DEBUG ((DEBUG_ERROR, "Sparse image version %d.%d not supported.\n", Indent is two spaces. > + SparseHeader->MajorVersion, SparseHeader->MinorVersion)); These indents (two DEBUG statements above) look a bit funky. Should the continuation lines not line up with DEBUG_? / Leif > + return; > + } > + Status = FlashSparseImage (PartitionName, SparseHeader); > + } else { > + Status = mPlatform->FlashPartition ( > + PartitionName, > + mNumDataBytes, > + mDataBuffer > + ); > + } > if (Status == EFI_NOT_FOUND) { > SEND_LITERAL ("FAILNo such partition."); > mTextOut->OutputString (mTextOut, L"No such partition.\r\n"); > diff --git a/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h b/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h > index a9b4aac..2cb51eb 100644 > --- a/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h > +++ b/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h > @@ -133,6 +133,28 @@ EFI_STATUS > IN CHAR8 *Command > ); > > +/* > + Flash the partition named (according to a platform-specific scheme) > + PartitionName, with partition offset and the image pointed to by Buffer, > + whose size is BufferSize. > + > + @param[in] PartitionName Null-terminated name of partition to write. > + @param[in] Offset Offset of partition. > + @param[in] BufferSize Size of Buffer in byets. > + @param[in] Buffer Data to write to partition. > + > + @retval EFI_NOT_FOUND No such partition. > + @retval EFI_DEVICE_ERROR Flashing failed. > +*/ > +typedef > +EFI_STATUS > +(*FASTBOOT_PLATFORM_FLASH_EX) ( > + IN CHAR8 *PartitionName, > + IN UINTN Offset, > + IN UINTN BufferSize, > + IN VOID *Buffer > + ); > + > typedef struct _FASTBOOT_PLATFORM_PROTOCOL { > FASTBOOT_PLATFORM_INIT Init; > FASTBOOT_PLATFORM_UN_INIT UnInit; > @@ -140,6 +162,7 @@ typedef struct _FASTBOOT_PLATFORM_PROTOCOL { > FASTBOOT_PLATFORM_ERASE ErasePartition; > FASTBOOT_PLATFORM_GETVAR GetVar; > FASTBOOT_PLATFORM_OEM_COMMAND DoOemCommand; > + FASTBOOT_PLATFORM_FLASH_EX FlashPartitionEx; > } FASTBOOT_PLATFORM_PROTOCOL; > > #endif > -- > 2.7.4 >