ddimage 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #!/bin/sh
  2. #
  3. # Copyright OpenEmbedded Contributors
  4. #
  5. # SPDX-License-Identifier: GPL-2.0-only
  6. #
  7. # 1MB blocksize
  8. BLOCKSIZE=1048576
  9. usage() {
  10. echo "Usage: $(basename $0) IMAGE DEVICE"
  11. }
  12. image_details() {
  13. IMG=$1
  14. echo "Image details"
  15. echo "============="
  16. echo " image: $(basename $IMG)"
  17. # stat format is different on Mac OS and Linux
  18. if [ "$(uname)" = "Darwin" ]; then
  19. echo " size: $(stat -L -f '%z bytes' $IMG)"
  20. echo " modified: $(stat -L -f '%Sm' $IMG)"
  21. else
  22. echo " size: $(stat -L -c '%s bytes' $IMG)"
  23. echo " modified: $(stat -L -c '%y' $IMG)"
  24. fi
  25. echo " type: $(file -L -b $IMG)"
  26. echo ""
  27. }
  28. device_details() {
  29. BLOCK_SIZE=512
  30. echo "Device details"
  31. echo "=============="
  32. # Collect disk info using diskutil on Mac OS
  33. if [ "$(uname)" = "Darwin" ]; then
  34. diskutil info $DEVICE | egrep "(Device Node|Media Name|Total Size)"
  35. return
  36. fi
  37. # Default / Linux information collection
  38. ACTUAL_DEVICE=`readlink -f $DEVICE`
  39. DEV=`basename $ACTUAL_DEVICE`
  40. if [ "$ACTUAL_DEVICE" != "$DEVICE" ] ; then
  41. echo " device: $DEVICE -> $ACTUAL_DEVICE"
  42. else
  43. echo " device: $DEVICE"
  44. fi
  45. if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
  46. echo " vendor: $(cat /sys/class/block/$DEV/device/vendor)"
  47. else
  48. echo " vendor: UNKNOWN"
  49. fi
  50. if [ -f "/sys/class/block/$DEV/device/model" ]; then
  51. echo " model: $(cat /sys/class/block/$DEV/device/model)"
  52. else
  53. echo " model: UNKNOWN"
  54. fi
  55. if [ -f "/sys/class/block/$DEV/size" ]; then
  56. echo " size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
  57. else
  58. echo " size: UNKNOWN"
  59. fi
  60. echo ""
  61. }
  62. check_mount_device() {
  63. if cat /proc/self/mounts | awk '{ print $1 }' | grep /dev/ | grep -q -E "^$1$" ; then
  64. return 0
  65. fi
  66. return 1
  67. }
  68. is_mounted() {
  69. if [ "$(uname)" = "Darwin" ]; then
  70. if df | awk '{ print $1 }' | grep /dev/ | grep -q -E "^$1(s[0-9]+)?$" ; then
  71. return 0
  72. fi
  73. else
  74. if check_mount_device $1 ; then
  75. return 0
  76. fi
  77. DEV=`basename $1`
  78. if [ -d /sys/class/block/$DEV/ ] ; then
  79. PARENT_BLKDEV=`basename $(readlink -f "/sys/class/block/$DEV/..")`
  80. if [ "$PARENT_BLKDEV" != "block" ] ; then
  81. if check_mount_device $PARENT_BLKDEV ; then
  82. return 0
  83. fi
  84. fi
  85. for CHILD_BLKDEV in `find /sys/class/block/$DEV/ -mindepth 1 -maxdepth 1 -name "$DEV*" -type d`
  86. do
  87. if check_mount_device /dev/`basename $CHILD_BLKDEV` ; then
  88. return 0
  89. fi
  90. done
  91. fi
  92. fi
  93. return 1
  94. }
  95. is_inuse() {
  96. HOLDERS_DIR="/sys/class/block/`basename $1`/holders"
  97. if [ -d $HOLDERS_DIR ] && [ `ls -A $HOLDERS_DIR` ] ; then
  98. return 0
  99. fi
  100. return 1
  101. }
  102. if [ $# -ne 2 ]; then
  103. usage
  104. exit 1
  105. fi
  106. IMAGE=$1
  107. DEVICE=$2
  108. if [ ! -e "$IMAGE" ]; then
  109. echo "ERROR: Image $IMAGE does not exist"
  110. usage
  111. exit 1
  112. fi
  113. if [ ! -e "$DEVICE" ]; then
  114. echo "ERROR: Device $DEVICE does not exist"
  115. usage
  116. exit 1
  117. fi
  118. if [ "$(uname)" = "Darwin" ]; then
  119. # readlink doesn't support -f on MacOS, just assume it isn't a symlink
  120. ACTUAL_DEVICE=$DEVICE
  121. else
  122. ACTUAL_DEVICE=`readlink -f $DEVICE`
  123. fi
  124. if is_mounted $ACTUAL_DEVICE ; then
  125. echo "ERROR: Device $DEVICE is currently mounted - check if this is the right device, and unmount it first if so"
  126. device_details
  127. exit 1
  128. fi
  129. if is_inuse $ACTUAL_DEVICE ; then
  130. echo "ERROR: Device $DEVICE is currently in use (possibly part of LVM) - check if this is the right device!"
  131. device_details
  132. exit 1
  133. fi
  134. if [ ! -w "$DEVICE" ]; then
  135. echo "ERROR: Device $DEVICE is not writable - possibly use sudo?"
  136. usage
  137. exit 1
  138. fi
  139. image_details $IMAGE
  140. device_details
  141. printf "Write $IMAGE to $DEVICE [y/N]? "
  142. read RESPONSE
  143. if [ "$RESPONSE" != "y" ]; then
  144. echo "Write aborted"
  145. exit 0
  146. fi
  147. echo "Writing image..."
  148. if which pv >/dev/null 2>&1; then
  149. pv "$IMAGE" | dd of="$DEVICE" bs="$BLOCKSIZE"
  150. else
  151. dd if="$IMAGE" of="$DEVICE" bs="$BLOCKSIZE"
  152. fi
  153. sync