From patchwork Fri May 12 03:46: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: 99701 Delivered-To: patch@linaro.org Received: by 10.140.96.100 with SMTP id j91csp111774qge; Thu, 11 May 2017 20:46:20 -0700 (PDT) X-Received: by 10.99.154.18 with SMTP id o18mr2075386pge.59.1494560780029; Thu, 11 May 2017 20:46:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494560780; cv=none; d=google.com; s=arc-20160816; b=DDCRYiPpHgVrqvGld0mfFke84ny1QbRVmE9+d593sf1rYfui6QrUUOxIJXPFG0fbPk g+PsqPda4cN5MEEY12uKGqRC1Yt25EqRU3x4DRklMnb5ydlN19I+AibIGZ/gvAyrAw6b BpeM+1k9h1kQL6HMKgvxow3KEJEZpS67wtMFG2Tcp8X6P76LpUNMzFepiZkcU2eu2T75 lzGwKwS/nyCvBXjTIAzo8P/YkzIlc2rZvRY1Ad11L1Sv2C+7d+r0S6sYS4aFBjwuBny5 DP0Wv7ZBsLrdd7sp8RJ/KVv5V6NUHqw5F80ARHqFExkIGPERgbCjpD21iv9SRq4FKRir OfZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=EbcuXil2tOzMy8n3ggXFttI41bPXhFwv9DK36Hrv2II=; b=ueTwfntnTbjWgbaIe5m6bAJecVtGJhQYcRn/jw1Yyy1jw8b3b3gD9ZZcrZBhlJhdPh sqU2MHO/awOWRriH1UXmBVP+XiDKIRVpugoR9fdlln3h39DYJjBlOMAy1THrL75GqMZ7 L85GTb5rbeyNC7sfE3I5ZAna6zHocp6+shuDeXHVGGwb9nfLaBkRqlwIN0ouOmz7Ymve efJaynW0hFm24SYOK1LRCIzi7vXzTSAjQQ+Pv4LYPShZh09JHO4OVMsLJ3aeJ+DXltv4 hZ/8w+FKK7NMpYvpG6+yAlv3tbuGVZfAQ5xXDoXANl85qXLfOlyDl1U9Tw0s+n4uAZ4A IJVA== ARC-Authentication-Results: i=1; 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 Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id e8si1111057pgn.367.2017.05.11.20.46.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 11 May 2017 20:46:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; 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 071CF21A04E38; Thu, 11 May 2017 20:46:19 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-pf0-x235.google.com (mail-pf0-x235.google.com [IPv6:2607:f8b0:400e:c00::235]) (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 B027121A04E35 for ; Thu, 11 May 2017 20:46:17 -0700 (PDT) Received: by mail-pf0-x235.google.com with SMTP id e193so23453744pfh.0 for ; Thu, 11 May 2017 20:46:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BUVoCP/1PB0IC6BC0Wbrg63WrT+fw5TsCXFcXVdXQFQ=; b=ePYcW3ofBjcrSnxW6LwWm2fZswnXcZ6oWw6W11GvIB8emmLt5t9gG1jjxkPBJNERoP sM6z4eXzQ+IS2dZYbNSE56TREFTYAYW3fKbIMtgoK5U3wV/LV05ql6VaGg5SInSn8zLF j2Z4ZD1tf28gbuwaWT3ImGcyK86nPhyvBk1Nk= 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=BUVoCP/1PB0IC6BC0Wbrg63WrT+fw5TsCXFcXVdXQFQ=; b=MazhF30japwHgirNGLeBs/Zv9ry52BcOTWtOBvDaTgFxKxsys24IXPm8tbS5gMqWg8 VxOU0896zsj4sCdF6dG0OBk1sR5GwMPrr65CjinbBWCoQHl21MaxSlkm/0LdhxOCnR+d cVmh7DirNpOL7lHbXnJyujYMftynODChekgOucZqlGbf90/c51TItBHErM2Iddowjdqq y4rdFLwHXrsa6K8OVzwtcnJ7N+io0jvpbvJRl3oUM1+WizctEm9DcyhN1Ym9sXs6ykS5 PLuZxOh7WbWZgDayr1QfqN0iyG0AYQgCAad28fdBLoK1KB99IYMh0Vjexrjm27xMENHw ZE0Q== X-Gm-Message-State: AODbwcAvCrKU4NmS3sXBbqKIOMaa4JW3CKST7gsRAsZYvhksUG9ZIeqo IrCzsxaIY/2y5GIX X-Received: by 10.84.141.3 with SMTP id 3mr2772454plu.8.1494560777261; Thu, 11 May 2017 20:46:17 -0700 (PDT) Received: from localhost.localdomain ([45.56.159.224]) by smtp.gmail.com with ESMTPSA id u67sm2350782pgb.24.2017.05.11.20.46.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 11 May 2017 20:46:16 -0700 (PDT) From: Haojian Zhuang To: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, edk2-devel@lists.01.org Date: Fri, 12 May 2017 11:46:06 +0800 Message-Id: <1494560766-5451-2-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1494560766-5451-1-git-send-email-haojian.zhuang@linaro.org> References: <1494560766-5451-1-git-send-email-haojian.zhuang@linaro.org> Subject: [edk2] [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: , Cc: Haojian Zhuang MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" 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 | 100 +++++++++++++++++++-- .../AndroidFastboot/AndroidFastbootApp.h | 29 +++++- .../Include/Protocol/AndroidFastbootPlatform.h | 23 +++++ 3 files changed, 144 insertions(+), 8 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..6226bd5 100644 --- a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c +++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c @@ -138,13 +138,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, sizeof (FillBuf), *(UINT32 *)Image); + 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); @@ -156,11 +226,27 @@ 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", + SparseHeader->MajorVersion, SparseHeader->MinorVersion + )); + 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/Application/AndroidFastboot/AndroidFastbootApp.h b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h index f62660f..0e90b1f 100644 --- a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h +++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h @@ -21,7 +21,34 @@ #define BOOTIMG_KERNEL_ARGS_SIZE 512 -#define ANDROID_FASTBOOT_VERSION "0.4" +#define ANDROID_FASTBOOT_VERSION "0.5" + +#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 + +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; EFI_STATUS BootAndroidBootImg ( 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