On 04.11.25 07:30, Jan Kiszka wrote:
> On 03.11.25 14:12, Philippe Mathieu-Daudé wrote:
>> Hi Jan,
>>
>> On 17/10/25 14:03, Jan Kiszka wrote:
>>> From: Jan Kiszka <[email protected]>
>>>
>>> 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 <[email protected]>
>>> ---
>>>   scripts/mkemmc.sh | 218 ++++++++++++++++++++++++++++++++++++++++++++++
>>>   1 file changed, 218 insertions(+)
>>>   create mode 100755 scripts/mkemmc.sh
>>>
>>> diff --git a/scripts/mkemmc.sh b/scripts/mkemmc.sh
>>> new file mode 100755
>>> index 0000000000..1a2b7a6193
>>> --- /dev/null
>>> +++ b/scripts/mkemmc.sh
>>> @@ -0,0 +1,218 @@
>>> +#!/bin/sh -e
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +#
>>> +# Create eMMC block device image from boot, RPMB and user data images
>>> +#
>>> +# Copyright (c) Siemens, 2025
>>> +#
>>> +# Authors:
>>> +#  Jan Kiszka <[email protected]>
>>> +#
>>> +# 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 up to 2G and multiples of 512
>>> byte from there on."
>>> +    echo "If no SIZE is specified, the size of USER_ING will 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
>>> BOOT1_IMG will be"
>>> +    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() {
>>> +    name=$1
>>> +    image_file=$2
>>> +    alignment=$3
>>> +    image_arg=$4
>>> +    if [ "${image_arg#*:}" = "$image_arg"  ]; then
>>> +        if ! size=$(stat -L -c %s "$image_file" 2>/dev/null); then
>>> +            echo "Missing $name image '$image_file'." >&2
>>> +            exit 1
>>> +        fi
>>> +        if [ "$alignment" = 128 ]; then
>>> +            size=$(( (size + 128 * 1024 - 1) & ~(128 * 1024 - 1) ))
>>> +        elif [ $size -gt $((2 * 1024 * 1024 * 1024)) ]; then
>>> +            size=$(( (size + 511) & ~511 ))
>>> +        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="${image_arg#*:}"
>>> +        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
>>
>> I don't get this check, should one be "$value"?
>>
> 
> Likely deserves a comment, I had to refresh my own memory as well:
> This checks if $size is a valid integer value. If we just run the
> multiplication below, we won't be able to react properly.
> 
>>> +            size=$((size * multiplier))
>>> +        else
>>> +            echo "Invalid value '$value' specified for $image_file
>>> image size." >&2
>>> +            exit 1
>>> +        fi
>>> +        if [ "$alignment" = 128 ]; then
>>> +            if [ $(( size & (128 * 1024 - 1) )) -ne 0 ]; then
>>> +                echo "The $name image size must be multiples of
>>> 128K." >&2
>>> +                exit 1
>>> +            fi
>>> +        elif [ $size -gt $((2 * 1024 * 1024 * 1024)) ]; then
>>> +            if [ $(( size & 511)) -ne 0 ]; then
>>> +                echo "The $name image size must be multiples of 512
>>> (if >2G)." >&2
>>> +                exit 1
>>> +            fi
>>> +        elif [ $(( size & (size - 1) )) -gt 0 ]; then
>>> +            echo "The $name image size must be power of 2 (up to
>>> 2G)." >&2
>>> +            exit 1
>>> +        fi
>>> +    fi
>>> +    echo $size
>>> +}
>>> +
>>> +check_truncation() {
>>> +    image_file=$1
>>> +    output_size=$2
>>> +    if [ "$image_file" = "/dev/zero" ]; then
>>> +        return
>>> +    fi
>>> +    if ! actual_size=$(stat -L -c %s "$image_file" 2>/dev/null); then
>>> +        echo "Missing image '$image_file'." >&2
>>> +        exit 1
>>> +    fi
>>> +    if [ "$actual_size" -gt "$output_size" ]; then
>>> +        echo "Warning: image '$image_file' will be truncated on output."
>>> +    fi
>>> +}
>>> +
>>> +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" U "$1")
>>> +            elif [ -z "$outimg" ]; then
>>> +                outimg=$1
>>> +            else
>>> +                usage 1
>>> +            fi
>>> +            shift
>>> +            ;;
>>> +    esac
>>> +done
>>> +
>>> +[ -n "$outimg" ] || usage 1
>>> +
>>> +if [ "$bootsz" -gt $((32640 * 1024)) ]; then
>>
>> Running on macOS:
>>
>> scripts/mkemmc.sh: line 165: [: : integer expression expected
>> scripts/mkemmc.sh: line 169: [: : integer expression expected
>> scripts/mkemmc.sh: line 179: [: : integer expression expected
>> scripts/mkemmc.sh: line 191: [: : integer expression expected
>> scripts/mkemmc.sh: line 200: [: : integer expression expected
>> scripts/mkemmc.sh: line 202: [: : integer expression expected
>> scripts/mkemmc.sh: line 204: [: : integer expression expected
>>
>> $ sh --version
>> GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24)
>>
>> When using dash:
>>
>> scripts/mkemmc.sh: 165: [: Illegal number:
>> scripts/mkemmc.sh: 169: [: Illegal number:
>> scripts/mkemmc.sh: 179: [: Illegal number:
>> scripts/mkemmc.sh: 191: [: Illegal number:
>> scripts/mkemmc.sh: 200: [: Illegal number:
>> scripts/mkemmc.sh: 202: [: Illegal number:
>> scripts/mkemmc.sh: 204: [: Illegal number:
>>
>> Should we replace s/[/[[/?
> 
> No, that would be invalid outside of bash. There must be a logical error.
> 
> How did you invoke the script? What was the value of bootsz then?
> 

I tried with dash from debian trixie, and there is no issue like yours
visible.

What problem could macOS have here? Will need your help, don't have
anything mac-like around right now.

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center

Reply via email to