blob: 6f485c17208a3ed2c188d7e9ef585ae29fc2acc1 [file] [log] [blame]
Iliyan Malchev4ffa22b2013-02-27 18:45:49 -08001import common
2import struct
3
4def FindRadio(zipfile):
5 try:
6 return zipfile.read("RADIO/radio.img")
7 except KeyError:
8 return None
9
10
11def FullOTA_InstallEnd(info):
12 try:
13 bootloader_img = info.input_zip.read("RADIO/bootloader.img")
14 except KeyError:
15 print "no bootloader.img in target_files; skipping install"
16 else:
17 WriteBootloader(info, bootloader_img)
18
19 radio_img = FindRadio(info.input_zip)
20 if radio_img:
21 WriteRadio(info, radio_img)
22 else:
23 print "no radio.img in target_files; skipping install"
24
johnny1_linee060bd2013-07-18 17:07:26 +080025 DDR_img = FindDDR(info.input_zip)
26 if DDR_img:
27 WriteDDR(info, DDR_img)
28 else:
29 print "no DDR.bin in target_files; skipping install"
30
Iliyan Malchev4ffa22b2013-02-27 18:45:49 -080031
32def IncrementalOTA_VerifyEnd(info):
33 target_radio_img = FindRadio(info.target_zip)
34 source_radio_img = FindRadio(info.source_zip)
35 if not target_radio_img or not source_radio_img: return
36 if source_radio_img != target_radio_img:
37 info.script.CacheFreeSpaceCheck(len(source_radio_img))
38 radio_type, radio_device = common.GetTypeAndDevice("/radio", info.info_dict)
39 info.script.PatchCheck("%s:%s:%d:%s:%d:%s" % (
40 radio_type, radio_device,
41 len(source_radio_img), common.sha1(source_radio_img).hexdigest(),
42 len(target_radio_img), common.sha1(target_radio_img).hexdigest()))
43
44
45def IncrementalOTA_InstallEnd(info):
46 try:
47 target_bootloader_img = info.target_zip.read("RADIO/bootloader.img")
48 try:
49 source_bootloader_img = info.source_zip.read("RADIO/bootloader.img")
50 except KeyError:
51 source_bootloader_img = None
52
53 if source_bootloader_img == target_bootloader_img:
54 print "bootloader unchanged; skipping"
55 else:
56 WriteBootloader(info, target_bootloader_img)
57 except KeyError:
58 print "no bootloader.img in target target_files; skipping install"
59
johnny1_linee060bd2013-07-18 17:07:26 +080060 df = FindDDR(info.target_zip)
61 if not df:
62 print "no DDR.bin in target target_files; skipping install"
63 else:
64 df = common.File("DDR.bin", df)
65 WriteDDR(info, df.data)
66
Iliyan Malchev4ffa22b2013-02-27 18:45:49 -080067 tf = FindRadio(info.target_zip)
68 if not tf:
69 # failed to read TARGET radio image: don't include any radio in update.
70 print "no radio.img in target target_files; skipping install"
71 else:
72 tf = common.File("radio.img", tf)
73
74 sf = FindRadio(info.source_zip)
75 if not sf:
76 # failed to read SOURCE radio image: include the whole target
77 # radio image.
78 WriteRadio(info, tf.data)
79 else:
80 sf = common.File("radio.img", sf)
81
82 if tf.sha1 == sf.sha1:
83 print "radio image unchanged; skipping"
84 else:
85 diff = common.Difference(tf, sf, diff_program="bsdiff")
86 common.ComputeDifferences([diff])
87 _, _, d = diff.GetPatch()
88 if d is None or len(d) > tf.size * common.OPTIONS.patch_threshold:
89 # computing difference failed, or difference is nearly as
90 # big as the target: simply send the target.
91 WriteRadio(info, tf.data)
92 else:
93 common.ZipWriteStr(info.output_zip, "radio.img.p", d)
94 info.script.Print("Patching radio...")
95 radio_type, radio_device = common.GetTypeAndDevice(
96 "/radio", info.info_dict)
97 info.script.ApplyPatch(
98 "%s:%s:%d:%s:%d:%s" % (radio_type, radio_device,
99 sf.size, sf.sha1, tf.size, tf.sha1),
100 "-", tf.size, tf.sha1, sf.sha1, "radio.img.p")
101
102
103def WriteRadio(info, radio_img):
104 info.script.Print("Writing radio...")
105 common.ZipWriteStr(info.output_zip, "radio.img", radio_img)
106 _, device = common.GetTypeAndDevice("/radio", info.info_dict)
107 info.script.AppendExtra(
108 'package_extract_file("radio.img", "%s");' % (device,))
109
johnny1_linee060bd2013-07-18 17:07:26 +0800110def FindDDR(zipfile):
111 try:
112 return zipfile.read("RADIO/DDR.bin")
113 except KeyError:
114 return None
115
116
117def WriteDDR(info, DDR_img):
118 info.script.Print("Writing DDR...")
119 common.ZipWriteStr(info.output_zip, "DDR.bin", DDR_img)
120 info.script.AppendExtra(
121 'package_extract_file("DDR.bin", "/dev/block/platform/msm_sdcc.1/by-name/DDR");' )
Iliyan Malchev4ffa22b2013-02-27 18:45:49 -0800122
123# /* msm8960 bootloader.img format */
124#
125# #define BOOTLDR_MAGIC "BOOTLDR!"
126# #define BOOTLDR_MAGIC_SIZE 8
127#
128# struct bootloader_images_header {
129# char magic[BOOTLDR_MAGIC_SIZE];
130# unsigned int num_images;
131# unsigned int start_offset;
132# unsigned int bootldr_size;
133# struct {
134# char name[64];
135# unsigned int size;
136# } img_info[];
137# };
138
139def WriteBootloader(info, bootloader):
140 info.script.Print("Writing bootloader...")
141
142 # bootloader.img contains 6 separate images. Each goes to its own
143 # partition; we write all 6 for development devices but skip one for
144 # release devices.. There are backup partitions of all but the
145 # special one that we also write. The special one is "sbl1", which
146 # does not have a backup, so we don't update it on release devices..
147
148
149 header_fmt = "<8sIII"
150 header_size = struct.calcsize(header_fmt)
151 magic, num_images, start_offset, bootloader_size = struct.unpack(
152 header_fmt, bootloader[:header_size])
153 assert magic == "BOOTLDR!", "bootloader.img bad magic value"
154
155 img_info_fmt = "<64sI"
156 img_info_size = struct.calcsize(img_info_fmt)
157
158 imgs = [struct.unpack(img_info_fmt,
159 bootloader[header_size+i*img_info_size:
160 header_size+(i+1)*img_info_size])
161 for i in range(num_images)]
162
163 total = 0
164 p = start_offset
165 img_dict = {}
166 for name, size in imgs:
167 img_dict[trunc_to_null(name)] = p, size
168 p += size
169 assert p - start_offset == bootloader_size, "bootloader.img corrupted"
170 imgs = img_dict
171
172 common.ZipWriteStr(info.output_zip, "bootloader-flag.txt",
173 "updating-bootloader" + "\0" * 13)
174 common.ZipWriteStr(info.output_zip, "bootloader-flag-clear.txt", "\0" * 32)
175
176 _, misc_device = common.GetTypeAndDevice("/misc", info.info_dict)
177
178 info.script.AppendExtra(
179 'package_extract_file("bootloader-flag.txt", "%s");' %
180 (misc_device,))
181
182 # flashing sbl1 is somewhat dangerous because if we die while doing
183 # it the device can't boot. Do it for development devices but not
184 # release devices.
185 fp = info.info_dict["build.prop"]["ro.build.fingerprint"]
186 if "release-keys" in fp:
187 to_flash = "sbl2 sbl3 tz rpm aboot".split()
188 else:
189 to_flash = "sbl1 sbl2 sbl3 tz rpm aboot".split()
190
191 # Write the images to separate files in the OTA package
192 for i in to_flash:
193 try:
194 _, device = common.GetTypeAndDevice("/"+i, info.info_dict)
195 except KeyError:
196 print "skipping flash of %s; not in recovery.fstab" % (i,)
197 continue
198 common.ZipWriteStr(info.output_zip, "bootloader.%s.img" % (i,),
199 bootloader[imgs[i][0]:imgs[i][0]+imgs[i][1]])
200
201 info.script.AppendExtra('package_extract_file("bootloader.%s.img", "%s");' %
202 (i, device))
203
204 info.script.AppendExtra(
205 'package_extract_file("bootloader-flag-clear.txt", "%s");' %
206 (misc_device,))
207
208 try:
209 # there is no "sbl1b" partition
210 for i in "sbl2 sbl3 tz rpm aboot".split():
211 _, device = common.GetTypeAndDevice("/"+i+"b", info.info_dict)
212 info.script.AppendExtra(
213 'package_extract_file("bootloader.%s.img", "%s");' % (i, device))
214 except KeyError:
215 pass
216
217
218def trunc_to_null(s):
219 if '\0' in s:
220 return s[:s.index('\0')]
221 else:
222 return s