From de1cba53fda0ad7816fc1acb43b9fb7e9ea52ed1 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Mon, 26 Feb 2024 16:39:30 +0100 Subject: [PATCH] image-android-sparse: make the CRC optional Recent Android fastboot tools don't support sparse images containing the CRC at the end of the image and instead fail with an coredump. Checking the fastboot code base there are no promising commits that this will change in the near future: | commit 94d05063ba7d2a2d614733d179c4bce94cead362 | Author: Hridya Valsaraju | Date: Tue Oct 2 10:08:38 2018 -0700 | | Remove tests for sparse images with CRC from fuzzy_fastboot | | Sparse images with CRC are currently not supported by the | Android build system. | | Test: ./fuzzy_fastboot --gtest_filter=Conformance.* | Change-Id: I6a73fb0dc5d4c77a3d1a0384c137789eb06fa956 Therefore make the crc optional and turn it of by default to have an better user experience. This is also what img2simg does except for the fact that they don't support adding the crc at all. Signed-off-by: Marco Felsch --- README.rst | 3 +++ image-android-sparse.c | 31 +++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/README.rst b/README.rst index bf82caf..ba575bd 100644 --- a/README.rst +++ b/README.rst @@ -235,6 +235,9 @@ Options: :block-size: The granularity that the sparse image uses to find "don't care" or "fill" blocks. The supported block sizes depend on the user. The default is 4k. +:add-crc: Generate sparse comptible images containing the CRC. Ensure + that your sparse tool can handle CRC sparse images. + Defaults to false. cpio **** diff --git a/image-android-sparse.c b/image-android-sparse.c index 7d4d779..f6e194d 100644 --- a/image-android-sparse.c +++ b/image-android-sparse.c @@ -29,6 +29,7 @@ struct sparse { uint32_t block_size; + cfg_bool_t add_crc; }; struct sparse_header { @@ -333,16 +334,23 @@ static int android_sparse_generate(struct image *image) crc32 = crc32_next(zeros, sparse->block_size, crc32); } - header.input_chunks++; - chunk_header.chunk_type = SPARSE_CRC32; - chunk_header.blocks = 0; - chunk_header.size = sizeof(chunk_header) + sizeof(crc32); - ret = flush_header(image, out_fd, &chunk_header, -1); - if (ret < 0) - return ret; - ret = write_data(image, out_fd, &crc32, sizeof(crc32)); - if (ret < 0) - goto out; + if (sparse->add_crc) { + /* + * Albeit CRC is supported by the sparse format, the Android + * tools don't honor the support and now starting to fail if an + * CRC is found. + */ + header.input_chunks++; + chunk_header.chunk_type = SPARSE_CRC32; + chunk_header.blocks = 0; + chunk_header.size = sizeof(chunk_header) + sizeof(crc32); + ret = flush_header(image, out_fd, &chunk_header, -1); + if (ret < 0) + return ret; + ret = write_data(image, out_fd, &crc32, sizeof(crc32)); + if (ret < 0) + goto out; + } offset = lseek(out_fd, 0, SEEK_SET); if (offset < 0) { @@ -396,6 +404,8 @@ static int android_sparse_setup(struct image *image, cfg_t *cfg) return -EINVAL; } + sparse->add_crc = cfg_getbool(cfg, "add-crc"); + image->handler_priv = sparse; return 0; } @@ -403,6 +413,7 @@ static int android_sparse_setup(struct image *image, cfg_t *cfg) static cfg_opt_t android_sparse_opts[] = { CFG_STR("image", NULL, CFGF_NONE), CFG_STR("block-size", "4k", CFGF_NONE), + CFG_BOOL("add-crc", cfg_false, CFGF_NONE), CFG_END() };