xref: /OK3568_Linux_fs/device/rockchip/common/scripts/mk-image.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1#!/bin/bash
2
3# Prefer using buildroot host tools for compatible.
4if [ -n "$RK_BUILDROOT_CFG" ]; then
5    HOST_DIR="$SDK_DIR/buildroot/output/$RK_BUILDROOT_CFG/host"
6    export PATH=$HOST_DIR/usr/sbin:$HOST_DIR/usr/bin:$HOST_DIR/sbin:$HOST_DIR/bin:$PATH
7    echo "Using host tools in $HOST_DIR"
8else
9    "$(dirname "$(realpath "$0")")/check-mkimage.sh"
10fi
11
12fatal()
13{
14    echo -e "FATAL: " $@
15    exit 1
16}
17
18usage()
19{
20    echo $@
21    fatal "Usage: $0 <src_dir> <target_image> <fs_type> <size(M|K)|auto(0)> [label]"
22}
23
24[ ! $# -lt 4 ] || usage "Not enough args${@+: $0 $@}"
25
26export SRC_DIR=$1
27export TARGET=$2
28FS_TYPE=$3
29SIZE=$4
30LABEL=$5
31
32case $SIZE in
33    auto)
34        SIZE_KB=0
35        ;;
36    *K)
37        SIZE_KB=$(( ${SIZE%K} ))
38        ;;
39    *)
40        SIZE_KB=$(( ${SIZE%M} * 1024 )) # default is MB
41        ;;
42esac
43
44echo $SIZE_KB | grep -vq [^0-9] || usage "Invalid size: $SIZE_KB"
45
46TEMP=$(mktemp -u)
47
48[ -d "$SRC_DIR" ] || usage "No such src dir: $SRC_DIR"
49
50copy_to_ntfs()
51{
52    DEPTH=1
53    while true;do
54        find $SRC_DIR -maxdepth $DEPTH -mindepth $DEPTH -type d|grep -q "" \
55            || break
56        find $SRC_DIR -maxdepth $DEPTH -mindepth $DEPTH -type d \
57            -exec sh -c 'ntfscp $TARGET "$1" "${1#$SRC_DIR}"' sh {} \; || \
58	    fatal "Detected non-buildroot ntfscp(doesn't support dir copy)"
59        DEPTH=$(($DEPTH + 1))
60    done
61
62    find $SRC_DIR -type f \
63        -exec sh -c 'ntfscp $TARGET "$1" "${1#$SRC_DIR}"' sh {} \; || \
64            fatal "Failed to do ntfscp!"
65}
66
67copy_to_image()
68{
69    ls $SRC_DIR/* &>/dev/null || return 0
70
71    echo "Copying $SRC_DIR into $TARGET (root permission required)"
72    mkdir -p $TEMP || return 1
73    sudo mount $TARGET $TEMP || return 1
74
75    cp -rp $SRC_DIR/* $TEMP
76    RET=$?
77
78    sudo umount $TEMP
79    rm -rf $TEMP
80
81    return $RET
82}
83
84check_host_tool()
85{
86    which $1|grep -wq buildroot
87}
88
89mkimage()
90{
91    echo "Making $TARGET from $SRC_DIR with size(${SIZE_KB}KB)"
92    rm -rf $TARGET
93    dd of=$TARGET bs=1K seek=$SIZE_KB count=0 &>/dev/null || \
94        fatal "Failed to dd image!"
95    case $FS_TYPE in
96        ext[234])
97            if mke2fs -h 2>&1 | grep -wq "\-d"; then
98                mke2fs -t $FS_TYPE $TARGET -d $SRC_DIR \
99                    || return 1
100            else
101                echo "Detected old mke2fs(doesn't support '-d' option)!"
102                mke2fs -t $FS_TYPE $TARGET || return 1
103                copy_to_image || return 1
104            fi
105            # Set max-mount-counts to 0, and disable the time-dependent checking.
106            tune2fs -c 0 -i 0 $TARGET ${LABEL:+-L $LABEL}
107            ;;
108        msdos|fat|vfat)
109            # Use fat32 by default
110            mkfs.vfat -F 32 $TARGET ${LABEL:+-n $LABEL} && \
111                MTOOLS_SKIP_CHECK=1 \
112                mcopy -bspmn -D s -i $TARGET $SRC_DIR/* ::/
113            ;;
114        ntfs)
115            # Enable compression
116            mkntfs -FCQ $TARGET ${LABEL:+-L $LABEL}
117            if check_host_tool ntfscp; then
118                copy_to_ntfs
119            else
120                copy_to_image
121            fi
122            ;;
123        ubi|ubifs)
124            mk_ubi_image
125            ;;
126    esac
127}
128
129mkimage_auto_sized()
130{
131    tar cf $TEMP $SRC_DIR &>/dev/null
132    SIZE_KB=$(du -k $TEMP|grep -o "^[0-9]*")
133    rm -rf $TEMP
134    echo "Making $TARGET from $SRC_DIR (auto sized)"
135
136    MAX_RETRY=10
137    RETRY=0
138
139    while true;do
140        EXTRA_SIZE=$(($SIZE_KB / 50))
141        SIZE_KB=$(($SIZE_KB + ($EXTRA_SIZE > 4096 ? $EXTRA_SIZE : 4096)))
142        mkimage && break
143
144        RETRY=$[RETRY+1]
145        [ $RETRY -gt $MAX_RETRY ] && fatal "Failed to make image!"
146        echo "Retring with increased size....($RETRY/$MAX_RETRY)"
147    done
148}
149
150mk_ubi_image()
151{
152    TARGET_DIR="${RK_OUTDIR:-$(dirname "$TARGET")}"
153    UBI_VOL_NAME=${LABEL:-ubi}
154
155    # default page size 2KB
156    UBI_PAGE_SIZE=${RK_UBI_PAGE_SIZE:-2048}
157    # default block size 128KB
158    UBI_BLOCK_SIZE=${RK_UBI_BLOCK_SIZE:-0x20000}
159
160    UBIFS_LEBSIZE=$(( $UBI_BLOCK_SIZE - 2 * $UBI_PAGE_SIZE ))
161    UBIFS_MINIOSIZE=$UBI_PAGE_SIZE
162
163    UBIFS_IMAGE="$TARGET_DIR/$UBI_VOL_NAME.ubifs"
164    UBINIZE_CFG="$TARGET_DIR/${UBI_VOL_NAME}-ubinize.cfg"
165
166    UBIFS_MAXLEBCNT=$(( $SIZE_KB * 1024 / $UBIFS_LEBSIZE ))
167
168    mkfs.ubifs -x lzo -e $UBIFS_LEBSIZE -m $UBIFS_MINIOSIZE \
169        -c $UBIFS_MAXLEBCNT -d $SRC_DIR -F -v -o $UBIFS_IMAGE || return 1
170
171    echo "[ubifs]" > $UBINIZE_CFG
172    echo "mode=ubi" >> $UBINIZE_CFG
173    echo "vol_id=0" >> $UBINIZE_CFG
174    echo "vol_type=dynamic" >> $UBINIZE_CFG
175    echo "vol_name=$UBI_VOL_NAME" >> $UBINIZE_CFG
176    echo "vol_size=${SIZE_KB}KiB" >> $UBINIZE_CFG
177    echo "vol_alignment=1" >> $UBINIZE_CFG
178    echo "vol_flags=autoresize" >> $UBINIZE_CFG
179    echo "image=$UBIFS_IMAGE" >> $UBINIZE_CFG
180    ubinize -o $TARGET -m $UBIFS_MINIOSIZE -p $UBI_BLOCK_SIZE \
181        -v $UBINIZE_CFG
182}
183
184rm -rf $TARGET
185case $FS_TYPE in
186    ext[234]|msdos|fat|vfat|ntfs|ubi|ubifs)
187        if [ $SIZE_KB -eq 0 ]; then
188            mkimage_auto_sized
189        else
190            mkimage && echo "Generated $TARGET"
191        fi
192        ;;
193    squashfs)
194        [ $SIZE_KB -eq 0 ] || fatal "$FS_TYPE: fixed size not supported."
195        mksquashfs $SRC_DIR $TARGET -noappend -comp lz4
196        ;;
197    jffs2)
198        [ $SIZE_KB -eq 0 ] || fatal "$FS_TYPE: fixed size not supported."
199        mkfs.jffs2 -r $SRC_DIR -o $TARGET 0x10000 --pad=0x400000 -s 0x1000 -n
200        ;;
201    *)
202        usage "File system: $FS_TYPE not supported."
203        ;;
204esac
205