zoukankan      html  css  js  c++  java
  • android OTA package packing and extract to partition

    android OTA package packing and extract to partition

    1. 打包image并将写image到对应partition的命令写入OTA升级脚本里

    device/google/dragon/releasetools.py

    def FullOTA_InstallEnd(info):
      # copy the data into the package.
      try:
        bootloader_img = info.input_zip.read("RADIO/bootloader.img")
        ec_img = info.input_zip.read("RADIO/ec.bin")
      except KeyError:
        print "no firmware images in target_files; skipping install"
        return
      # copy the data into the package.
      common.ZipWriteStr(info.output_zip, "bootloader.img", bootloader_img) #应该是将bootloader.img打包到OTA package
      common.ZipWriteStr(info.output_zip, "ec.bin", ec_img)
    
      # emit the script code to trigger the firmware updater on the device
      info.script.AppendExtra(
        """dragon.firmware_update(package_extract_file("bootloader.img"), package_extract_file("ec.bin"));""")

    build/tools/releasetools/edify_generator.py

      def AppendExtra(self, extra):
        """Append text verbatim to the output script."""
        self.script.append(extra)
    self.script.append()应该是将package_extract_file命令写入一个OTA升级脚本里,这个脚本最终的样子类似于:
    https://www.cnblogs.com/aspirs/p/13060333.html
    在升级OTA package会执行这个命令将文件写入partition

    build/tools/releasetools/edify_generator.py

      def WriteRawImage(self, mount_point, fn, mapfn=None):
        """Write the given package file into the partition for the given
        mount point."""
    
        fstab = self.fstab
        if fstab:
          p = fstab[mount_point]
          partition_type = common.PARTITION_TYPES[p.fs_type]
          args = {'device': p.device, 'fn': fn}
          if partition_type == "EMMC":
            if mapfn:
              args["map"] = mapfn
              self.script.append(
                  'package_extract_file("%(fn)s", "%(device)s", "%(map)s");' % args)
            else:
              self.script.append(
                  'package_extract_file("%(fn)s", "%(device)s");' % args)
          else:
            raise ValueError(
                "don't know how to write "%s" partitions" % p.fs_type)

    2. 将image写到partition

    bootable/recovery/updater/install.cpp

    Value* PackageExtractFileFn(const char* name, State* state,
                                const std::vector<std::unique_ptr<Expr>>& argv) {
      if (argv.size() < 1 || argv.size() > 2) {
        return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 or 2 args, got %zu", name,
                          argv.size());
      }
    
      if (argv.size() == 2) {
        // The two-argument version extracts to a file.
    
        std::vector<std::string> args;
        if (!ReadArgs(state, argv, &args)) {
          return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %zu args", name,
                            argv.size());
        }
        const std::string& zip_path = args[0]; //bin name
        const std::string& dest_path = args[1]; //device name
    
        ZipArchiveHandle za = static_cast<UpdaterInfo*>(state->cookie)->package_zip;
        ZipString zip_string_path(zip_path.c_str());
        ZipEntry entry;
        if (FindEntry(za, zip_string_path, &entry) != 0) {
          LOG(ERROR) << name << ": no " << zip_path << " in package";
          return StringValue("");
        }
    
        unique_fd fd(TEMP_FAILURE_RETRY(
            ota_open(dest_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)));
        if (fd == -1) {
          PLOG(ERROR) << name << ": can't open " << dest_path << " for write";
          return StringValue("");
        }
    
        bool success = true;
        int32_t ret = ExtractEntryToFile(za, &entry, fd); //fd是device name对应的fd,从zip package za里抽取bin name对应的entry写到fd(device name)
        if (ret != 0) {
          LOG(ERROR) << name << ": Failed to extract entry "" << zip_path << "" ("
                     << entry.uncompressed_length << " bytes) to "" << dest_path
                     << "": " << ErrorCodeString(ret);
          success = false;
        }
        if (ota_fsync(fd) == -1) {
          PLOG(ERROR) << "fsync of "" << dest_path << "" failed";
          success = false;
        }
        if (ota_close(fd) == -1) {
          PLOG(ERROR) << "close of "" << dest_path << "" failed";
          success = false;
        }
    
        return StringValue(success ? "t" : "");
      } else {
        // The one-argument version returns the contents of the file as the result.
    
        std::vector<std::string> args;
        if (!ReadArgs(state, argv, &args)) {
          return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %zu args", name,
                            argv.size());
        }
        const std::string& zip_path = args[0];
    
        ZipArchiveHandle za = static_cast<UpdaterInfo*>(state->cookie)->package_zip;
        ZipString zip_string_path(zip_path.c_str());
        ZipEntry entry;
        if (FindEntry(za, zip_string_path, &entry) != 0) {
          return ErrorAbort(state, kPackageExtractFileFailure, "%s(): no %s in package", name,
                            zip_path.c_str());
        }
    
        std::string buffer;
        buffer.resize(entry.uncompressed_length);
    
        int32_t ret =
            ExtractToMemory(za, &entry, reinterpret_cast<uint8_t*>(&buffer[0]), buffer.size());
        if (ret != 0) {
          return ErrorAbort(state, kPackageExtractFileFailure,
                            "%s: Failed to extract entry "%s" (%zu bytes) to memory: %s", name,
                            zip_path.c_str(), buffer.size(), ErrorCodeString(ret));
        }
    
        return new Value(VAL_BLOB, buffer);
      }
    }

    bootable/recovery/updater/install.cpp

    void RegisterInstallFunctions() {
      RegisterFunction("mount", MountFn);
      RegisterFunction("is_mounted", IsMountedFn);
      RegisterFunction("unmount", UnmountFn);
      RegisterFunction("format", FormatFn);
      RegisterFunction("show_progress", ShowProgressFn);
      RegisterFunction("set_progress", SetProgressFn);
      RegisterFunction("package_extract_file", PackageExtractFileFn);
    
      RegisterFunction("getprop", GetPropFn);
      RegisterFunction("file_getprop", FileGetPropFn);
    
      RegisterFunction("apply_patch", ApplyPatchFn);
      RegisterFunction("apply_patch_check", ApplyPatchCheckFn);
      RegisterFunction("apply_patch_space", ApplyPatchSpaceFn);
    
      RegisterFunction("wipe_block_device", WipeBlockDeviceFn);
    
      RegisterFunction("read_file", ReadFileFn);
      RegisterFunction("sha1_check", Sha1CheckFn);
      RegisterFunction("write_value", WriteValueFn);
    
      RegisterFunction("wipe_cache", WipeCacheFn);
    
      RegisterFunction("ui_print", UIPrintFn);
    
      RegisterFunction("run_program", RunProgramFn);
    
      RegisterFunction("reboot_now", RebootNowFn);
      RegisterFunction("get_stage", GetStageFn);
      RegisterFunction("set_stage", SetStageFn);
    
      RegisterFunction("enable_reboot", EnableRebootFn);
      RegisterFunction("tune2fs", Tune2FsFn);
    }
  • 相关阅读:
    【初学EXT】布局练习
    创建型模式总结(补充UML类图)
    数据库基本概念总结
    Word2010操作技巧总结
    VMWare虚拟机磁盘压缩和上网总结
    第一次用word2010发布文章到博客园记
    设计模式学习总结一原则及创建型模式
    为什么要开始写blog?
    Delphi异常处理总结
    设计模式总结之行为型模式
  • 原文地址:https://www.cnblogs.com/aspirs/p/13060738.html
Copyright © 2011-2022 走看看