base-files: add generic sdcard upgrade method
[openwrt/staging/jow.git] / package / base-files / files / lib / upgrade / sdcard.sh
1 sdcard_check_image() {
2 local file="$1"
3 local diskdev partdev diff
4
5 export_bootdevice && export_partdevice diskdev 0 || {
6 v "Unable to determine upgrade device"
7 return 1
8 }
9
10 get_partitions "/dev/$diskdev" bootdisk
11
12 v "Extract boot sector from the image"
13 get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
14
15 get_partitions /tmp/image.bs image
16
17 #compare tables
18 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
19
20 rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
21
22 if [ -n "$diff" ]; then
23 v "Partition layout has changed. Full image will be written."
24 ask_bool 0 "Abort" && exit 1
25 return 0
26 fi
27 }
28
29 sdcard_do_upgrade() {
30 local board=$(board_name)
31 local diskdev partdev diff
32
33 export_bootdevice && export_partdevice diskdev 0 || {
34 v "Unable to determine upgrade device"
35 return 1
36 }
37
38 sync
39
40 if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
41 get_partitions "/dev/$diskdev" bootdisk
42
43 v "Extract boot sector from the image"
44 get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
45
46 get_partitions /tmp/image.bs image
47
48 #compare tables
49 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
50 else
51 diff=1
52 fi
53
54 if [ -n "$diff" ]; then
55 get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
56
57 # Separate removal and addtion is necessary; otherwise, partition 1
58 # will be missing if it overlaps with the old partition 2
59 partx -d - "/dev/$diskdev"
60 partx -a - "/dev/$diskdev"
61 else
62 v "Writing bootloader to /dev/$diskdev"
63 get_image_dd "$1" of="$diskdev" bs=512 skip=1 seek=1 count=2048 conv=fsync
64 #iterate over each partition from the image and write it to the boot disk
65 while read part start size; do
66 if export_partdevice partdev $part; then
67 v "Writing image to /dev/$partdev..."
68 get_image_dd "$1" of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
69 else
70 v "Unable to find partition $part device, skipped."
71 fi
72 done < /tmp/partmap.image
73
74 v "Writing new UUID to /dev/$diskdev..."
75 get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
76 fi
77
78 sleep 1
79 }
80
81 sdcard_copy_config() {
82 local partdev
83
84 if export_partdevice partdev 1; then
85 mkdir -p /boot
86 [ -f /boot/kernel.img ] || mount -o rw,noatime /dev/$partdev /boot
87 cp -af "$UPGRADE_BACKUP" "/boot/$BACKUP_FILE"
88 sync
89 umount /boot
90 fi
91 }