EC20 DFOTA » History » Version 7
zecke, 12/23/2016 10:58 AM
1 | 1 | zecke | h1. EC20/EC25 Delta Firmware over the air (DFOTA) upgrades |
---|---|---|---|
2 | |||
3 | 6 | zecke | An example of the DFOTA file is here: http://dfota.quectel-service.com:8088/Dfiles/EC20/EC20EQAR02A05V03-R02A09V02.zip. EC25 seems to use the stock "recovery"/"applypatch". |
4 | 1 | zecke | |
5 | 6 | zecke | h2. Mechanism |
6 | |||
7 | It is based on the recovery.git of Android. For the EC20 the delta format (and RSA signing) has been replaced by the usage of |
||
8 | RedBend FOTA. The RedBend FOTA is used by other Qualcomm customers too and is also used on the UC20. For the EC25 it |
||
9 | seems that the stock Android/LinuxFoundation @recovery@ is used. |
||
10 | |||
11 | The general approach is: |
||
12 | |||
13 | * APN is configured for the Linux system |
||
14 | * AT+QFOTADL is handled by atfwd_daemon and starts @wget@ to write to @update.zip@ |
||
15 | * @"IP_START_UPDATE" > /cache/fota/ipth_config_dfs.txt@ |
||
16 | * Reboot into the recovery image |
||
17 | * recovery will apply the update. |
||
18 | |||
19 | |||
20 | |||
21 | 1 | zecke | h2. Start delta upgrade |
22 | |||
23 | <pre> |
||
24 | 6 | zecke | AT+QICSGP=1,1,"APN_NAME_HERE","","",1 |
25 | 1 | zecke | AT+QFOTADL="http://dfota.quectel-service.com:8088/Dfiles/EC20/EC20EQAR02A05V03-R02A09V02.zip" |
26 | </pre> |
||
27 | |||
28 | It will start an internal connection manager to terminate data on the Linux module and then run wget to store the file to |
||
29 | "update.zip". If it worked a reboot into the recovery system will be made. |
||
30 | |||
31 | h2. Recovery image |
||
32 | |||
33 | 7 | zecke | The @/usr/bin/recovery@ of the recovery image will be started on boot and checks for a @update.zip@ and |
34 | the instructions in @ipth_config_dfs.txt@ and then apply the updates. Maintain some counters for how often |
||
35 | an upgrade was attempted and reboot into the main image. |
||
36 | 1 | zecke | |
37 | |||
38 | h2. Delta format |
||
39 | 6 | zecke | |
40 | 7 | zecke | Delta updates can update images (e.g. bootloader, kernel) and files on a mounted filesystem. The update.zip |
41 | contains one file per image/filesystem to update. The general format is the same for both images and filesystems |
||
42 | and the semantic comes from the partition table supplied by the recovery application to the RedBend component. |
||
43 | 1 | zecke | |
44 | 7 | zecke | The delta update consists out of several nested parts and pointers/offsets into it. |
45 | 6 | zecke | |
46 | 7 | zecke | * Part1 with actual update |
47 | ** CRC32 + len |
||
48 | ** Common header |
||
49 | ** Information of decompressed size of TableOfContents (TOC), offset for info within TOC |
||
50 | ** Information of different amount of updates (diffs, inserts, removals, links, etc.) |
||
51 | ** Variable part depending on above information (e.g. old and new CRC32 of files, unused data for insert, unknown for other) |
||
52 | ** LZMA TableOfContents (TOC) (needs to have uncompressed size in the header and no end-of-payload marker) |
||
53 | *** Starts with null terminated filenames to patch |
||
54 | *** List of file permissions (separated by 0xAF) |
||
55 | *** Information about updates (common header points to this offset). For inserts includes filesize, offset for permission, compressed size of update) |
||
56 | ** LZMA of Insert (same requirement as above) |
||
57 | ** Maybe some padding.. unknown about when to insert it |
||
58 | 1 | zecke | |
59 | 7 | zecke | * Part2 with FileNamesTable |
60 | ** CRC32 + len |
||
61 | ** Common Information |
||
62 | ** Len + null terminated string |
||
63 | 1 | zecke | |
64 | 7 | zecke | |
65 | <pre> |
||
66 | struct update_part_header { |
||
67 | uint32_t crc32 // CRC32 of len + data |
||
68 | uint32_t __le len; // |
||
69 | uint8_t data[0]; |
||
70 | }; |
||
71 | 5 | zecke | </pre> |
72 | |||
73 | 7 | zecke | We have a python script to dissect the basic structure of a diff and another script to pack a file as insert in an upgrade. Image |
74 | updates were not studied. |
||
75 | 3 | zecke | |
76 | 7 | zecke | |
77 | 2 | zecke | h2. Kicking the recovery binary |
78 | |||
79 | * mount /dev/mtdblock14 /mnt.. |
||
80 | * Place update.zip to /cache/ |
||
81 | * echo "IP_START_UPDATE" > /cache/fota/ipth_config_dfs.txt to say what to do |
||
82 | |||
83 | Was difficult to repeat, e.g. creating backup and mounting system partition failed on second/third tries |
||
84 | |||
85 | <pre> |
||
86 | 7 | zecke | / # recovery |
87 | 2 | zecke | mount: mounting none on /sys/kernel/debug failed: Device or resource busy |
88 | Starting recovery on Fri Oct 14 12:39:48 2016 |
||
89 | recovery filesystem table |
||
90 | ========================= |
||
91 | 0 /tmp ramdisk (null) (null) 0 |
||
92 | 1 / auto rootfs (null) 0 |
||
93 | 2 /proc proc proc (null) 0 |
||
94 | 3 /dev/pts devpts devpts (null) 0 |
||
95 | 4 /proc/bus/usb usbfs usbfs (null) 0 |
||
96 | 5 /dev/shm tmpfs tmpfs (null) 0 |
||
97 | 6 /cache yaffs2 /dev/mtdblock9 (null) 0 |
||
98 | 7 /media/card auto /dev/mmcblk0p1 (null) 0 |
||
99 | 8 /system yaffs2 /dev/mtdblock14 (null) 0 |
||
100 | 9 /data yaffs2 /dev/mtdblock15 (null) 0 |
||
101 | 10 /misc mtd /dev/mtdblock10 (null) 0 |
||
102 | |||
103 | rootfs on / type rootfs (rw) |
||
104 | /dev/root on / type yaffs2 (rw,relatime) |
||
105 | proc on /proc type proc (rw,relatime) |
||
106 | sysfs on /sys type sysfs (rw,relatime) |
||
107 | tmpfs on /dev type tmpfs (rw,relatime,size=64k,mode=755) |
||
108 | devpts on /dev/pts type devpts (rw,relatime,mode=600) |
||
109 | tmpfs on /dev/shm type tmpfs (rw,relatime,mode=777) |
||
110 | /dev/mtdblock15 on /usr type yaffs2 (rw,relatime) |
||
111 | /dev/mtdblock9 on /cache type yaffs2 (rw,relatime) |
||
112 | /dev/mtdblock13 on / type yaffs (rw,relatime) |
||
113 | tmpfs on /dev type tmpfs (rw,relatime,size=64k,mode=755) |
||
114 | /dev/mtdblock9 on /cache type yaffs2 (rw,relatime) |
||
115 | none on /sys type sysfs (rw,relatime) |
||
116 | none on /sys/kernel/debug type debugfs (rw,relatime) |
||
117 | proc on /proc type proc (rw,relatime) |
||
118 | total 3 |
||
119 | lrwxrwxrwx 1 root root 31 Jul 21 07:10 boot_hsic_composition -> /usr/bin/usb/compositions/empty |
||
120 | lrwxrwxrwx 1 root root 30 Jul 21 07:10 boot_hsusb_composition -> /usr/bin/usb/compositions/9215 |
||
121 | drwxr-xr-x 1 root root 2048 Jul 21 07:10 compositions |
||
122 | crw--w---- 1 root root 247, 0 Jan 8 1970 /dev/ttyGS0 |
||
123 | RB_Progress: fwrite "/dev/ttyGS1" fail |
||
124 | I:Checking delta update status... |
||
125 | handle_redbend_update: START_DELTA_UPDATE |
||
126 | I:Setting delta update status... |
||
127 | I:Delta update status is set to (IP_PREVIOUS_UPDATE_IN_PROGRESS 0) |
||
128 | I:Start delta update... |
||
129 | I:Setting recovery boot... |
||
130 | I:Recovery mode reached maximum retry. Clear boot message. |
||
131 | mtd: successfully wrote block at bebe0f4800000000 |
||
132 | I:Set boot command "" |
||
133 | I:boot.command= |
||
134 | I:boot.recovery= |
||
135 | I:Update location: /cache/update.zip |
||
136 | I:number of files in zip is 1 |
||
137 | I:verifying file at index 0 |
||
138 | I:No radio diff images found |
||
139 | I:system.diff found |
||
140 | E:No modem package available. |
||
141 | E:No modem update needed. returning O.K |
||
142 | mtd: successfully wrote block at bebe23a000000000 |
||
143 | I:Reset FOTA cookie done. |
||
144 | start fota update (/cache/fota/system.diff) |
||
145 | redbend_fs_entry: device_name: /dev/mtdblock14 |
||
146 | redbend_fs_entry: mount_point: /tmp/system |
||
147 | redbend_fs_entry: update_name: /cache/fota/system.diff |
||
148 | redbend_fs_entry: part_name: system |
||
149 | |||
150 | |||
151 | |||
152 | RB_GetDelta: offset 0x0(0), size 0x14(20) |
||
153 | RB_GetDelta: offset 0x0(0), size 0x18(24) |
||
154 | RB_GetDelta: offset 0x4(4), size 0x3508(13576) |
||
155 | RB_GetDelta: offset 0x0(0), size 0x40(64) |
||
156 | RB_GetDelta: offset 0x350c(13580), size 0x18(24) |
||
157 | RB_GetDelta: offset 0x3510(13584), size 0x27(39) |
||
158 | RB_GetDelta: offset 0x0(0), size 0x14(20) |
||
159 | RB_GetDelta: offset 0x0(0), size 0x18(24) |
||
160 | RB_GetDelta: offset 0x350c(13580), size 0x18(24) |
||
161 | RB_GetDelta: offset 0x0(0), size 0x18(24) |
||
162 | RB_GetDelta: offset 0x0(0), size 0x18(24) |
||
163 | RB_GetDelta: offset 0x350c(13580), size 0x18(24) |
||
164 | RB_GetDelta: offset 0x3524(13604), size 0x4(4) |
||
165 | RB_GetDelta: offset 0x3528(13608), size 0x4(4) |
||
166 | RB_GetDelta: offset 0x352c(13612), size 0x7(7) |
||
167 | RB_GetDelta: offset 0x0(0), size 0x40(64) |
||
168 | RB_GetDelta: offset 0x0(0), size 0x40(64) |
||
169 | RB_GetDelta: offset 0x40(64), size 0x304(772) |
||
170 | RB_GetDelta: offset 0x344(836), size 0xd(13) |
||
171 | RB_GetDelta: offset 0x351(849), size 0x4a8(1192) |
||
172 | FS partition delta dump |
||
173 | RedBend: Delta Info: delta_sig - 0x6d0d05e5 |
||
174 | RedBend: Delta Info: delta_size - 13580 |
||
175 | RedBend: Delta Info: ver - 82000 |
||
176 | RedBend: Delta Info: scout_ver - 80000 |
||
177 | RedBend: Delta Info: flags - 0x80000000 |
||
178 | RedBend: Delta Info: runtype_flags - 0x280 |
||
179 | RedBend: Delta Info: ram_size - 0x200c8 |
||
180 | RedBend: Delta Info: sector_size - 0x40000 |
||
181 | RedBend: Delta Info: dic_sz - 0xdc8 |
||
182 | RedBend: Delta Info: compress_sz - 0x4b5 |
||
183 | RedBend: Delta Info: min_alloc_ram_use - 0x22 |
||
184 | RedBend: Delta Info: ext_info_sz - 2 |
||
185 | RedBend: Delta Info: num_copy - 0 |
||
186 | RedBend: Delta Info: num_diff - 95 |
||
187 | RedBend: Delta Info: num_insert - 3 |
||
188 | RedBend: Delta Info: num_delete - 0 |
||
189 | RedBend: Delta Info: num_del_dirs - 0 |
||
190 | RedBend: Delta Info: num_dirs - 0 |
||
191 | RedBend: Delta Info: num_del_link - 0 |
||
192 | RedBend: Delta Info: num_link - 4 |
||
193 | RedBend: Delta Info: num_critical_update - 95 |
||
194 | RedBend: Delta Info: num_critical_insert - 3 |
||
195 | RB_CreateFolder: /cache/fota/a, mode:0x1ff |
||
196 | open file /cache/fota/a/backup |
||
197 | RB_OpenFile: Path:/cache/fota/a/backup | Mode: RDONLY |
||
198 | First open() with error 2 |
||
199 | open file /tmp/system/etc/version |
||
200 | RB_OpenFile: Path:/tmp/system/etc/version | Mode: RDONLY |
||
201 | First open() with error 2 |
||
202 | open file /tmp/system/etc/version |
||
203 | RB_OpenFile: Path:/tmp/system/etc/version | Mode: RDONLY |
||
204 | First open() with error 2 |
||
205 | RedBend: Error in scout, file signature mismatch in file /tmp/system/etc/version |
||
206 | umount: can't umount /tmp/system: No such file or directory |
||
207 | fota update fail (/cache/fota/system.diff) |
||
208 | I:fs:/cache/update.zip update err |
||
209 | mtd: successfully wrote block at bebe23a000000000 |
||
210 | I:Reset FOTA cookie done. |
||
211 | mtd: successfully wrote block at bebe0f3800000000 |
||
212 | I:Set boot command "" |
||
213 | I:Setting delta update status... |
||
214 | I:Delta update status is set to (IP_PREVIOUS_UPDATE_FAILED 500) |
||
215 | handle_redbend_update: DELTA_UPDATE_IN_PROGRESS |
||
216 | I:Setting delta update status... |
||
217 | I:Delta update status is set to (IP_PREVIOUS_UPDATE_IN_PROGRESS 0) |
||
218 | I:Start delta update... |
||
219 | I:Setting recovery boot... |
||
220 | I:Error opening recovery count file. Ignore. |
||
221 | mtd: successfully wrote block at bebe0f4800000000 |
||
222 | I:Set boot command "boot-recovery" |
||
223 | I:boot.command=boot-recovery |
||
224 | I:boot.recovery=recovery |
||
225 | |||
226 | I:Update location: /cache/update.zip |
||
227 | E:Can't open /cache/update.zip |
||
228 | (No such file or directory) |
||
229 | mtd: successfully wrote block at bebe0f3800000000 |
||
230 | I:Set boot command "" |
||
231 | I:Setting delta update status... |
||
232 | I:Delta update status is set to (IP_PREVIOUS_UPDATE_FAILED 410) |
||
233 | mtd: successfully wrote block at bebe23a000000000 |
||
234 | I:Reset FOTA cookie done. |
||
235 | RB_Progress: fwrite "/dev/ttyGS1" fail |
||
236 | precent:0 total:1 cur:1 |
||
237 | Rebooting after recovery |
||
238 | I:Rebooting at the end of recovery module. |
||
239 | mtd: successfully wrote block at bebe0f8000000000 |
||
240 | I:Set boot command "" |
||
241 | </pre> |