From: Jerome Forissier <jerome.forissier@linaro.org>
To: Jan Kiszka <jan.kiszka@siemens.com>, qemu-devel <qemu-devel@nongnu.org>
Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Bin Meng" <bmeng.cn@gmail.com>,
qemu-block@nongnu.org,
"Ilias Apalodimas" <ilias.apalodimas@linaro.org>
Subject: Re: [PATCH 8/8] scripts: Add helper script to generate eMMC block device images
Date: Tue, 9 Sep 2025 16:25:09 +0200 [thread overview]
Message-ID: <891712cb-0dee-482f-888c-2649ae2d4ca9@linaro.org> (raw)
In-Reply-To: <c8ee22c72a87c6bd8d9495995868cb22a633de41.1756019920.git.jan.kiszka@siemens.com>
Hi Jan,
On 8/24/25 09:18, Jan Kiszka wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
>
> As an eMMC block device image may consist of more than just the user
> data partition, provide a helper script that can compose the image from
> boot partitions, an RPMB partition and the user data image. The script
> also does the required size validation and/or rounding.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
> scripts/mkemmc.sh | 185 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 185 insertions(+)
> create mode 100755 scripts/mkemmc.sh
>
> diff --git a/scripts/mkemmc.sh b/scripts/mkemmc.sh
> new file mode 100755
> index 0000000000..5d40c2889b
> --- /dev/null
> +++ b/scripts/mkemmc.sh
> @@ -0,0 +1,185 @@
> +#!/bin/sh -e
> +#
> +# Create eMMC block device image from boot, RPMB and user data images
> +#
> +# Copyright (c) Siemens, 2025
> +#
> +# Authors:
> +# Jan Kiszka <jan.kiszka@siemens.com>
> +#
> +# This work is licensed under the terms of the GNU GPL version 2.
> +# See the COPYING file in the top-level directory.
> +#
> +
> +usage() {
> + echo "$0 [OPTIONS] USER_IMG[:SIZE] OUTPUT_IMG"
> + echo ""
> + echo "SIZE must be a power of 2. If no SIZE is specified, the size of USER_ING will"
> + echo "be used (rounded up)."
> + echo ""
> + echo "Supported options:"
> + echo " -b BOOT1_IMG[:SIZE] Add boot partitions. SIZE must be multiples of 128K. If"
> + echo " no SIZE is specified, the size of BOOT_IMG will be"
the size of BOOT1_IMG
> + echo " used (rounded up). BOOT1_IMG will be stored in boot"
> + echo " partition 1, and a boot partition 2 of the same size"
> + echo " will be created as empty (all zeros) unless -B is"
> + echo " specified as well."
> + echo " -B BOOT2_IMG Fill boot partition 2 with BOOT2_IMG. Must be combined"
> + echo " with -b which is also defining the partition size."
> + echo " -r RPMB_IMG[:SIZE] Add RPMB partition. SIZE must be multiples of 128K. If"
> + echo " no SIZE is specified, the size of RPMB_IMG will be"
> + echo " used (rounded up)."
> + echo " -h, --help This help"
> + echo ""
> + echo "All SIZE parameters support the units K, M, G. If SIZE is smaller than the"
> + echo "associated image, it will be truncated in the output image."
> + exit "$1"
> +}
> +
> +process_size() {
> + if [ "${4#*:}" = "$4" ]; then
> + if ! size=$(stat -L -c %s "$2" 2>/dev/null); then
> + echo "Missing $1 image '$2'." >&2
> + exit 1
> + fi
> + if [ "$3" = 128 ]; then
> + size=$(( (size + 128 * 1024 - 1) & ~(128 * 1024 - 1) ))
> + elif [ $(( size & (size - 1) )) -gt 0 ]; then
> + n=0
> + while [ "$size" -gt 0 ]; do
> + size=$((size >> 1))
> + n=$((n + 1))
> + done
> + size=$((1 << n))
> + fi
> + else
> + value="${4#*:}"
> + if [ "${value%K}" != "$value" ]; then
> + size=${value%K}
> + multiplier=1024
> + elif [ "${value%M}" != "$value" ]; then
> + size=${value%M}
> + multiplier=$((1024 * 1024))
> + elif [ "${value%G}" != "$value" ]; then
> + size=${value%G}
> + multiplier=$((1024 * 1024 * 1024))
> + else
> + size=$value
> + multiplier=1
> + fi
> + if [ "$size" -eq "$size" ] 2>/dev/null; then
> + size=$((size * multiplier))
> + else
> + echo "Invalid value '$value' specified for $2 image size." >&2
> + exit 1
> + fi
> + if [ "$3" = 128 ]; then
> + if [ $(( size & (128 * 1024 - 1) )) -ne 0 ]; then
> + echo "The $2 image size must be multiples of 128K." >&2
> + exit 1
> + fi
> + elif [ $(( size & (size - 1) )) -gt 0 ]; then
> + echo "The %2 image size must be power of 2." >&2
> + exit 1
> + fi
> + fi
> + echo $size
> +}
> +
> +userimg=
> +outimg=
> +bootimg1=
> +bootimg2=/dev/zero
> +bootsz=0
> +rpmbimg=
> +rpmbsz=0
> +
> +while [ $# -gt 0 ]; do
> + case "$1" in
> + -b)
> + shift
> + [ $# -ge 1 ] || usage 1
> + bootimg1=${1%%:*}
> + bootsz=$(process_size boot "$bootimg1" 128 "$1")
> + shift
> + ;;
> + -B)
> + shift
> + [ $# -ge 1 ] || usage 1
> + bootimg2=$1
> + shift
> + ;;
> + -r)
> + shift
> + [ $# -ge 1 ] || usage 1
> + rpmbimg=${1%%:*}
> + rpmbsz=$(process_size RPMB "$rpmbimg" 128 "$1")
> + shift
> + ;;
> + -h|--help)
> + usage 0
> + ;;
> + *)
> + if [ -z "$userimg" ]; then
> + userimg=${1%%:*}
> + usersz=$(process_size user "$userimg" 2 "$1")
> + elif [ -z "$outimg" ]; then
> + outimg=$1
> + else
> + usage 1
> + fi
> + shift
> + ;;
> + esac
> +done
> +
> +[ -n "$outimg" ] || usage 1
> +
> +if [ "$bootsz" -gt $((32640 * 1024)) ]; then
> + echo "Boot image size is larger than 32640K." >&2
> + exit 1
> +fi
Should we warn if BOOT1_IMG and/or BOOT2_IMG are truncated as a result
of $bootsz being too small? I can see how providing a larger size can be
useful to be able to later extend the filesystem, but a smaller size is
more likely to indicate an error I suppose?
> +if [ "$rpmbsz" -gt $((16384 * 1024)) ]; then
> + echo "RPMB image size is larger than 16384K." >&2
> + exit 1
> +fi> +
> +echo "Creating eMMC image"
> +
> +truncate "$outimg" -s 0
> +pos=0
> +
> +if [ "$bootsz" -gt 0 ]; then
> + echo " Boot partition 1 and 2: $((bootsz / 1024))K each"
> + blocks=$(( bootsz / (128 * 1024) ))
> + dd if="$bootimg1" of="$outimg" conv=sparse bs=128K count=$blocks \
> + status=none
> + dd if="$bootimg2" of="$outimg" conv=sparse bs=128K count=$blocks \
> + seek=$blocks status=none
> + pos=$((2 * bootsz))
> +fi
> +
> +if [ "$rpmbsz" -gt 0 ]; then
> + echo " RPMB partition: $((rpmbsz / 1024))K"
> + blocks=$(( rpmbsz / (128 * 1024) ))
> + dd if="$rpmbimg" of="$outimg" conv=sparse bs=128K count=$blocks \
> + seek=$(( pos / (128 * 1024) )) status=none
> + pos=$((pos + rpmbsz))
> +fi
> +
> +if [ "$usersz" -lt 1024 ]; then
> + echo " User data: $usersz bytes"
> +elif [ "$usersz" -lt $((1024 * 1024)) ]; then
> + echo " User data: $(( (usersz + 1023) / 1024 ))K ($usersz)"
> +elif [ "$usersz" -lt $((1024 * 1024 * 1024)) ]; then
> + echo " User data: $(( (usersz + 1048575) / 1048576))M ($usersz)"
> +else
> + echo " User data: $(( (usersz + 1073741823) / 1073741824))G ($usersz)"
> +fi
> +dd if="$userimg" of="$outimg" conv=sparse bs=128K seek=$(( pos / (128 * 1024) )) \
> + count=$(( (usersz + 128 * 1024 - 1) / (128 * 1024) )) status=none
> +pos=$((pos + usersz))
> +truncate "$outimg" -s $pos
> +
> +echo ""
> +echo "Instantiate via '-device emmc,boot-partition-size=$bootsz,rpmb-partition-size=$rpmbsz,drive=$outimg'"
That did not work for me. I had to provide a drive name, not the image path.
An also create PCIe and SDHCI devices. That is:
-device pcie-root-port,id=pcie-root,bus=pcie.0 \
-device sdhci-pci,bus=pcie-root \
-device emmc,boot-partition-size=$bootsz,rpmb-partition-size=$rpmbsz,drive=mmc0
-drive if=none,id=mmc0,file=$outimg,format=raw"
I applied the patches on top of QEMU 10.1.0 if that matters.
Regards,
--
Jerome
next prev parent reply other threads:[~2025-09-09 14:26 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-24 7:18 [PATCH 0/8] sd: Add RPMB emulation to eMMC model Jan Kiszka
2025-08-24 7:18 ` [PATCH 1/8] hw/sd/sdcard: Fix size check for backing block image Jan Kiszka
2025-08-25 9:39 ` Philippe Mathieu-Daudé
2025-08-24 7:18 ` [PATCH 2/8] hw/sd/sdcard: Add validation for boot-partition-size Jan Kiszka
2025-08-24 7:18 ` [PATCH 3/8] hw/sd/sdcard: Allow user-instantiated eMMC Jan Kiszka
2025-08-24 7:18 ` [PATCH 4/8] hw/sd/sdcard: Refactor sd_bootpart_offset Jan Kiszka
2025-08-25 9:41 ` Philippe Mathieu-Daudé
2025-08-24 7:18 ` [PATCH 5/8] hw/sd/sdcard: Add basic support for RPMB partition Jan Kiszka
2025-08-24 7:18 ` [PATCH 6/8] crypto/hmac: Allow to build hmac over multiple qcrypto_gnutls_hmac_bytes[v] calls Jan Kiszka
2025-08-25 9:43 ` Philippe Mathieu-Daudé
2025-08-24 7:18 ` [PATCH 7/8] hw/sd/sdcard: Handle RPMB MAC field Jan Kiszka
2025-08-25 9:47 ` Philippe Mathieu-Daudé
2025-08-25 16:12 ` Jan Kiszka
2025-08-25 16:30 ` Philippe Mathieu-Daudé
2025-08-26 10:18 ` Daniel P. Berrangé
2025-08-27 5:53 ` Jan Kiszka
2025-08-27 9:53 ` Daniel P. Berrangé
2025-09-09 14:39 ` Jerome Forissier
2025-08-24 7:18 ` [PATCH 8/8] scripts: Add helper script to generate eMMC block device images Jan Kiszka
2025-08-25 9:51 ` Philippe Mathieu-Daudé
2025-09-09 14:25 ` Jerome Forissier [this message]
2025-09-14 12:23 ` Jan Kiszka
2025-08-24 7:41 ` [PATCH 0/8] sd: Add RPMB emulation to eMMC model Jan Kiszka
2025-08-24 7:41 ` Jan Kiszka via OP-TEE
2025-08-26 10:57 ` Sumit Garg via OP-TEE
2025-08-27 5:55 ` Jan Kiszka
2025-08-27 5:55 ` Jan Kiszka via OP-TEE
2025-10-19 16:35 ` Jan Kiszka
2025-10-19 16:35 ` Jan Kiszka via OP-TEE
2025-09-03 14:35 ` Jerome Forissier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=891712cb-0dee-482f-888c-2649ae2d4ca9@linaro.org \
--to=jerome.forissier@linaro.org \
--cc=bmeng.cn@gmail.com \
--cc=ilias.apalodimas@linaro.org \
--cc=jan.kiszka@siemens.com \
--cc=philmd@linaro.org \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.