scripts: tizen: sd_fusing_rpi4: support gpt label
[platform/kernel/u-boot.git] / scripts / tizen / sd_fusing_rpi4.sh
1 #!/bin/bash
2
3 declare FORMAT=""
4 declare DEVICE=""
5 declare -i OLD_DD=0
6
7 # Binaires array for fusing
8 declare -a FUSING_BINARY_ARRAY
9 declare -i FUSING_BINARY_NUM=0
10
11 declare CONV_ASCII=""
12 declare -i FUS_ENTRY_NUM=0
13
14 # binary name | part number | bs | label | fs type
15 declare -a PART_TABLE=(
16         "boot.img"                      1       4M      boot                    vfat
17         "rootfs.img"                    2       4M      rootfs_a                ext4
18         "system-data.img"               3       4M      system-data             ext4
19         "user.img"                      5       4M      user                    ext4
20         "modules.img"                   6       4M      modules_a               ext4
21         "ramdisk.img"                   7       4M      ramdisk_a               ext4
22         "ramdisk-recovery.img"          8       4M      recovery_a              ext4
23         "hal.img"                       10      4M      hal                     ext4
24         "rootfs.img"                    11      4M      rootfs_b                ext4
25         "modules.img"                   12      4M      modules_b               ext4
26         "ramdisk.img"                   13      4M      ramdisk_b               ext4
27         "ramdisk-recovery.img"          14      4M      recovery_b              ext4
28         )
29 declare -a PART_TABLE_B=(
30         "rootfs.img"                    11      4M      rootfs_b                ext4
31         "modules.img"                   12      4M      modules_b               ext4
32         "ramdisk.img"                   13      4M      ramdisk_b               ext4
33         "ramdisk-recovery.img"          14      4M      recovery_b              ext4
34         )
35
36 declare -r -i PART_TABLE_COL=5
37 declare -r -i PART_TABLE_ROW=${#PART_TABLE[*]}/${PART_TABLE_COL}
38 declare -r -i PART_TABLE_ROW_B=${#PART_TABLE_B[*]}/${PART_TABLE_COL}
39
40 # partition table support
41 function get_index_use_name () {
42         local -r binary_name=$1
43
44         for ((idx=0;idx<$PART_TABLE_ROW;idx++)); do
45                 if [ ${PART_TABLE[idx * ${PART_TABLE_COL} + 0]} == "$binary_name" ]; then
46                         return $idx
47                 fi
48         done
49
50         # return out of bound index
51         return $idx
52 }
53
54 # partition table support
55 function get_index_use_name_to_b () {
56         local -r binary_name=$1
57
58         for ((idx=0;idx<$PART_TABLE_ROW_B;idx++)); do
59                 if [ ${PART_TABLE_B[idx * ${PART_TABLE_COL} + 0]} == "$binary_name" ]; then
60                         return $idx
61                 fi
62         done
63
64         # return out of bound index
65         return $idx
66 }
67
68 function print_message () {
69         local color=$1
70         local message=$2
71
72         tput setaf $color
73         tput bold
74         echo ""
75         echo $message
76         tput sgr 0
77 }
78
79 function check_ddversion () {
80         # NOTE
81         # before coreutils dd 8.24, dd doesn't support "status=progress"
82         # and the option causes fusing failure. For backward compatibility,
83         # do not use the option for old dd
84         local version=(`dd --version | head -1 | grep -o '[0-9]\+'`)
85         local major=${version[0]}
86         local minor=${version[1]}
87
88         if [ $major -lt 8 ];  then
89                 OLD_DD=1
90         elif [ $major -eq 8 -a $minor -lt 24 ];  then
91                 OLD_DD=1
92         fi
93 }
94
95 function fusing_image () {
96         local -r fusing_img=$1
97
98         # get binary info using basename
99         get_index_use_name $(basename "$fusing_img")
100         local -r -i part_idx=$?
101
102         if [ $part_idx -ne $PART_TABLE_ROW ];then
103                 local -r num=${PART_TABLE[${part_idx} * ${PART_TABLE_COL} + 1]}
104                 if [ "${num}" == "" ]; then
105                         local -r blktype=disk
106                 else
107                         local -r blktype=part
108                 fi
109                 local -r device=/dev/`lsblk ${DEVICE} -o TYPE,KNAME | awk "/^${blktype}.*[a-z]${num}\$/ { print \\\$2 }"`
110                 local -r bs=${PART_TABLE[${part_idx} * ${PART_TABLE_COL} + 2]}
111         else
112                 echo "Not supported binary: $fusing_img"
113                 return
114         fi
115
116         local -r input_size=`du -b $fusing_img | awk '{print $1}'`
117         local -r input_size_mb=`expr $input_size / 1024 / 1024`
118
119         print_message 2 "[Fusing $1 ($input_size_mb MiB)]"
120         if [ "$blktype" == "part" ]; then
121                 local MOUNT_PART=`mount | grep $device`
122                 if [ "$MOUNT_PART" != "" ]; then
123                         umount $device
124                 fi
125         fi
126         if [ $OLD_DD == 1 ]; then
127                 dd if=$fusing_img | pv -s $input_size | dd of=$device bs=$bs
128         else
129                 dd if=$fusing_img of=$device bs=$bs status=progress oflag=direct
130         fi
131
132         local -r fstype=`blkid -o value -s TYPE $device`
133         if [[ "$fstype" =~ "ext" ]]; then
134                 resize2fs -f $device
135         fi
136 }
137
138 function fusing_image_to_b () {
139         local -r fusing_img=$1
140
141         # get binary info using basename
142         get_index_use_name_to_b $(basename "$fusing_img")
143
144         local -r -i part_idx=$?
145
146         if [ $part_idx -ne $PART_TABLE_ROW_B ];then
147                 local -r num=${PART_TABLE_B[${part_idx} * ${PART_TABLE_COL} + 1]}
148                 if [ "${num}" == "" ]; then
149                         local -r blktype=disk
150                 else
151                         local -r blktype=part
152                 fi
153                 local -r device=/dev/`lsblk ${DEVICE} -o TYPE,KNAME | awk "/^${blktype}.*[a-z]${num}\$/ { print \\\$2 }"`
154                 local -r bs=${PART_TABLE_B[${part_idx} * ${PART_TABLE_COL} + 2]}
155         else
156                 echo "Not supported binary: $fusing_img"
157                 return
158         fi
159
160         local -r input_size=`du -b $fusing_img | awk '{print $1}'`
161         local -r input_size_mb=`expr $input_size / 1024 / 1024`
162
163         print_message 2 "[Fusing $1 ($input_size_mb MiB)]"
164         if [ "$blktype" == "part" ]; then
165                 local MOUNT_PART=`mount | grep $device`
166                 if [ "$MOUNT_PART" != "" ]; then
167                         umount $device
168                 fi
169         fi
170         if [ $OLD_DD == 1 ]; then
171                 dd if=$fusing_img | pv -s $input_size | dd of=$device bs=$bs
172         else
173                 dd if=$fusing_img of=$device bs=$bs status=progress oflag=direct
174         fi
175
176         local -r fstype=`blkid -o value -s TYPE $device`
177         if [[ "$fstype" =~ "ext" ]]; then
178                 resize2fs -f $device
179         fi
180 }
181
182 function fuse_image_tarball () {
183         local -r filepath=$1
184         local -r temp_dir="tar_tmp"
185
186         mkdir -p $temp_dir
187         tar xvf $filepath -C $temp_dir
188         cd $temp_dir
189
190         for file in *
191         do
192                 fusing_image $file
193                 fusing_image_to_b $file
194         done
195
196         cd ..
197         rm -rf $temp_dir
198         eval sync
199 }
200
201 function fuse_image () {
202
203         if [ "$FUSING_BINARY_NUM" == 0 ]; then
204                 return
205         fi
206
207         for ((fuse_idx = 0 ; fuse_idx < $FUSING_BINARY_NUM ; fuse_idx++))
208         do
209                 local filename=${FUSING_BINARY_ARRAY[fuse_idx]}
210
211                 case "$filename" in
212                     *.tar | *.tar.gz)
213                         fuse_image_tarball $filename
214                         ;;
215                     *)
216                         fusing_image $filename
217                         fusing_image_to_b $filename
218                         ;;
219                 esac
220         done
221         echo ""
222 }
223
224 # partition format
225 function mkpart_3 () {
226         # NOTE: if your sfdisk version is less than 2.26.0, then you should use following sfdisk command:
227         # sfdisk --in-order --Linux --unit M $DISK <<-__EOF__
228
229         # NOTE: sfdisk 2.26 doesn't support units other than sectors and marks --unit option as deprecated.
230         # The input data needs to contain multipliers (MiB) instead.
231         local version=(`sfdisk -v | grep -o '[0-9]\+'`)
232         local major=${version[0]}
233         local minor=${version[1]}
234         local sfdisk_new=0
235         local support_delete=0
236
237         if [ $major -gt 2 ];  then
238                 sfdisk_new=1
239                 if [ $major -eq 2 -a $minor -ge 28 ]; then
240                         support_delete=1
241                 fi
242         else
243                 if [ $major -eq 2 -a $minor -ge 26 ];  then
244                         sfdisk_new=1
245                 fi
246         fi
247
248         if [ $sfdisk_new == 0 ]; then
249                 echo "$(tput setaf 3)$(tput bold)NOTICE: Your sfidk ${version[0]}.${version[1]}  version is too old. It can do unstable behavior!"
250                 tput sgr 0
251                 echo ""
252
253         fi
254
255         local -r DISK=$DEVICE
256         local -r SIZE=`sfdisk -s $DISK`
257         local -r SIZE_MB=$((SIZE >> 10))
258
259         local -r BOOT_SZ=64
260         local -r ROOTFS_SZ=3072
261         local -r DATA_SZ=1344
262         local -r MODULE_SZ=32
263         local -r RAMDISK_SZ=32
264         local -r RAMDISK_RECOVERY_SZ=32
265         local -r INFORM_SZ=8
266         local -r HAL_SZ=256
267         local -r RESERVED2_SZ=125
268         local -r EXTEND_SZ=36
269
270         let "USER_SZ = $SIZE_MB - $BOOT_SZ - $ROOTFS_SZ * 2 - $DATA_SZ - $MODULE_SZ * 2 - $RAMDISK_SZ * 2 - $RAMDISK_RECOVERY_SZ * 2 - $INFORM_SZ - $EXTEND_SZ - $HAL_SZ - $RESERVED2_SZ"
271
272         local -r BOOT=${PART_TABLE[0 * ${PART_TABLE_COL} + 3]}
273         local -r ROOTFS_A=${PART_TABLE[1 * ${PART_TABLE_COL} + 3]}
274         local -r SYSTEMDATA=${PART_TABLE[2 * ${PART_TABLE_COL} + 3]}
275         local -r USER=${PART_TABLE[3 * ${PART_TABLE_COL} + 3]}
276         local -r MODULE_A=${PART_TABLE[4 * ${PART_TABLE_COL} + 3]}
277         local -r RAMDISK_A=${PART_TABLE[5 * ${PART_TABLE_COL} + 3]}
278         local -r RAMDISK_RECOVERY_A=${PART_TABLE[6 * ${PART_TABLE_COL} + 3]}
279         local -r INFORM=inform
280         local -r HAL=${PART_TABLE[7 * ${PART_TABLE_COL} + 3]}
281         local -r ROOTFS_B=${PART_TABLE[8 * ${PART_TABLE_COL} + 3]}
282         local -r MODULE_B=${PART_TABLE[9 * ${PART_TABLE_COL} + 3]}
283         local -r RAMDISK_B=${PART_TABLE[10 * ${PART_TABLE_COL} + 3]}
284         local -r RAMDISK_RECOVERY_B=${PART_TABLE[10 * ${PART_TABLE_COL} + 3]}
285         local -r RESERVED2=reserved2
286
287         if [[ $USER_SZ -le 100 ]]
288         then
289                 echo "We recommend to use more than 4GB disk"
290                 exit 0
291         fi
292
293         echo "================================================"
294         echo "Label                     dev             size"
295         echo "================================================"
296         echo $BOOT"                     " $DISK"1       " $BOOT_SZ "MB"
297         echo $ROOTFS_A"                 " $DISK"2       " $ROOTFS_SZ "MB"
298         echo $SYSTEMDATA"               " $DISK"3       " $DATA_SZ "MB"
299         echo "[Extend]""                " $DISK"4"
300         echo " "$USER"                  " $DISK"5       " $USER_SZ "MB"
301         echo " "$MODULE_A"              " $DISK"6       " $MODULE_SZ "MB"
302         echo " "$RAMDISK_A"             " $DISK"7       " $RAMDISK_SZ "MB"
303         echo " "$RAMDISK_RECOVERY_A"    " $DISK"8       " $RAMDISK_RECOVERY_SZ "MB"
304         echo " "$INFORM"                " $DISK"9       " $INFORM_SZ "MB"
305         echo " "$HAL"                   " $DISK"10      " $HAL_SZ "MB"
306         echo " "$ROOTFS_B"              " $DISK"11      " $ROOTFS_SZ "MB"
307         echo " "$MODULE_B"              " $DISK"12      " $MODULE_SZ "MB"
308         echo " "$RAMDISK_B"             " $DISK"13      " $RAMDISK_SZ "MB"
309         echo " "$RAMDISK_RECOVERY_B"    " $DISK"14      " $RAMDISK_RECOVERY_SZ "MB"
310         echo " "$RESERVED2"             " $DISK"15      " $RESERVED2_SZ "MB"
311
312         local MOUNT_LIST=`mount | grep $DISK | awk '{print $1}'`
313         for mnt in $MOUNT_LIST
314         do
315                 umount $mnt
316         done
317
318         echo "Remove partition table..."
319         dd if=/dev/zero of=$DISK bs=512 count=32 conv=notrunc
320
321         if [ $sfdisk_new == 1 ]; then
322                 if [ $support_delete == 1 ]; then
323                         sfdisk --delete $DISK
324                 fi
325
326                 SCRIPT=""
327                 for ((idx=0; idx < $PART_TABLE_ROW; idx++)); do
328                         NR=${PART_TABLE[idx * ${PART_TABLE_COL} + 1]}
329                         eval "PART_LABEL_NR_${NR}=${PART_TABLE[idx * ${PART_TABLE_COL} + 3]}"
330                 done
331
332                 sfdisk $DISK <<-__EOF__
333                 label: gpt
334                 ${DEVICE}1 : start=4MiB, size=${BOOT_SZ}MiB, type= C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name=${PART_LABEL_NR_1}
335                 ${DEVICE}2 : size=${ROOTFS_SZ}MiB, name=${PART_LABEL_NR_2}
336                 ${DEVICE}3 : size=${DATA_SZ}MiB, name=${PART_LABEL_NR_3}
337                 ${DEVICE}4 : size=${EXTEND_SZ}MiB, name=none
338                 ${DEVICE}5 : size=${USER_SZ}MiB, name=${PART_LABEL_NR_5}
339                 ${DEVICE}6 : size=${MODULE_SZ}MiB, name=${PART_LABEL_NR_6}
340                 ${DEVICE}7 : size=${RAMDISK_SZ}MiB, name=${PART_LABEL_NR_7}
341                 ${DEVICE}8 : size=${RAMDISK_RECOVERY_SZ}MiB, name=${PART_LABEL_NR_8}
342                 ${DEVICE}9 : size=${INFORM_SZ}MiB, name=inform
343                 ${DEVICE}10: size=${HAL_SZ}MiB, name=${PART_LABEL_NR_10}
344                 ${DEVICE}11: size=${ROOTFS_SZ}MiB, name=${PART_LABEL_NR_11}
345                 ${DEVICE}12: size=${MODULE_SZ}MiB, name=${PART_LABEL_NR_12}
346                 ${DEVICE}13: size=${RAMDISK_SZ}MiB, name=${PART_LABEL_NR_13}
347                 ${DEVICE}14: size=${RAMDISK_RECOVERY_SZ}MiB, name=${PART_LABEL_NR_14}
348                 ${DEVICE}15: size=${RESERVED2_SZ}MiB, name=reserved2
349                 __EOF__
350         else
351                 # calculate start positions for alignment for extended partitions
352                 let "USER_START = 4 + $BOOT_SZ + $ROOTFS_SZ + $DATA_SZ + 1"
353                 let "MODULE_A_START = $USER_START + $USER_SZ + 1"
354                 let "RAMDISK_A_START = $MODULE_A_START + $MODULE_SZ + 1"
355                 let "RAMDISK_RECOVERY_A_START = $RAMDISK_A_START + $RAMDISK_SZ + 1"
356                 let "INFORM_START = $RAMDISK_RECOVERY_A_START + $RAMDISK_RECOVERY_SZ + 1"
357                 let "HAL_START = $INFORM_START + $INFORM_SZ + 1"
358                 let "ROOTFS_B_START = $HAL_START + $HAL_SZ + 1"
359                 let "MODULE_B_START = $ROOTFS_B_START + $ROOTFS_SZ + 1"
360                 let "RAMDISK_B_START = $MODULE_B_START + $MODULE_SZ + 1"
361                 let "RAMDISK_RECOVERY_B_START = $RAMDISK_B_START + $RAMDISK_SZ + 1"
362                 let "RESERVED2_START = $RAMDISK_RECOVERY_B_START + $RAMDISK_RECOVERY_SZ + 1"
363
364                 sfdisk --in-order --Linux --unit M $DISK <<-__EOF__
365                 4,$BOOT_SZ,0xE,*
366                 ,$ROOTFS_SZ,,-
367                 ,$DATA_SZ,,-
368                 ,,E,-
369                 $USER_START,$USER_SZ,,-
370                 $MODULE_A_START,$MODULE_SZ,,-
371                 $RAMDISK_A_START,$RAMDISK_SZ,,-
372                 $RAMDISK_RECOVERY_A_START,$RAMDISK_RECOVERY_SZ,,-
373                 $INFORM_START,$INFORM_SZ,,-
374                 $HAL_START,$HAL_SZ,,-
375                 $ROOTFS_B_START,$ROOTFS_SZ,,-
376                 $MODULE_B_START,$MODULE_SZ,,-
377                 $RAMDISK_B_START,$RAMDISK_SZ,,-
378                 $RAMDISK_RECOVERY_B_START,$RAMDISK_RECOVERY_SZ,,-
379                 $RESERVED2_START,$RESERVED2_SZ,,-
380                 __EOF__
381         fi
382
383         for ((idx=0;idx<$PART_TABLE_ROW;idx++)); do
384                 local PART=/dev/`lsblk ${DISK} -o TYPE,KNAME | awk "/^part.*[a-z]${PART_TABLE[$idx * ${PART_TABLE_COL} + 1]}\$/ { print \\\$2 }"`
385                 if [ "${PART_TABLE[$idx * ${PART_TABLE_COL} + 4]}" == "vfat" ]; then
386                         mkfs.vfat -F 16 ${PART} -n ${PART_TABLE[$idx * ${PART_TABLE_COL} + 3]}
387                         if [ $? -eq 1 ]; then
388                                 echo "Failed to format as FAT filesystem"
389                                 exit -1
390                         fi
391                 elif [ "${PART_TABLE[$idx * ${PART_TABLE_COL} + 4]}" == "ext4" ]; then
392                         mkfs.ext4 -q ${PART} -L ${PART_TABLE[$idx * ${PART_TABLE_COL} + 3]} -F
393                 else
394                         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]}"
395                 fi
396         done
397
398         local -r PART9=/dev/`lsblk ${DISK} -o TYPE,KNAME | grep part | awk '{ print $2 }' | grep -G "[a-z]9\$"`
399         mkfs.ext4 -q ${PART9} -L $INFORM -F
400
401         # create "reboot-param.bin" file in inform partition for passing reboot parameter
402         # It should be done only once upon partition format.
403         if [ -d mnt_tmp ]; then
404                 echo "Remove the existing mnt_tmp directory!!"
405                 rm -rf mnt_tmp
406         fi
407         mkdir mnt_tmp
408         mount -t ext4 ${PART9} ./mnt_tmp
409         touch ./mnt_tmp/reboot-param.bin
410         sync
411         umount ./mnt_tmp
412         rmdir mnt_tmp
413
414         local -r PART15=/dev/`lsblk ${DISK} -o TYPE,KNAME | grep part | awk '{ print $2 }' | grep -G "[a-z]15\$"`
415         mkfs.ext4 -q ${PART15} -L $RESERVED2 -F
416 }
417
418 function show_usage () {
419         echo "- Usage:"
420         echo "  sudo ./sd_fusing*.sh -d <device> [-b <path> <path> ..] [--format]"
421 }
422
423 function check_partition_format () {
424         if [ "$FORMAT" != "2" ]; then
425                 echo "-----------------------"
426                 echo "Skip $DEVICE format"
427                 echo "-----------------------"
428                 return 0
429         fi
430
431         echo "-------------------------------"
432         echo "Start $DEVICE format"
433         echo ""
434         mkpart_3
435         echo "End $DEVICE format"
436         echo "-------------------------------"
437         echo ""
438 }
439
440 function check_args () {
441         if [ "$DEVICE" == "" ]; then
442                 echo -n "$(tput setaf 3)$(tput bold)$DEVICE will be formatted, Is it OK? [y/<n>] "
443                 show_usage
444                 tput sgr 0
445                 exit 0
446         fi
447
448         if [ "$DEVICE" != "" ]; then
449                 echo "Device: $DEVICE"
450         fi
451
452         if [ "$FUSING_BINARY_NUM" != 0 ]; then
453                 echo "Fusing binary: "
454                 for ((bid = 0 ; bid < $FUSING_BINARY_NUM ; bid++))
455                 do
456                         echo "  ${FUSING_BINARY_ARRAY[bid]}"
457                 done
458                 echo ""
459         fi
460
461         if [ "$FORMAT" == "1" ]; then
462                 echo ""
463                 echo "$(tput setaf 3)$(tput bold)$DEVICE will be formatted, Is it OK? [y/<n>]"
464                 tput sgr 0
465                 read input
466                 if [ "$input" == "y" ] || [ "$input" == "Y" ]; then
467                         FORMAT=2
468                 else
469                         FORMAT=0
470                 fi
471         fi
472 }
473
474 function check_device () {
475         if [ ! -b "$DEVICE" ]; then
476                 echo "No such device: $DEVICE"
477                 exit 0
478         fi
479
480         local REMOVABLE=`lsblk $DEVICE -nd -o RM | grep 1 | wc -l`
481         if [ "$REMOVABLE" == "0" ]; then
482                 echo ""
483                 echo "$(tput setaf 3)$(tput bold)$DEVICE is not a removable disk, Is it OK? [y/<n>]"
484                 tput sgr 0
485                 read input
486                 if [ "$input" != "y" ] && [ "$input" != "Y" ]; then
487                         exit 0
488                 fi
489         fi
490
491         if [ ! -w "$DEVICE" ]; then
492                 echo "Write not permitted: $DEVICE"
493                 exit 0
494         fi
495 }
496
497 function print_logo () {
498         echo ""
499         echo "Raspberry Pi4 downloader, version 1.0.0"
500         echo ""
501 }
502
503 print_logo
504
505 function add_fusing_binary() {
506         local declare binary_name=$1
507
508         if [ "$binary_name" != "" ]; then
509                 if [ -f "$binary_name" ]; then
510                         FUSING_BINARY_ARRAY[$FUSING_BINARY_NUM]=$binary_name
511
512                         FUSING_BINARY_NUM=$((FUSING_BINARY_NUM + 1))
513                 else
514                         echo "No such file: $binary_name"
515                 fi
516         fi
517 }
518
519
520 declare -i binary_option=0
521
522 while test $# -ne 0; do
523         option=$1
524         shift
525
526         case $option in
527         --f | --format)
528                 FORMAT="1"
529                 binary_option=0
530                 ;;
531         -d)
532                 DEVICE=$1
533                 binary_option=0
534                 shift
535                 ;;
536         -b)
537                 add_fusing_binary $1
538                 binary_option=1
539                 shift
540                 ;;
541         *)
542                 if [ $binary_option == 1 ];then
543                         add_fusing_binary $option
544                 else
545                         echo "Unkown command: $option"
546                         exit
547                 fi
548                 ;;
549         esac
550 done
551
552 check_args
553 check_device
554 check_partition_format
555 check_ddversion
556 fuse_image