7 # Binaires array for fusing
8 declare -a FUSING_BINARY_ARRAY
9 declare -i FUSING_BINARY_NUM=0
12 declare -i FUS_ENTRY_NUM=0
13 declare -i ab_option=0
15 # binary name | part number | bs | label | fs type
16 declare -a PART_TABLE=(
17 "u-boot-spl.bin.normal.out" 1 4M SPL raw
18 "u-boot.img" 2 4M u-boot raw
19 "u-boot.itb" 2 4M u-boot raw
20 "boot.img" 3 4M boot_a vfat
21 "rootfs.img" 5 4M rootfs_a ext4
22 "system-data.img" 6 4M system-data ext4
23 "user.img" 7 4M user ext4
24 "modules.img" 8 4M module_a ext4
25 "ramdisk.img" 9 4M ramdisk_a ext4
26 "ramdisk-recovery.img" 10 4M ramdisk-recovery_a ext4
27 "hal.img" 12 4M hal_a ext4
30 declare -r -i PART_TABLE_COL=5
31 declare -r -i PART_TABLE_ROW=${#PART_TABLE[*]}/${PART_TABLE_COL}
33 # partition table support
34 function get_index_use_name () {
35 local -r binary_name=$1
37 for ((idx=0;idx<$PART_TABLE_ROW;idx++)); do
38 if [ ${PART_TABLE[idx * ${PART_TABLE_COL} + 0]} == "$binary_name" ]; then
43 # return out of bound index
47 function print_message () {
58 function check_ddversion () {
60 # before coreutils dd 8.24, dd doesn't support "status=progress"
61 # and the option causes fusing failure. For backward compatibility,
62 # do not use the option for old dd
63 local version=(`dd --version | head -1 | grep -o '[0-9]\+'`)
64 local major=${version[0]}
65 local minor=${version[1]}
67 if [ $major -lt 8 ]; then
69 elif [ $major -eq 8 -a $minor -lt 24 ]; then
74 function fusing_image () {
75 local -r fusing_img=$1
77 # get binary info using basename
78 get_index_use_name $(basename "$fusing_img")
79 local -r -i part_idx=$?
81 if [ $part_idx -ne $PART_TABLE_ROW ];then
82 local -r num=${PART_TABLE[${part_idx} * ${PART_TABLE_COL} + 1]}
83 if [ "${num}" == "" ]; then
88 local -r device=/dev/`lsblk ${DEVICE} -o TYPE,KNAME | awk "/^${blktype}.*[a-z]${num}\$/ { print \\\$2 }"`
89 local -r bs=${PART_TABLE[${part_idx} * ${PART_TABLE_COL} + 2]}
91 echo "Not supported binary: $fusing_img"
95 local -r input_size=`du -b $fusing_img | awk '{print $1}'`
96 local -r input_size_mb=`expr $input_size / 1024 / 1024`
98 print_message 2 "[Fusing $1 ($input_size_mb MiB)]"
99 if [ "$blktype" == "part" ]; then
100 local MOUNT_PART=`mount | grep $device`
101 if [ "$MOUNT_PART" != "" ]; then
105 if [ $OLD_DD == 1 ]; then
106 dd if=$fusing_img | pv -s $input_size | dd of=$device bs=$bs
108 dd if=$fusing_img of=$device bs=$bs status=progress oflag=direct
112 function fuse_image_tarball () {
114 local -r temp_dir="tar_tmp"
117 tar xvf $filepath -C $temp_dir
130 function fuse_image () {
132 if [ "$FUSING_BINARY_NUM" == 0 ]; then
136 for ((fuse_idx = 0 ; fuse_idx < $FUSING_BINARY_NUM ; fuse_idx++))
138 local filename=${FUSING_BINARY_ARRAY[fuse_idx]}
142 fuse_image_tarball $filename
145 fusing_image $filename
153 function mkpart_3 () {
154 # NOTE: if your sfdisk version is less than 2.26.0, then you should use following sfdisk command:
155 # sfdisk --in-order --Linux --unit M $DISK <<-__EOF__
157 # NOTE: sfdisk 2.26 doesn't support units other than sectors and marks --unit option as deprecated.
158 # The input data needs to contain multipliers (MiB) instead.
159 local version=(`sfdisk -v | grep -o '[0-9]\+'`)
160 local major=${version[0]}
161 local minor=${version[1]}
163 local support_delete=0
165 if [ $major -gt 2 ]; then
167 if [ $major -eq 2 -a $minor -ge 28 ]; then
171 if [ $major -eq 2 -a $minor -ge 26 ]; then
176 if [ $sfdisk_new == 0 ]; then
177 echo "$(tput setaf 3)$(tput bold)NOTICE: Your sfdisk ${version[0]}.${version[1]} version is too old. Update Latest sfdisk!"
182 local -r DISK=$DEVICE
183 local -r SIZE=`sfdisk -s $DISK`
184 local -r SIZE_MB=$((SIZE >> 10))
189 local -r ROOTFS_SZ=3072
190 local -r DATA_SZ=1344
191 local -r MODULE_SZ=32
192 local -r RAMDISK_SZ=32
193 local -r RAMDISK_RECOVERY_SZ=32
197 local -r DATA_SIZE=1344
198 local -r RESERVED1_SZ=64
199 local -r RESERVED2_SZ=125
200 local -r EXTEND_SZ=36
202 let "USER_SZ = $SIZE_MB - $SPL_SZ - $UBOOT_SZ - $BOOT_SZ - $ROOTFS_SZ - $DATA_SZ - $MODULE_SZ - $RAMDISK_SZ - $RAMDISK_RECOVERY_SZ - $INFORM_SZ - $EXTEND_SZ - $HAL_SZ - $RESERVED1_SZ - $RESERVED2_SZ - $PARAM_SZ"
206 local -r BOOT_A=${PART_TABLE[0 * ${PART_TABLE_COL} + 3]}
207 local -r ROOTFS_A=${PART_TABLE[1 * ${PART_TABLE_COL} + 3]}
208 local -r SYSTEMDATA=${PART_TABLE[2 * ${PART_TABLE_COL} + 3]}
209 local -r USER=${PART_TABLE[3 * ${PART_TABLE_COL} + 3]}
210 local -r MODULE_A=${PART_TABLE[4 * ${PART_TABLE_COL} + 3]}
211 local -r RAMDISK_A=${PART_TABLE[5 * ${PART_TABLE_COL} + 3]}
212 local -r RAMDISK_RECOVERY_A=${PART_TABLE[6 * ${PART_TABLE_COL} + 3]}
213 local -r INFORM=inform
214 local -r HAL_A=${PART_TABLE[7 * ${PART_TABLE_COL} + 3]}
215 local -r RESERVED0=reserved0
216 local -r RESERVED1=reserved1
217 local -r RESERVED2=reserved2
219 if [[ $USER_SZ -le 100 ]]
221 echo "We recommend to use more than 8GB disk"
225 echo "================================================"
226 echo "Label dev size"
227 echo "================================================"
228 echo $SPL" " $DISK"1 " $SPL_SZ "MB"
229 echo $UBOOT" " $DISK"2 " $UBOOT_SZ "MB"
230 echo $BOOT_A" " $DISK"3 " $BOOT_SZ "MB"
231 echo "[Extend]"" " $DISK"4"
232 echo " "$SYSTEMDATA" " $DISK"5 " $DATA_SZ "MB"
233 echo " "$ROOTFS_A" " $DISK"6 " $ROOTFS_SZ "MB"
234 echo " "$USER" " $DISK"7 " $USER_SZ "MB"
235 echo " "$MODULE_A" " $DISK"8 " $MODULE_SZ "MB"
236 echo " "$RAMDISK_A" " $DISK"9 " $RAMDISK_SZ "MB"
237 echo " "$RAMDISK_RECOVERY_A" " $DISK"10 " $RAMDISK_RECOVERY_SZ "MB"
238 echo " "$INFORM" " $DISK"11 " $INFORM_SZ "MB"
239 echo " "$HAL_A" " $DISK"12 " $HAL_SZ "MB"
240 echo " "$RESERVED0" " $DISK"13 " $PARAM_SZ "MB"
241 echo " "$RESERVED1" " $DISK"14 " $RESERVED1_SZ "MB"
242 echo " "$RESERVED2" " $DISK"15 " $RESERVED2_SZ "MB"
244 local MOUNT_LIST=`mount | grep $DISK | awk '{print $1}'`
245 for mnt in $MOUNT_LIST
250 echo "Remove partition table..."
251 dd if=/dev/zero of=$DISK bs=512 count=32 conv=notrunc
253 if [ $support_delete == 1 ]; then
254 sfdisk --delete $DISK
258 for ((idx=0; idx < $PART_TABLE_ROW; idx++)); do
259 NR=${PART_TABLE[idx * ${PART_TABLE_COL} + 1]}
260 eval "PART_LABEL_NR_${NR}=${PART_TABLE[idx * ${PART_TABLE_COL} + 3]}"
263 sfdisk $DISK <<-__EOF__
265 start=4MiB, type= 2E54B353-1271-4842-806F-E436D6AF6985, size=${SPL_SZ}MiB, name=spl
266 size=${UBOOT_SZ}MiB, type=5B193300-FC78-40CD-8002-E86C45580B47, name=uboot
267 size=${BOOT_SZ}MiB, type= C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name=${PART_LABEL_NR_3}
268 size=${EXTEND_SZ}MiB, name=none
269 size=${ROOTFS_SZ}MiB, name=${PART_LABEL_NR_5}
270 size=${DATA_SZ}MiB, name=${PART_LABEL_NR_6}
271 size=${USER_SZ}MiB, name=${PART_LABEL_NR_7}
272 size=${MODULE_SZ}MiB, name=${PART_LABEL_NR_8}
273 size=${RAMDISK_SZ}MiB, name=${PART_LABEL_NR_9}
274 size=${RAMDISK_RECOVERY_SZ}MiB, name=${PART_LABEL_NR_10}
275 size=${INFORM_SZ}MiB, name=inform
276 size=${HAL_SZ}MiB, name=${PART_LABEL_NR_12}
277 size=${PARAM_SZ}MiB, name=reserved0
278 size=${RESERVED1_SZ}MiB, name=reserved1
279 size=${RESERVED2_SZ}MiB, name=reserved2
283 for ((idx=0;idx<$PART_TABLE_ROW;idx++)); do
284 local PART=/dev/`lsblk ${DISK} -o TYPE,KNAME | awk "/^part.*[a-z]${PART_TABLE[$idx * ${PART_TABLE_COL} + 1]}\$/ { print \\\$2 }"`
285 if [ "${PART_TABLE[$idx * ${PART_TABLE_COL} + 4]}" == "vfat" ]; then
286 mkfs.vfat -F 16 ${PART} -n ${PART_TABLE[$idx * ${PART_TABLE_COL} + 3]}
287 if [ $? -eq 1 ]; then
288 echo "Failed to format as FAT filesystem"
291 elif [ "${PART_TABLE[$idx * ${PART_TABLE_COL} + 4]}" == "ext4" ]; then
292 mkfs.ext4 -q ${PART} -L ${PART_TABLE[$idx * ${PART_TABLE_COL} + 3]} -F
294 echo "Skip to format for unknown filesystem type ${PART_TABLE[$idx * ${PART_TABLE_COL} + 4]} for part$idx, ${PART_TABLE[$idx * ${PART_TABLE_COL} + 3]}"
299 function show_usage () {
301 echo " sudo ./sd_fusing*.sh -d <device> [-b <path> <path> ..] [--format]"
302 echo " -d : device ndoe "
306 function check_partition_format () {
307 if [ "$FORMAT" != "2" ]; then
308 echo "-----------------------"
309 echo "Skip $DEVICE format"
310 echo "-----------------------"
314 echo "-------------------------------"
315 echo "Start $DEVICE format"
318 echo "End $DEVICE format"
319 echo "-------------------------------"
323 function check_args () {
324 if [ "$DEVICE" == "" ]; then
325 echo "$(tput setaf 1)$(tput bold)- Device node is empty!"
331 if [ "$DEVICE" != "" ]; then
332 echo "Device: $DEVICE"
335 if [ "$FUSING_BINARY_NUM" != 0 ]; then
336 echo "Fusing binary: "
337 for ((bid = 0 ; bid < $FUSING_BINARY_NUM ; bid++))
339 echo " ${FUSING_BINARY_ARRAY[bid]}"
344 if [ "$FORMAT" == "1" ]; then
346 echo "$(tput setaf 3)$(tput bold)$DEVICE will be formatted, Is it OK? [y/<n>]"
349 if [ "$input" == "y" ] || [ "$input" == "Y" ]; then
357 function check_device () {
358 if [ ! -b "$DEVICE" ]; then
359 echo "No such device: $DEVICE"
363 DEVICE=/dev/`lsblk $DEVICE -o TYPE,KNAME | awk '/^(disk|loop)/ { print $2 }'`
365 local REMOVABLE=`lsblk $DEVICE -nd -o RM | grep 1 | wc -l`
366 if [ "$REMOVABLE" == "0" ]; then
368 echo "$(tput setaf 3)$(tput bold)$DEVICE is not a removable disk, Is it OK? [y/<n>]"
371 if [ "$input" != "y" ] && [ "$input" != "Y" ]; then
376 if [ ! -w "$DEVICE" ]; then
377 echo "Write not permitted: $DEVICE"
382 function print_logo () {
384 echo "For VisionFive2 , version 1.0.1"
390 function add_fusing_binary() {
391 local declare binary_name=$1
393 if [ "$binary_name" != "" ]; then
394 if [ -f "$binary_name" ]; then
395 FUSING_BINARY_ARRAY[$FUSING_BINARY_NUM]=$binary_name
397 FUSING_BINARY_NUM=$((FUSING_BINARY_NUM + 1))
399 echo "No such file: $binary_name"
405 declare -i binary_option=0
407 while test $# -ne 0; do
427 if [ $binary_option == 1 ];then
428 add_fusing_binary $option
430 echo "Unkown command: $option"
439 check_partition_format