x86: add bootloader upgrade on sysupgrade
[openwrt/openwrt.git] / target / linux / x86 / base-files / lib / upgrade / platform.sh
1 RAMFS_COPY_BIN='grub-bios-setup'
2
3 platform_check_image() {
4 local diskdev partdev diff
5 [ "$#" -gt 1 ] && return 1
6
7 case "$(get_magic_word "$1")" in
8 eb48|eb63) ;;
9 *)
10 echo "Invalid image type"
11 return 1
12 ;;
13 esac
14
15 export_bootdevice && export_partdevice diskdev 0 || {
16 echo "Unable to determine upgrade device"
17 return 1
18 }
19
20 get_partitions "/dev/$diskdev" bootdisk
21
22 #extract the boot sector from the image
23 get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
24
25 get_partitions /tmp/image.bs image
26
27 #compare tables
28 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
29
30 rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
31
32 if [ -n "$diff" ]; then
33 echo "Partition layout has changed. Full image will be written."
34 ask_bool 0 "Abort" && exit 1
35 return 0
36 fi
37 }
38
39 platform_copy_config() {
40 local partdev
41
42 if export_partdevice partdev 1; then
43 mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
44 cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
45 umount /mnt
46 fi
47 }
48
49 platform_do_bootloader_upgrade() {
50 local bootpart
51 local diskdev="$1"
52
53 if export_partdevice bootpart 1; then
54 mkdir -p /tmp/boot
55 mount -o rw,noatime "/dev/$bootpart" /tmp/boot
56 echo "(hd0) /dev/$diskdev" > /tmp/device.map
57
58 echo "Upgrading bootloader on /dev/$diskdev..."
59 grub-bios-setup \
60 -m "/tmp/device.map" \
61 -d "/tmp/boot/boot/grub" \
62 -r "hd0,msdos1" \
63 "/dev/$diskdev"
64
65 umount /tmp/boot
66 fi
67 }
68
69 platform_do_upgrade() {
70 local diskdev partdev diff
71
72 export_bootdevice && export_partdevice diskdev 0 || {
73 echo "Unable to determine upgrade device"
74 return 1
75 }
76
77 sync
78
79 if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
80 get_partitions "/dev/$diskdev" bootdisk
81
82 #extract the boot sector from the image
83 get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
84
85 get_partitions /tmp/image.bs image
86
87 #compare tables
88 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
89 else
90 diff=1
91 fi
92
93 if [ -n "$diff" ]; then
94 get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
95
96 # Separate removal and addtion is necessary; otherwise, partition 1
97 # will be missing if it overlaps with the old partition 2
98 partx -d - "/dev/$diskdev"
99 partx -a - "/dev/$diskdev"
100
101 return 0
102 fi
103
104 #iterate over each partition from the image and write it to the boot disk
105 while read part start size; do
106 if export_partdevice partdev $part; then
107 echo "Writing image to /dev/$partdev..."
108 get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
109 else
110 echo "Unable to find partition $part device, skipped."
111 fi
112 done < /tmp/partmap.image
113
114 #copy partition uuid
115 echo "Writing new UUID to /dev/$diskdev..."
116 get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
117
118 platform_do_bootloader_upgrade "$diskdev"
119 }