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 18 import struct 19 import common 20 21 22 def 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 26 def WriteDroidboot(info): 27 info.script.WriteRawImage("/fastboot", "droidboot.img") 28 29 def WriteSplashscreen(info): 30 info.script.WriteRawImage("/splashscreen", "splashscreen.img") 31 32 def 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 79 def 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 88 def 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