EC20 DFOTA » History » Version 6
zecke, 12/23/2016 10:39 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 | It seems that /usr/bin/recovery will be started and finds a update.zip in the right partition and will then apply |
||
34 | 6 | zecke | the delta updates. On exit it will reboot the system. |
35 | 1 | zecke | |
36 | |||
37 | h2. Delta format |
||
38 | |||
39 | 6 | zecke | Delta updates are available for the bootloader (?), dsp, userdata and system. The delta image contains a |
40 | FileNamesTable that has a null terminated ascii string of which part to update. The partition table for RedBend |
||
41 | is populated with information if this is a filsystem or image update. |
||
42 | 1 | zecke | |
43 | <pre> |
||
44 | struct upgrade_file_begin { |
||
45 | uint32_t checksum; // ???? different in all of these upgrades |
||
46 | 5 | zecke | uint32_t __le len; // len.. E.g. 184014 of a 184059 file, len includes the size of len+checksum too |
47 | 1 | zecke | ... still a lot of 32bit length.. not really TLV |
48 | }; |
||
49 | struct upgrade_file_trailer { |
||
50 | uint32_t __le len; |
||
51 | char name[len]; with trailing \0 |
||
52 | uint32_t null_end (four bytes 0x00) |
||
53 | }; |
||
54 | </pre> |
||
55 | 2 | zecke | |
56 | 1 | zecke | <pre> |
57 | 5 | zecke | Trailer... checksum.. len.. data.. chunks a 32bit aligned with 0x00 padding inbetween.. can be seen with the dsp2.diff |
58 | 3 | zecke | |
59 | 5 | zecke | # system.diff |
60 | 9c113566 2b00000050400100803801000000000000030000010000000700000073797374656d0000000000 |
||
61 | # userdata.diff |
||
62 | 05608f30 2d00000050400100803801000000000000030000010000000900000075736572646174610000000000 |
||
63 | 3 | zecke | # dsp2.diff |
64 | 5 | zecke | 66ecbcdc 20000000504001008038010000000000000300000000000000000000 |
65 | |||
66 | four byte? |
||
67 | 3 | zecke | </pre> |
68 | |||
69 | 2 | zecke | |
70 | h2. Kicking the recovery binary |
||
71 | |||
72 | * mount /dev/mtdblock14 /mnt.. |
||
73 | * Place update.zip to /cache/ |
||
74 | * echo "IP_START_UPDATE" > /cache/fota/ipth_config_dfs.txt to say what to do |
||
75 | |||
76 | Was difficult to repeat, e.g. creating backup and mounting system partition failed on second/third tries |
||
77 | |||
78 | <pre> |
||
79 | / # ./strace -o foo.txt -f ./recovery2 |
||
80 | mount: mounting none on /sys/kernel/debug failed: Device or resource busy |
||
81 | Starting recovery on Fri Oct 14 12:39:48 2016 |
||
82 | recovery filesystem table |
||
83 | ========================= |
||
84 | 0 /tmp ramdisk (null) (null) 0 |
||
85 | 1 / auto rootfs (null) 0 |
||
86 | 2 /proc proc proc (null) 0 |
||
87 | 3 /dev/pts devpts devpts (null) 0 |
||
88 | 4 /proc/bus/usb usbfs usbfs (null) 0 |
||
89 | 5 /dev/shm tmpfs tmpfs (null) 0 |
||
90 | 6 /cache yaffs2 /dev/mtdblock9 (null) 0 |
||
91 | 7 /media/card auto /dev/mmcblk0p1 (null) 0 |
||
92 | 8 /system yaffs2 /dev/mtdblock14 (null) 0 |
||
93 | 9 /data yaffs2 /dev/mtdblock15 (null) 0 |
||
94 | 10 /misc mtd /dev/mtdblock10 (null) 0 |
||
95 | |||
96 | rootfs on / type rootfs (rw) |
||
97 | /dev/root on / type yaffs2 (rw,relatime) |
||
98 | proc on /proc type proc (rw,relatime) |
||
99 | sysfs on /sys type sysfs (rw,relatime) |
||
100 | tmpfs on /dev type tmpfs (rw,relatime,size=64k,mode=755) |
||
101 | devpts on /dev/pts type devpts (rw,relatime,mode=600) |
||
102 | tmpfs on /dev/shm type tmpfs (rw,relatime,mode=777) |
||
103 | /dev/mtdblock15 on /usr type yaffs2 (rw,relatime) |
||
104 | /dev/mtdblock9 on /cache type yaffs2 (rw,relatime) |
||
105 | /dev/mtdblock13 on / type yaffs (rw,relatime) |
||
106 | tmpfs on /dev type tmpfs (rw,relatime,size=64k,mode=755) |
||
107 | /dev/mtdblock9 on /cache type yaffs2 (rw,relatime) |
||
108 | none on /sys type sysfs (rw,relatime) |
||
109 | none on /sys/kernel/debug type debugfs (rw,relatime) |
||
110 | proc on /proc type proc (rw,relatime) |
||
111 | total 3 |
||
112 | lrwxrwxrwx 1 root root 31 Jul 21 07:10 boot_hsic_composition -> /usr/bin/usb/compositions/empty |
||
113 | lrwxrwxrwx 1 root root 30 Jul 21 07:10 boot_hsusb_composition -> /usr/bin/usb/compositions/9215 |
||
114 | drwxr-xr-x 1 root root 2048 Jul 21 07:10 compositions |
||
115 | crw--w---- 1 root root 247, 0 Jan 8 1970 /dev/ttyGS0 |
||
116 | RB_Progress: fwrite "/dev/ttyGS1" fail |
||
117 | I:Checking delta update status... |
||
118 | handle_redbend_update: START_DELTA_UPDATE |
||
119 | I:Setting delta update status... |
||
120 | I:Delta update status is set to (IP_PREVIOUS_UPDATE_IN_PROGRESS 0) |
||
121 | I:Start delta update... |
||
122 | I:Setting recovery boot... |
||
123 | I:Recovery mode reached maximum retry. Clear boot message. |
||
124 | mtd: successfully wrote block at bebe0f4800000000 |
||
125 | I:Set boot command "" |
||
126 | I:boot.command= |
||
127 | I:boot.recovery= |
||
128 | I:Update location: /cache/update.zip |
||
129 | I:number of files in zip is 1 |
||
130 | I:verifying file at index 0 |
||
131 | I:No radio diff images found |
||
132 | I:system.diff found |
||
133 | E:No modem package available. |
||
134 | E:No modem update needed. returning O.K |
||
135 | mtd: successfully wrote block at bebe23a000000000 |
||
136 | I:Reset FOTA cookie done. |
||
137 | start fota update (/cache/fota/system.diff) |
||
138 | redbend_fs_entry: device_name: /dev/mtdblock14 |
||
139 | redbend_fs_entry: mount_point: /tmp/system |
||
140 | redbend_fs_entry: update_name: /cache/fota/system.diff |
||
141 | redbend_fs_entry: part_name: system |
||
142 | |||
143 | |||
144 | |||
145 | RB_GetDelta: offset 0x0(0), size 0x14(20) |
||
146 | RB_GetDelta: offset 0x0(0), size 0x18(24) |
||
147 | RB_GetDelta: offset 0x4(4), size 0x3508(13576) |
||
148 | RB_GetDelta: offset 0x0(0), size 0x40(64) |
||
149 | RB_GetDelta: offset 0x350c(13580), size 0x18(24) |
||
150 | RB_GetDelta: offset 0x3510(13584), size 0x27(39) |
||
151 | RB_GetDelta: offset 0x0(0), size 0x14(20) |
||
152 | RB_GetDelta: offset 0x0(0), size 0x18(24) |
||
153 | RB_GetDelta: offset 0x350c(13580), size 0x18(24) |
||
154 | RB_GetDelta: offset 0x0(0), size 0x18(24) |
||
155 | RB_GetDelta: offset 0x0(0), size 0x18(24) |
||
156 | RB_GetDelta: offset 0x350c(13580), size 0x18(24) |
||
157 | RB_GetDelta: offset 0x3524(13604), size 0x4(4) |
||
158 | RB_GetDelta: offset 0x3528(13608), size 0x4(4) |
||
159 | RB_GetDelta: offset 0x352c(13612), size 0x7(7) |
||
160 | RB_GetDelta: offset 0x0(0), size 0x40(64) |
||
161 | RB_GetDelta: offset 0x0(0), size 0x40(64) |
||
162 | RB_GetDelta: offset 0x40(64), size 0x304(772) |
||
163 | RB_GetDelta: offset 0x344(836), size 0xd(13) |
||
164 | RB_GetDelta: offset 0x351(849), size 0x4a8(1192) |
||
165 | FS partition delta dump |
||
166 | RedBend: Delta Info: delta_sig - 0x6d0d05e5 |
||
167 | RedBend: Delta Info: delta_size - 13580 |
||
168 | RedBend: Delta Info: ver - 82000 |
||
169 | RedBend: Delta Info: scout_ver - 80000 |
||
170 | RedBend: Delta Info: flags - 0x80000000 |
||
171 | RedBend: Delta Info: runtype_flags - 0x280 |
||
172 | RedBend: Delta Info: ram_size - 0x200c8 |
||
173 | RedBend: Delta Info: sector_size - 0x40000 |
||
174 | RedBend: Delta Info: dic_sz - 0xdc8 |
||
175 | RedBend: Delta Info: compress_sz - 0x4b5 |
||
176 | RedBend: Delta Info: min_alloc_ram_use - 0x22 |
||
177 | RedBend: Delta Info: ext_info_sz - 2 |
||
178 | RedBend: Delta Info: num_copy - 0 |
||
179 | RedBend: Delta Info: num_diff - 95 |
||
180 | RedBend: Delta Info: num_insert - 3 |
||
181 | RedBend: Delta Info: num_delete - 0 |
||
182 | RedBend: Delta Info: num_del_dirs - 0 |
||
183 | RedBend: Delta Info: num_dirs - 0 |
||
184 | RedBend: Delta Info: num_del_link - 0 |
||
185 | RedBend: Delta Info: num_link - 4 |
||
186 | RedBend: Delta Info: num_critical_update - 95 |
||
187 | RedBend: Delta Info: num_critical_insert - 3 |
||
188 | RB_CreateFolder: /cache/fota/a, mode:0x1ff |
||
189 | open file /cache/fota/a/backup |
||
190 | RB_OpenFile: Path:/cache/fota/a/backup | Mode: RDONLY |
||
191 | First open() with error 2 |
||
192 | open file /tmp/system/etc/version |
||
193 | RB_OpenFile: Path:/tmp/system/etc/version | Mode: RDONLY |
||
194 | First open() with error 2 |
||
195 | open file /tmp/system/etc/version |
||
196 | RB_OpenFile: Path:/tmp/system/etc/version | Mode: RDONLY |
||
197 | First open() with error 2 |
||
198 | RedBend: Error in scout, file signature mismatch in file /tmp/system/etc/version |
||
199 | umount: can't umount /tmp/system: No such file or directory |
||
200 | fota update fail (/cache/fota/system.diff) |
||
201 | I:fs:/cache/update.zip update err |
||
202 | mtd: successfully wrote block at bebe23a000000000 |
||
203 | I:Reset FOTA cookie done. |
||
204 | mtd: successfully wrote block at bebe0f3800000000 |
||
205 | I:Set boot command "" |
||
206 | I:Setting delta update status... |
||
207 | I:Delta update status is set to (IP_PREVIOUS_UPDATE_FAILED 500) |
||
208 | handle_redbend_update: DELTA_UPDATE_IN_PROGRESS |
||
209 | I:Setting delta update status... |
||
210 | I:Delta update status is set to (IP_PREVIOUS_UPDATE_IN_PROGRESS 0) |
||
211 | I:Start delta update... |
||
212 | I:Setting recovery boot... |
||
213 | I:Error opening recovery count file. Ignore. |
||
214 | mtd: successfully wrote block at bebe0f4800000000 |
||
215 | I:Set boot command "boot-recovery" |
||
216 | I:boot.command=boot-recovery |
||
217 | I:boot.recovery=recovery |
||
218 | |||
219 | I:Update location: /cache/update.zip |
||
220 | E:Can't open /cache/update.zip |
||
221 | (No such file or directory) |
||
222 | mtd: successfully wrote block at bebe0f3800000000 |
||
223 | I:Set boot command "" |
||
224 | I:Setting delta update status... |
||
225 | I:Delta update status is set to (IP_PREVIOUS_UPDATE_FAILED 410) |
||
226 | mtd: successfully wrote block at bebe23a000000000 |
||
227 | I:Reset FOTA cookie done. |
||
228 | RB_Progress: fwrite "/dev/ttyGS1" fail |
||
229 | precent:0 total:1 cur:1 |
||
230 | Rebooting after recovery |
||
231 | I:Rebooting at the end of recovery module. |
||
232 | mtd: successfully wrote block at bebe0f8000000000 |
||
233 | I:Set boot command "" |
||
234 | </pre> |