diff options
author | Doug Zongker <dougz@android.com> | 2010-09-20 18:04:41 -0700 |
---|---|---|
committer | Doug Zongker <dougz@android.com> | 2010-09-21 09:55:29 -0700 |
commit | 258bf46ea6bb4f25d01fab1b783238589e5bbec4 (patch) | |
tree | 62bff5a39c435132ba74e5830ac98716735fc386 | |
parent | 1020d271c67b062e95b61c4eb9f1f5168e2b6197 (diff) | |
download | build-258bf46ea6bb4f25d01fab1b783238589e5bbec4.zip build-258bf46ea6bb4f25d01fab1b783238589e5bbec4.tar.gz build-258bf46ea6bb4f25d01fab1b783238589e5bbec4.tar.bz2 |
support for per-partition fs_type (do not merge)
Include the recovery.fstab file in the recovery image. Remove the
global fs_type and partition_type values from the target-files
key/value dict, and parse the recovery.fstab file instead to find
types for each partition.
Change-Id: I35ee2dd0989441dc2a704b63c1b32e598049acb5
-rw-r--r-- | core/Makefile | 16 | ||||
-rw-r--r-- | tools/releasetools/common.py | 56 | ||||
-rw-r--r-- | tools/releasetools/edify_generator.py | 99 | ||||
-rwxr-xr-x | tools/releasetools/img_from_target_files | 9 | ||||
-rwxr-xr-x | tools/releasetools/ota_from_target_files | 12 |
5 files changed, 134 insertions, 58 deletions
diff --git a/core/Makefile b/core/Makefile index a97d8bf..df7566b 100644 --- a/core/Makefile +++ b/core/Makefile @@ -601,11 +601,16 @@ recovery_resources_common := $(call include-path-for, recovery)/res recovery_resources_private := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery/res)) recovery_resource_deps := $(shell find $(recovery_resources_common) \ $(recovery_resources_private) -type f) +recovery_fstab := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery.fstab)) ifeq ($(recovery_resources_private),) $(info No private recovery resources for TARGET_DEVICE $(TARGET_DEVICE)) endif +ifeq ($(recovery_fstab),) + $(info No recovery.fstab for TARGET_DEVICE $(TARGET_DEVICE)) +endif + INTERNAL_RECOVERYIMAGE_ARGS := \ $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \ --kernel $(recovery_kernel) \ @@ -663,6 +668,8 @@ $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \ cp -rf $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/ $(foreach item,$(recovery_resources_private), \ cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/) + $(foreach item,$(recovery_fstab), \ + cp -f $(item) $(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab) cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \ > $(TARGET_RECOVERY_ROOT_OUT)/default.prop @@ -1011,15 +1018,6 @@ endif ifdef BOARD_USERDATAIMAGE_PARTITION_SIZE $(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt endif -ifneq (,$(INTERNAL_USERIMAGES_EXT_VARIANT)) - $(hide) echo "fs_type=$(INTERNAL_USERIMAGES_EXT_VARIANT)" >> $(zip_root)/META/misc_info.txt - $(hide) echo "partition_type=EMMC" >> $(zip_root)/META/misc_info.txt - @# TODO: where is the right place to get this path from? BoardConfig.mk? - $(hide) echo "partition_path=/dev/block/platform/sdhci-tegra.3/by-name/" >> $(zip_root)/META/misc_info.txt -else - $(hide) echo "fs_type=yaffs2" >> $(zip_root)/META/misc_info.txt - $(hide) echo "partition_type=MTD" >> $(zip_root)/META/misc_info.txt -endif $(hide) echo "tool_extensions=$(tool_extensions)" >> $(zip_root)/META/misc_info.txt ifdef mkyaffs2_extra_flags $(hide) echo "mkyaffs2_extra_flags=$(mkyaffs2_extra_flags)" >> $(zip_root)/META/misc_info.txt diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 31e86a1..be8333b 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -72,9 +72,6 @@ def LoadInfoDict(zip): # ok if misc_info.txt doesn't exist pass - if "fs_type" not in d: d["fs_type"] = "yaffs2" - if "partition_type" not in d: d["partition_type"] = "MTD" - # backwards compatibility: These values used to be in their own # files. Look for them, in case we're processing an old # target_files zip. @@ -123,8 +120,45 @@ def LoadInfoDict(zip): makeint("recovery_size") makeint("boot_size") + d["fstab"] = LoadRecoveryFSTab(zip) + if not d["fstab"]: + if "fs_type" not in d: d["fs_type"] = "yaffs2" + if "partition_type" not in d: d["partition_type"] = "MTD" + return d +def LoadRecoveryFSTab(zip): + class Partition(object): + pass + + try: + data = zip.read("RECOVERY/RAMDISK/etc/recovery.fstab") + except KeyError: + # older target-files that doesn't have a recovery.fstab; fall back + # to the fs_type and partition_type keys. + return + + d = {} + for line in data.split("\n"): + line = line.strip() + if not line or line.startswith("#"): continue + pieces = line.split() + if not (3 <= len(pieces) <= 4): + raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,)) + + p = Partition() + p.mount_point = pieces[0] + p.fs_type = pieces[1] + p.device = pieces[2] + if len(pieces) == 4: + p.device2 = pieces[3] + else: + p.device2 = None + + d[p.mount_point] = p + return d + + def DumpInfoDict(d): for k, v in sorted(d.items()): print "%-25s = (%s) %s" % (k, type(v).__name__, v) @@ -308,12 +342,18 @@ def CheckSize(data, target, info_dict): any, for the given target. Raise exception if the data is too big. Print a warning if the data is nearing the maximum size.""" - fs_type = info_dict.get("fs_type", None) - if not fs_type: return - if target.endswith(".img"): target = target[:-4] - limit = info_dict.get(target + "_size", None) - if limit is None: return + mount_point = "/" + target + + if info_dict["fstab"]: + if mount_point == "/userdata": mount_point = "/data" + p = info_dict["fstab"][mount_point] + fs_type = p.fs_type + limit = info_dict.get(p.device + "_size", None) + else: + fs_type = info_dict.get("fs_type", None) + limit = info_dict.get(target + "_size", None) + if not fs_type or not limit: return if fs_type == "yaffs2": # image size should be increased by 1/64th to account for the diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py index 390bd4b..012c06a 100644 --- a/tools/releasetools/edify_generator.py +++ b/tools/releasetools/edify_generator.py @@ -21,6 +21,9 @@ class EdifyGenerator(object): """Class to generate scripts in the 'edify' recovery script language used from donut onwards.""" + # map recovery.fstab's fs_types to mount/format "partition types" + PARTITION_TYPES = { "yaffs2": "MTD", "mtd": "MTD", "ext4": "EMMC" } + def __init__(self, version, info): self.script = [] self.mounts = set() @@ -131,15 +134,22 @@ class EdifyGenerator(object): available on /cache.""" self.script.append("assert(apply_patch_space(%d));" % (amount,)) - def Mount(self, what, mount_point): - """Mount the given 'what' at the given path. 'what' should be a - partition name for an MTD partition, or a block device for - anything else.""" - what = self.info.get("partition_path", "") + what - self.script.append('mount("%s", "%s", "%s", "%s");' % - (self.info["fs_type"], self.info["partition_type"], - what, mount_point)) - self.mounts.add(mount_point) + def Mount(self, mount_point): + """Mount the partition with the given mount_point.""" + fstab = self.info.get("fstab", None) + if fstab: + p = fstab[mount_point] + self.script.append('mount("%s", "%s", "%s", "%s");' % + (p.fs_type, self.PARTITION_TYPES[p.fs_type], + p.device, p.mount_point)) + self.mounts.add(p.mount_point) + else: + what = mount_point.lstrip("/") + what = self.info.get("partition_path", "") + what + self.script.append('mount("%s", "%s", "%s", "%s");' % + (self.info["fs_type"], self.info["partition_type"], + what, mount_point)) + self.mounts.add(mount_point) def UnpackPackageDir(self, src, dst): """Unpack a given directory from the OTA package into the given @@ -158,11 +168,20 @@ class EdifyGenerator(object): self.script.append('ui_print("%s");' % (message,)) def FormatPartition(self, partition): - """Format the given partition.""" - partition = self.info.get("partition_path", "") + partition - self.script.append('format("%s", "%s", "%s");' % - (self.info["fs_type"], self.info["partition_type"], - partition)) + """Format the given partition, specified by its mount point (eg, + "/system").""" + + fstab = self.info.get("fstab", None) + if fstab: + p = fstab[partition] + self.script.append('format("%s", "%s", "%s");' % + (p.fs_type, self.PARTITION_TYPES[p.fs_type], p.device)) + else: + # older target-files without per-partition types + partition = self.info.get("partition_path", "") + partition + self.script.append('format("%s", "%s", "%s");' % + (self.info["fs_type"], self.info["partition_type"], + partition)) def DeleteFiles(self, file_list): """Delete all files in file_list.""" @@ -196,24 +215,42 @@ class EdifyGenerator(object): self.script.append( 'write_firmware_image("PACKAGE:%s", "%s");' % (fn, kind)) - def WriteRawImage(self, partition, fn): - """Write the given package file into the given partition.""" - - if self.info["partition_type"] == "MTD": - self.script.append( - ('assert(package_extract_file("%(fn)s", "/tmp/%(partition)s.img"),\n' - ' write_raw_image("/tmp/%(partition)s.img", "%(partition)s"),\n' - ' delete("/tmp/%(partition)s.img"));') - % {'partition': partition, 'fn': fn}) - elif self.info["partition_type"] == "EMMC": - self.script.append( - ('package_extract_file("%(fn)s", "%(dir)s%(partition)s");') - % {'partition': partition, 'fn': fn, - 'dir': self.info.get("partition_path", ""), - }) + def WriteRawImage(self, mount_point, fn): + """Write the given package file into the partition for the given + mount point.""" + + fstab = self.info["fstab"] + if fstab: + p = fstab[mount_point] + partition_type = self.PARTITION_TYPES[p.fs_type] + args = {'device': p.device, 'fn': fn} + if partition_type == "MTD": + self.script.append( + ('assert(package_extract_file("%(fn)s", "/tmp/%(device)s.img"),\n' + ' write_raw_image("/tmp/%(device)s.img", "%(device)s"),\n' + ' delete("/tmp/%(device)s.img"));') % args) + elif partition_type == "EMMC": + 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,)) else: - raise ValueError("don't know how to write \"%s\" partitions" % - (self.info["partition_type"],)) + # backward compatibility with older target-files that lack recovery.fstab + if self.info["partition_type"] == "MTD": + self.script.append( + ('assert(package_extract_file("%(fn)s", "/tmp/%(partition)s.img"),\n' + ' write_raw_image("/tmp/%(partition)s.img", "%(partition)s"),\n' + ' delete("/tmp/%(partition)s.img"));') + % {'partition': partition, 'fn': fn}) + elif self.info["partition_type"] == "EMMC": + self.script.append( + ('package_extract_file("%(fn)s", "%(dir)s%(partition)s");') + % {'partition': partition, 'fn': fn, + 'dir': self.info.get("partition_path", ""), + }) + else: + raise ValueError("don't know how to write \"%s\" partitions" % + (self.info["partition_type"],)) def SetPermissions(self, fn, uid, gid, mode): """Set file ownership and permissions.""" diff --git a/tools/releasetools/img_from_target_files b/tools/releasetools/img_from_target_files index d734ad0..2a0e4cc 100755 --- a/tools/releasetools/img_from_target_files +++ b/tools/releasetools/img_from_target_files @@ -61,9 +61,10 @@ def AddUserdata(output_zip): img = tempfile.NamedTemporaryFile() build_command = [] - if OPTIONS.info_dict.get("fs_type", "").startswith("ext"): + if OPTIONS.info_dict["fstab"]["/data"].fs_type.startswith("ext"): build_command = ["mkuserimg.sh", - user_dir, img.name, OPTIONS.info_dict["fs_type"], "userdata"] + user_dir, img.name, + OPTIONS.info_dict["fstab"]["/data"].fs_type, "userdata"] if "userdata_size" in OPTIONS.info_dict: build_command.append(str(OPTIONS.info_dict["userdata_size"])) else: @@ -108,10 +109,10 @@ def AddSystem(output_zip): pass build_command = [] - if OPTIONS.info_dict.get("fs_type", "").startswith("ext"): + if OPTIONS.info_dict["fstab"]["/system"].fs_type.startswith("ext"): build_command = ["mkuserimg.sh", os.path.join(OPTIONS.input_tmp, "system"), img.name, - OPTIONS.info_dict["fs_type"], "system"] + OPTIONS.info_dict["fstab"]["/system"].fs_type, "system"] if "system_img" in OPTIONS.info_dict: build_command.append(str(OPTIONS.info_dict["system_size"])) else: diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files index 37715bc..320c6fc 100755 --- a/tools/releasetools/ota_from_target_files +++ b/tools/releasetools/ota_from_target_files @@ -363,10 +363,10 @@ def WriteFullOTAPackage(input_zip, output_zip): script.ShowProgress(0.5, 0) if OPTIONS.wipe_user_data: - script.FormatPartition("userdata") + script.FormatPartition("/data") - script.FormatPartition("system") - script.Mount("system", "/system") + script.FormatPartition("/system") + script.Mount("/system") script.UnpackPackageDir("recovery", "/system") script.UnpackPackageDir("system", "/system") @@ -387,7 +387,7 @@ def WriteFullOTAPackage(input_zip, output_zip): script.ShowProgress(0.2, 0) script.ShowProgress(0.2, 10) - script.WriteRawImage("boot", "boot.img") + script.WriteRawImage("/boot", "boot.img") script.ShowProgress(0.1, 0) device_specific.FullOTA_InstallEnd() @@ -500,7 +500,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): metadata["pre-build"] = source_fp metadata["post-build"] = target_fp - script.Mount("system", "/system") + script.Mount("/system") script.AssertSomeFingerprint(source_fp, target_fp) source_boot = common.File("/tmp/boot.img", @@ -564,7 +564,7 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): if OPTIONS.wipe_user_data: script.Print("Erasing user data...") - script.FormatPartition("userdata") + script.FormatPartition("/data") script.Print("Removing unneeded files...") script.DeleteFiles(["/"+i[0] for i in verbatim_targets] + |