1# Copyright (C) 2012 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Emit extra commands needed for Group during OTA installation
16(installing the bootloader)."""
17
18import struct
19import common
20
21
22def WriteIfwi(info):
23  info.script.AppendExtra('package_extract_file("ifwi.bin", "/tmp/ifwi.bin");')
24  info.script.AppendExtra("""fugu.flash_ifwi("/tmp/ifwi.bin");""")
25
26def WriteDroidboot(info):
27  info.script.WriteRawImage("/fastboot", "droidboot.img")
28
29def WriteSplashscreen(info):
30  info.script.WriteRawImage("/splashscreen", "splashscreen.img")
31
32def WriteBootloader(info, bootloader):
33  header_fmt = "<8sHHI"
34  header_size = struct.calcsize(header_fmt)
35  magic, revision, reserved, reserved = struct.unpack(
36    header_fmt, bootloader[:header_size])
37
38  assert magic == "BOOTLDR!", "bootloader.img bad magic value"
39
40  if revision == 1:
41    offset = header_size;
42    header_v1_fmt = "II"
43    header_v1_size = struct.calcsize(header_v1_fmt)
44    ifwi_size, droidboot_size = struct.unpack(header_v1_fmt, bootloader[offset:offset + header_v1_size])
45    offset += header_v1_size
46    ifwi = bootloader[offset:offset + ifwi_size]
47    offset += ifwi_size
48    droidboot = bootloader[offset:]
49    common.ZipWriteStr(info.output_zip, "droidboot.img", droidboot)
50    common.ZipWriteStr(info.output_zip, "ifwi.bin", ifwi)
51    WriteIfwi(info)
52    WriteDroidboot(info)
53    return
54
55  offset = header_size;
56  while offset < len(bootloader):
57    c_header_fmt = "<8sIBBBB"
58    c_header_size = struct.calcsize(c_header_fmt)
59    c_magic, size, flags, _, _ , _ = struct.unpack(c_header_fmt, bootloader[offset:offset + c_header_size])
60    buf = bootloader[offset + c_header_size: offset + c_header_size + size]
61    offset += c_header_size + size
62
63    if not flags & 1:
64      continue
65
66    if c_magic == "IFWI!!!!":
67      common.ZipWriteStr(info.output_zip, "ifwi.bin", buf)
68      WriteIfwi(info);
69      continue
70    if c_magic == "DROIDBT!":
71      common.ZipWriteStr(info.output_zip, "droidboot.img", buf)
72      WriteDroidboot(info);
73      continue
74    if c_magic == "SPLASHS!":
75      common.ZipWriteStr(info.output_zip, "splashscreen.img", buf)
76      WriteSplashscreen(info);
77      continue
78
79def FullOTA_InstallEnd(info):
80  try:
81    bootloader_img = info.input_zip.read("RADIO/bootloader.img")
82  except KeyError:
83    print "no bootloader.img in target_files; skipping install"
84  else:
85    WriteBootloader(info, bootloader_img)
86
87
88def IncrementalOTA_InstallEnd(info):
89  try:
90    target_bootloader_img = info.target_zip.read("RADIO/bootloader.img")
91    try:
92      source_bootloader_img = info.source_zip.read("RADIO/bootloader.img")
93    except KeyError:
94      source_bootloader_img = None
95
96    if source_bootloader_img == target_bootloader_img:
97      print "bootloader unchanged; skipping"
98    else:
99      print "bootloader changed; adding it"
100      WriteBootloader(info, target_bootloader_img)
101  except KeyError:
102    print "no bootloader.img in target target_files; skipping install"
103