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