common.sh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #!/bin/sh
  2. RAM_ROOT=/tmp/root
  3. [ -x /usr/bin/ldd ] || ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; }
  4. libs() { ldd $* 2>/dev/null | sed -r 's/(.* => )?(.*) .*/\2/'; }
  5. install_file() { # <file> [ <file> ... ]
  6. local target dest dir
  7. for file in "$@"; do
  8. if [ -L "$file" ]; then
  9. target="$(readlink -f "$file")"
  10. dest="$RAM_ROOT/$file"
  11. [ ! -f "$dest" ] && {
  12. dir="$(dirname "$dest")"
  13. mkdir -p "$dir"
  14. ln -s "$target" "$dest"
  15. }
  16. file="$target"
  17. fi
  18. dest="$RAM_ROOT/$file"
  19. [ -f "$file" -a ! -f "$dest" ] && {
  20. dir="$(dirname "$dest")"
  21. mkdir -p "$dir"
  22. cp "$file" "$dest"
  23. }
  24. done
  25. }
  26. install_bin() {
  27. local src files
  28. src=$1
  29. files=$1
  30. [ -x "$src" ] && files="$src $(libs $src)"
  31. install_file $files
  32. }
  33. run_hooks() {
  34. local arg="$1"; shift
  35. for func in "$@"; do
  36. eval "$func $arg"
  37. done
  38. }
  39. ask_bool() {
  40. local default="$1"; shift;
  41. local answer="$default"
  42. [ "$INTERACTIVE" -eq 1 ] && {
  43. case "$default" in
  44. 0) echo -n "$* (y/N): ";;
  45. *) echo -n "$* (Y/n): ";;
  46. esac
  47. read answer
  48. case "$answer" in
  49. y*) answer=1;;
  50. n*) answer=0;;
  51. *) answer="$default";;
  52. esac
  53. }
  54. [ "$answer" -gt 0 ]
  55. }
  56. v() {
  57. [ "$VERBOSE" -ge 1 ] && echo "$@"
  58. }
  59. json_string() {
  60. local v="$1"
  61. v="${v//\\/\\\\}"
  62. v="${v//\"/\\\"}"
  63. echo "\"$v\""
  64. }
  65. rootfs_type() {
  66. /bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }'
  67. }
  68. get_image() { # <source> [ <command> ]
  69. local from="$1"
  70. local cmd="$2"
  71. if [ -z "$cmd" ]; then
  72. local magic="$(dd if="$from" bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
  73. case "$magic" in
  74. 1f8b) cmd="zcat";;
  75. 425a) cmd="bzcat";;
  76. *) cmd="cat";;
  77. esac
  78. fi
  79. cat "$from" 2>/dev/null | $cmd
  80. }
  81. get_magic_word() {
  82. (get_image "$@" | dd bs=2 count=1 | hexdump -v -n 2 -e '1/1 "%02x"') 2>/dev/null
  83. }
  84. get_magic_long() {
  85. (get_image "$@" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null
  86. }
  87. export_bootdevice() {
  88. local cmdline uuid disk uevent line
  89. local MAJOR MINOR DEVNAME DEVTYPE
  90. if read cmdline < /proc/cmdline; then
  91. case "$cmdline" in
  92. *block2mtd=*)
  93. disk="${cmdline##*block2mtd=}"
  94. disk="${disk%%,*}"
  95. ;;
  96. *root=*)
  97. disk="${cmdline##*root=}"
  98. disk="${disk%% *}"
  99. ;;
  100. esac
  101. case "$disk" in
  102. PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-02)
  103. uuid="${disk#PARTUUID=}"
  104. uuid="${uuid%-02}"
  105. for disk in $(find /dev -type b); do
  106. set -- $(dd if=$disk bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '4/1 "%02x "')
  107. if [ "$4$3$2$1" = "$uuid" ]; then
  108. uevent="/sys/class/block/${disk##*/}/uevent"
  109. break
  110. fi
  111. done
  112. ;;
  113. /dev/*)
  114. uevent="/sys/class/block/${disk##*/}/uevent"
  115. ;;
  116. esac
  117. if [ -e "$uevent" ]; then
  118. while read line; do
  119. export -n "$line"
  120. done < "$uevent"
  121. export BOOTDEV_MAJOR=$MAJOR
  122. export BOOTDEV_MINOR=$MINOR
  123. return 0
  124. fi
  125. fi
  126. return 1
  127. }
  128. export_partdevice() {
  129. local var="$1" offset="$2"
  130. local uevent line MAJOR MINOR DEVNAME DEVTYPE
  131. for uevent in /sys/class/block/*/uevent; do
  132. while read line; do
  133. export -n "$line"
  134. done < "$uevent"
  135. if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then
  136. export "$var=$DEVNAME"
  137. return 0
  138. fi
  139. done
  140. return 1
  141. }
  142. hex_le32_to_cpu() {
  143. [ "$(echo 01 | hexdump -v -n 2 -e '/2 "%x"')" = "3031" ] && {
  144. echo "${1:0:2}${1:8:2}${1:6:2}${1:4:2}${1:2:2}"
  145. return
  146. }
  147. echo "$@"
  148. }
  149. get_partitions() { # <device> <filename>
  150. local disk="$1"
  151. local filename="$2"
  152. if [ -b "$disk" -o -f "$disk" ]; then
  153. v "Reading partition table from $filename..."
  154. local magic=$(dd if="$disk" bs=2 count=1 skip=255 2>/dev/null)
  155. if [ "$magic" != $'\x55\xAA' ]; then
  156. v "Invalid partition table on $disk"
  157. exit
  158. fi
  159. rm -f "/tmp/partmap.$filename"
  160. local part
  161. for part in 1 2 3 4; do
  162. set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk")
  163. local type="$(( $(hex_le32_to_cpu $1) % 256))"
  164. local lba="$(( $(hex_le32_to_cpu $2) ))"
  165. local num="$(( $(hex_le32_to_cpu $3) ))"
  166. [ $type -gt 0 ] || continue
  167. printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
  168. done
  169. fi
  170. }
  171. jffs2_copy_config() {
  172. if grep rootfs_data /proc/mtd >/dev/null; then
  173. # squashfs+jffs2
  174. mtd -e rootfs_data jffs2write "$CONF_TAR" rootfs_data
  175. else
  176. # jffs2
  177. mtd jffs2write "$CONF_TAR" rootfs
  178. fi
  179. }
  180. indicate_upgrade() {
  181. . /etc/diag.sh
  182. set_state upgrade
  183. }
  184. # Flash firmware to MTD partition
  185. #
  186. # $(1): path to image
  187. # $(2): (optional) pipe command to extract firmware, e.g. dd bs=n skip=m
  188. default_do_upgrade() {
  189. sync
  190. if [ "$SAVE_CONFIG" -eq 1 ]; then
  191. get_image "$1" "$2" | mtd $MTD_ARGS $MTD_CONFIG_ARGS -j "$CONF_TAR" write - "${PART_NAME:-image}"
  192. else
  193. get_image "$1" "$2" | mtd $MTD_ARGS write - "${PART_NAME:-image}"
  194. fi
  195. [ $? -ne 0 ] && exit 1
  196. }
  197. do_upgrade_stage2() {
  198. v "Performing system upgrade..."
  199. if [ -n "$do_upgrade" ]; then
  200. eval "$do_upgrade"
  201. elif type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
  202. platform_do_upgrade "$IMAGE"
  203. else
  204. default_do_upgrade "$IMAGE"
  205. fi
  206. if [ "$SAVE_CONFIG" -eq 1 ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then
  207. platform_copy_config
  208. fi
  209. v "Upgrade completed"
  210. sleep 1
  211. v "Rebooting system..."
  212. umount -a
  213. reboot -f
  214. sleep 5
  215. echo b 2>/dev/null >/proc/sysrq-trigger
  216. }