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
14 # binary name | part number | bs
15 declare -a PART_TABLE=(
18 "system-data.img" 3 4M
22 "ramdisk-recovery.img" 8 4M
25 declare -r -i PART_TABLE_ROW=3
26 declare -r -i PART_TABLE_COL=${#PART_TABLE[*]}/${PART_TABLE_ROW}
28 # partition table support
29 function get_index_use_name () {
30 local -r binary_name=$1
32 for ((idx=0;idx<$PART_TABLE_COL;idx++)); do
33 if [ ${PART_TABLE[idx * ${PART_TABLE_ROW} + 0]} == $binary_name ]; then
38 # return out of bound index
42 function print_message () {
53 function check_ddversion () {
55 # before coreutils dd 8.24, dd doesn't support "status=progress"
56 # and the option causes fusing failure. For backward compatibility,
57 # do not use the option for old dd
58 local version=(`dd --version | head -1 | grep -o '[0-9]\+'`)
59 local major=${version[0]}
60 local minor=${version[1]}
62 if [ $major -lt 8 ]; then
64 elif [ $major -eq 8 -a $minor -lt 24 ]; then
69 function fusing_image () {
70 local -r fusing_img=$1
72 # get binary info using basename
73 get_index_use_name $(basename $fusing_img)
74 local -r -i part_idx=$?
76 if [ $part_idx -ne $PART_TABLE_COL ];then
77 local -r num=${PART_TABLE[${part_idx} * ${PART_TABLE_ROW} + 1]}
78 local -r device=/dev/`lsblk ${DEVICE} -o KNAME | grep -G "[a-z]${num}\$"`
79 local -r bs=${PART_TABLE[${part_idx} * ${PART_TABLE_ROW} + 2]}
81 echo "Not supported binary: $fusing_img"
85 local -r input_size=`du -b $fusing_img | awk '{print $1}'`
86 local -r input_size_mb=`expr $input_size / 1024 / 1024`
88 print_message 2 "[Fusing $1 ($input_size_mb MiB)]"
90 if [ $OLD_DD == 1 ]; then
91 dd if=$fusing_img | pv -s $input_size | dd of=$device bs=$bs
93 dd if=$fusing_img of=$device bs=$bs status=progress oflag=direct
96 local -r fstype=`blkid -o value -s TYPE $device`
97 if [[ "$fstype" =~ "ext" ]]; then
102 function fuse_image_tarball () {
104 local -r temp_dir="tar_tmp"
107 tar xvf $filepath -C $temp_dir
120 function fuse_image () {
122 if [ "$FUSING_BINARY_NUM" == 0 ]; then
126 for ((fuse_idx = 0 ; fuse_idx < $FUSING_BINARY_NUM ; fuse_idx++))
128 local filename=${FUSING_BINARY_ARRAY[fuse_idx]}
132 fuse_image_tarball $filename
135 fusing_image $filename
143 function mkpart_3 () {
144 # NOTE: if your sfdisk version is less than 2.26.0, then you should use following sfdisk command:
145 # sfdisk --in-order --Linux --unit M $DISK <<-__EOF__
147 # NOTE: sfdisk 2.26 doesn't support units other than sectors and marks --unit option as deprecated.
148 # The input data needs to contain multipliers (MiB) instead.
149 local version=(`sfdisk -v | grep -o '[0-9]\+'`)
150 local major=${version[0]}
151 local minor=${version[1]}
154 if [ $major -gt 2 ]; then
157 if [ $major -eq 2 -a $minor -ge 26 ]; then
162 local -r DISK=$DEVICE
163 local -r SIZE=`sfdisk -s $DISK`
164 local -r SIZE_MB=$((SIZE >> 10))
167 local -r ROOTFS_SZ=3072
168 local -r DATA_SZ=1344
169 local -r MODULE_SZ=32
170 local -r RAMDISK_SZ=8
171 local -r RAMDISK_RECOVERY_SZ=32
174 local -r RESERVED2_SZ=125
175 local -r EXTEND_SZ=12
177 let "USER_SZ = $SIZE_MB - $BOOT_SZ - $ROOTFS_SZ - $DATA_SZ - $MODULE_SZ - $RAMDISK_SZ - $RAMDISK_RECOVERY_SZ - $INFORM_SZ - $EXTEND_SZ - $HAL_SZ - $RESERVED2_SZ"
180 local -r ROOTFS=rootfs
181 local -r SYSTEMDATA=system-data
183 local -r MODULE=modules
184 local -r RAMDISK=ramdisk
185 local -r RAMDISK_RECOVERY=ramdisk-recovery
186 local -r INFORM=inform
188 local -r RESERVED2=reserved2
190 if [[ $USER_SZ -le 100 ]]
192 echo "We recommend to use more than 4GB disk"
196 echo "========================================"
197 echo "Label dev size"
198 echo "========================================"
199 echo $BOOT" " $DISK"1 " $BOOT_SZ "MB"
200 echo $ROOTFS" " $DISK"2 " $ROOTFS_SZ "MB"
201 echo $SYSTEMDATA" " $DISK"3 " $DATA_SZ "MB"
202 echo "[Extend]"" " $DISK"4"
203 echo " "$USER" " $DISK"5 " $USER_SZ "MB"
204 echo " "$MODULE" " $DISK"6 " $MODULE_SZ "MB"
205 echo " "$RAMDISK" " $DISK"7 " $RAMDISK_SZ "MB"
206 echo " "$RAMDISK_RECOVERY" " $DISK"8 " $RAMDISK_RECOVERY_SZ "MB"
207 echo " "$INFORM" " $DISK"9 " $INFORM_SZ "MB"
208 echo " "$HAL" " $DISK"10 " $HAL_SZ "MB"
209 echo " "$RESERVED2" " $DISK"11 " $RESERVED2_SZ "MB"
211 local MOUNT_LIST=`mount | grep $DISK | awk '{print $1}'`
212 for mnt in $MOUNT_LIST
217 echo "Remove partition table..."
218 dd if=/dev/zero of=$DISK bs=512 count=16 conv=notrunc
220 if [ $sfdisk_new == 1 ]; then
221 sfdisk $DISK <<-__EOF__
222 4MiB,${BOOT_SZ}MiB,0xE,*
223 8MiB,${ROOTFS_SZ}MiB,,-
224 8MiB,${DATA_SZ}MiB,,-
229 ,${RAMDISK_RECOVERY_SZ}MiB,,-
232 ,${RESERVED2_SZ}MiB,,-
235 # calculate start positions for alignment for extended partitions
236 let "USER_START = 4 + $BOOT_SZ + $ROOTFS_SZ + $DATA_SZ + 1"
237 let "MODULE_START = $USER_START + $USER_SZ + 1"
238 let "RAMDISK_START = $MODULE_START + $MODULE_SZ + 1"
239 let "RAMDISK_RECOVERY_START = $RAMDISK_START + $RAMDISK_SZ + 1"
240 let "INFORM_START = $RAMDISK_RECOVERY_START + $RAMDISK_RECOVERY_SZ + 1"
241 let "HAL_START = $INFORM_START + $INFORM_SZ + 1"
242 let "RESERVED2_START = $HAL_START + $HAL_SZ + 1"
244 sfdisk --in-order --Linux --unit M $DISK <<-__EOF__
249 $USER_START,$USER_SZ,,-
250 $MODULE_START,$MODULE_SZ,,-
251 $RAMDISK_START,$RAMDISK_SZ,,-
252 $RAMDISK_RECOVERY_START,$RAMDISK_RECOVERY_SZ,,-
253 $INFORM_START,$INFORM_SZ,,-
254 $HAL_START,$HAL_SZ,,-
255 $RESERVED2_START,$RESERVED2_SZ,,-
259 local -r PART1=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]1\$"`
260 mkfs.vfat -F 16 ${PART1} -n $BOOT
262 local -r PART2=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]2\$"`
263 mkfs.ext4 -q ${PART2} -L $ROOTFS -F
265 local -r PART3=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]3\$"`
266 mkfs.ext4 -q ${PART3} -L $SYSTEMDATA -F
268 local -r PART5=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]5\$"`
269 mkfs.ext4 -q ${PART5} -L $USER -F
271 local -r PART6=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]6\$"`
272 mkfs.ext4 -q ${PART6} -L $MODULE -F
274 local -r PART7=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]7\$"`
275 mkfs.ext4 -q ${PART7} -L $RAMDISK -F
277 local -r PART8=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]8\$"`
278 mkfs.ext4 -q ${PART8} -L $RAMDISK_RECOVERY -F
280 local -r PART9=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]9\$"`
281 mkfs.ext4 -q ${PART9} -L $INFORM -F
283 local -r PART10=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]10\$"`
284 mkfs.ext4 -q ${PART10} -L $HAL -F
286 local -r PART11=/dev/`lsblk ${DISK} -o KNAME | grep -G "[a-z]11\$"`
287 mkfs.ext4 -q ${PART11} -L $RESERVED2 -F
289 # create "reboot-param.bin" file in inform partition for passing reboot parameter
290 # It should be done only once upon partition format.
293 mount -t ext4 ${PART9} ./mnt_tmp
294 touch ./mnt_tmp/reboot-param.bin
300 function show_usage () {
302 echo " sudo ./sd_fusing*.sh -d <device> [-b <path> <path> ..] [--format]"
305 function check_partition_format () {
306 if [ "$FORMAT" != "2" ]; then
307 echo "-----------------------"
308 echo "Skip $DEVICE format"
309 echo "-----------------------"
313 echo "-------------------------------"
314 echo "Start $DEVICE format"
317 echo "End $DEVICE format"
318 echo "-------------------------------"
322 function check_args () {
323 if [ "$DEVICE" == "" ]; then
324 echo "$(tput setaf 1)$(tput bold)- Device node is empty!"
330 if [ "$DEVICE" != "" ]; then
331 echo "Device: $DEVICE"
334 if [ "$FUSING_BINARY_NUM" != 0 ]; then
335 echo "Fusing binary: "
336 for ((bid = 0 ; bid < $FUSING_BINARY_NUM ; bid++))
338 echo " ${FUSING_BINARY_ARRAY[bid]}"
343 if [ "$FORMAT" == "1" ]; then
345 echo "$(tput setaf 3)$(tput bold)$DEVICE will be formatted, Is it OK? [y/n]"
348 if [ "$input" == "y" ] || [ "$input" == "Y" ]; then
356 function check_device () {
357 if [ ! -b "$DEVICE" ]; then
358 echo "No such device: $DEVICE"
362 local REMOVABLE=`lsblk $DEVICE -nd -o RM | grep 1 | wc -l`
363 if [ "$REMOVABLE" == "0" ]; then
365 echo "$(tput setaf 3)$(tput bold)$DEVICE is not a removable disk, Is it OK? [y/<n>]"
368 if [ "$input" != "y" ] && [ "$input" != "Y" ]; then
373 if [ ! -w "$DEVICE" ]; then
374 echo "Write not permitted: $DEVICE"
379 function print_logo () {
381 echo "Raspberry Pi downloader, version 2.0.0"
387 function add_fusing_binary() {
388 local declare binary_name=$1
389 FUSING_BINARY_ARRAY[$FUSING_BINARY_NUM]=$binary_name
391 FUSING_BINARY_NUM=$((FUSING_BINARY_NUM + 1))
395 declare -i binary_option=0
397 while test $# -ne 0; do
417 if [ $binary_option == 1 ];then
418 add_fusing_binary $option
420 echo "Unkown command: $option"
429 check_partition_format