You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
401 lines
15 KiB
401 lines
15 KiB
#!/usr/bin/env python
|
|
|
|
import os
|
|
import sys
|
|
import string
|
|
import argparse
|
|
import subprocess
|
|
import tempfile
|
|
|
|
|
|
root_dir = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
|
|
parser = argparse.ArgumentParser(description='Android system files extractor')
|
|
parser.add_argument("-p", "--prefix", metavar="NAME", required=True,
|
|
help="Prefix for stored files, e.g. galaxy-s7-us")
|
|
|
|
|
|
# System files which need to be read with `adb shell cat filename`
|
|
# instead of `adb pull filename`
|
|
SHELL_PREFIX = [
|
|
"/sys/class/kgsl/kgsl-3d0/",
|
|
]
|
|
|
|
SYSTEM_FILES = [
|
|
"/proc/cpuinfo",
|
|
"/system/build.prop",
|
|
"/sys/class/kgsl/kgsl-3d0/bus_split",
|
|
"/sys/class/kgsl/kgsl-3d0/clock_mhz",
|
|
"/sys/class/kgsl/kgsl-3d0/deep_nap_timer",
|
|
"/sys/class/kgsl/kgsl-3d0/default_pwrlevel",
|
|
"/sys/class/kgsl/kgsl-3d0/dev",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/available_frequencies",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/available_governors",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/cur_freq",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/governor",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/gpu_load",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/max_freq",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/min_freq",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/polling_interval",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/suspend_time",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/target_freq",
|
|
"/sys/class/kgsl/kgsl-3d0/devfreq/trans_stat",
|
|
"/sys/class/kgsl/kgsl-3d0/device/op_cpu_table",
|
|
"/sys/class/kgsl/kgsl-3d0/freq_table_mhz",
|
|
"/sys/class/kgsl/kgsl-3d0/ft_fast_hang_detect",
|
|
"/sys/class/kgsl/kgsl-3d0/ft_hang_intr_status",
|
|
"/sys/class/kgsl/kgsl-3d0/ft_long_ib_detect",
|
|
"/sys/class/kgsl/kgsl-3d0/ft_pagefault_policy",
|
|
"/sys/class/kgsl/kgsl-3d0/ft_policy",
|
|
"/sys/class/kgsl/kgsl-3d0/gpu_available_frequencies",
|
|
"/sys/class/kgsl/kgsl-3d0/gpu_busy_percentage",
|
|
"/sys/class/kgsl/kgsl-3d0/gpu_clock_stats",
|
|
"/sys/class/kgsl/kgsl-3d0/gpu_llc_slice_enable",
|
|
"/sys/class/kgsl/kgsl-3d0/gpu_model",
|
|
"/sys/class/kgsl/kgsl-3d0/gpubusy",
|
|
"/sys/class/kgsl/kgsl-3d0/gpuclk",
|
|
"/sys/class/kgsl/kgsl-3d0/gpuhtw_llc_slice_enable",
|
|
"/sys/class/kgsl/kgsl-3d0/hwcg",
|
|
"/sys/class/kgsl/kgsl-3d0/idle_timer",
|
|
"/sys/class/kgsl/kgsl-3d0/lm",
|
|
"/sys/class/kgsl/kgsl-3d0/max_gpuclk",
|
|
"/sys/class/kgsl/kgsl-3d0/max_pwrlevel",
|
|
"/sys/class/kgsl/kgsl-3d0/min_clock_mhz",
|
|
"/sys/class/kgsl/kgsl-3d0/min_pwrlevel",
|
|
"/sys/class/kgsl/kgsl-3d0/num_pwrlevels",
|
|
"/sys/class/kgsl/kgsl-3d0/pmqos_active_latency",
|
|
"/sys/class/kgsl/kgsl-3d0/popp",
|
|
"/sys/class/kgsl/kgsl-3d0/preempt_count",
|
|
"/sys/class/kgsl/kgsl-3d0/preempt_level",
|
|
"/sys/class/kgsl/kgsl-3d0/preemption",
|
|
"/sys/class/kgsl/kgsl-3d0/pwrscale",
|
|
"/sys/class/kgsl/kgsl-3d0/reset_count",
|
|
"/sys/class/kgsl/kgsl-3d0/skipsaverestore",
|
|
"/sys/class/kgsl/kgsl-3d0/sptp_pc",
|
|
"/sys/class/kgsl/kgsl-3d0/thermal_pwrlevel",
|
|
"/sys/class/kgsl/kgsl-3d0/throttling",
|
|
"/sys/class/kgsl/kgsl-3d0/usesgmem",
|
|
"/sys/class/kgsl/kgsl-3d0/wake_nice",
|
|
"/sys/class/kgsl/kgsl-3d0/wake_timeout",
|
|
"/sys/devices/soc0/accessory_chip",
|
|
"/sys/devices/soc0/build_id",
|
|
"/sys/devices/soc0/chip_family",
|
|
"/sys/devices/soc0/chip_name",
|
|
"/sys/devices/soc0/family",
|
|
"/sys/devices/soc0/foundry_id",
|
|
"/sys/devices/soc0/hw_platform",
|
|
"/sys/devices/soc0/image_crm_version",
|
|
"/sys/devices/soc0/image_variant",
|
|
"/sys/devices/soc0/image_version",
|
|
"/sys/devices/soc0/images",
|
|
"/sys/devices/soc0/machine",
|
|
"/sys/devices/soc0/ncluster_array_offset",
|
|
"/sys/devices/soc0/ndefective_parts_array_offset",
|
|
"/sys/devices/soc0/nmodem_supported",
|
|
"/sys/devices/soc0/nproduct_id",
|
|
"/sys/devices/soc0/num_clusters",
|
|
"/sys/devices/soc0/num_defective_parts",
|
|
"/sys/devices/soc0/platform_subtype",
|
|
"/sys/devices/soc0/platform_subtype_id",
|
|
"/sys/devices/soc0/platform_version",
|
|
"/sys/devices/soc0/pmic_die_revision",
|
|
"/sys/devices/soc0/pmic_model",
|
|
"/sys/devices/soc0/raw_device_family",
|
|
"/sys/devices/soc0/raw_device_number",
|
|
"/sys/devices/soc0/raw_id",
|
|
"/sys/devices/soc0/raw_version",
|
|
"/sys/devices/soc0/revision",
|
|
"/sys/devices/soc0/select_image",
|
|
"/sys/devices/soc0/serial_number",
|
|
"/sys/devices/soc0/soc_id",
|
|
"/sys/devices/soc0/vendor",
|
|
"/sys/devices/system/b.L/big_threads",
|
|
"/sys/devices/system/b.L/boot_cluster",
|
|
"/sys/devices/system/b.L/core_status",
|
|
"/sys/devices/system/b.L/little_threads",
|
|
"/sys/devices/system/b.L/down_migrations",
|
|
"/sys/devices/system/b.L/up_migrations",
|
|
"/sys/devices/system/cpu/isolated",
|
|
"/sys/devices/system/cpu/kernel_max",
|
|
"/sys/devices/system/cpu/modalias",
|
|
"/sys/devices/system/cpu/offline",
|
|
"/sys/devices/system/cpu/online",
|
|
"/sys/devices/system/cpu/possible",
|
|
"/sys/devices/system/cpu/present",
|
|
"/sys/devices/system/cpu/sched_isolated",
|
|
"/sys/devices/system/cpu/clusterhotplug/cur_hstate",
|
|
"/sys/devices/system/cpu/clusterhotplug/down_freq",
|
|
"/sys/devices/system/cpu/clusterhotplug/down_tasks",
|
|
"/sys/devices/system/cpu/clusterhotplug/down_threshold",
|
|
"/sys/devices/system/cpu/clusterhotplug/sampling_rate",
|
|
"/sys/devices/system/cpu/clusterhotplug/time_in_state",
|
|
"/sys/devices/system/cpu/clusterhotplug/up_freq",
|
|
"/sys/devices/system/cpu/clusterhotplug/up_tasks",
|
|
"/sys/devices/system/cpu/clusterhotplug/up_threshold",
|
|
"/sys/devices/system/cpu/cpufreq/all_time_in_state",
|
|
"/sys/devices/system/cpu/cpufreq/current_in_state",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/big_cpu_num",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/big_max_freq",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/big_min_freq",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/hmp_boost_type",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/hmp_prev_boost_type",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_cpu_num",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_divider",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_max_freq",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_min_freq",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_min_lock",
|
|
"/sys/devices/system/cpu/cpufreq/cpufreq_limit/requests",
|
|
"/sys/devices/system/cpu/cpuidle/current_driver",
|
|
"/sys/devices/system/cpu/cpuidle/current_governor_ro",
|
|
"/sys/devices/system/cpu/cputopo/cpus_per_cluster",
|
|
"/sys/devices/system/cpu/cputopo/big_cpumask",
|
|
"/sys/devices/system/cpu/cputopo/glbinfo",
|
|
"/sys/devices/system/cpu/cputopo/is_big_little",
|
|
"/sys/devices/system/cpu/cputopo/is_multi_cluster",
|
|
"/sys/devices/system/cpu/cputopo/little_cpumask",
|
|
"/sys/devices/system/cpu/cputopo/nr_clusters",
|
|
"/sys/devices/system/sched/idle_prefer",
|
|
"/sys/devices/system/sched/sched_boost",
|
|
]
|
|
|
|
CPU_FILES = [
|
|
"core_ctl/active_cpus",
|
|
"core_ctl/busy_up_thres",
|
|
"core_ctl/busy_down_thres",
|
|
"core_ctl/enable",
|
|
"core_ctl/global_state",
|
|
"core_ctl/is_big_cluster",
|
|
"core_ctl/max_cpus",
|
|
"core_ctl/min_cpus",
|
|
"core_ctl/need_cpus",
|
|
"core_ctl/not_preferred",
|
|
"core_ctl/offline_delay_ms",
|
|
"core_ctl/task_thres",
|
|
"current_driver",
|
|
"current_governor_ro",
|
|
"cpuidle/driver/name",
|
|
"cpufreq/affected_cpus",
|
|
"cpufreq/cpuinfo_max_freq",
|
|
"cpufreq/cpuinfo_min_freq",
|
|
"cpufreq/cpuinfo_transition_latency",
|
|
"cpufreq/related_cpus",
|
|
"cpufreq/scaling_available_frequencies",
|
|
"cpufreq/scaling_available_governors",
|
|
"cpufreq/scaling_cur_freq",
|
|
"cpufreq/scaling_driver",
|
|
"cpufreq/scaling_governor",
|
|
"cpufreq/scaling_max_freq",
|
|
"cpufreq/scaling_min_freq",
|
|
"cpufreq/sched/down_throttle_nsec",
|
|
"cpufreq/sched/up_throttle_nsec",
|
|
"cpufreq/stats/time_in_state",
|
|
"cpufreq/stats/total_trans",
|
|
"cpufreq/stats/trans_table",
|
|
"isolate",
|
|
"regs/identification/midr_el1",
|
|
"regs/identification/revidr_el1",
|
|
"sched_load_boost",
|
|
"topology/core_id",
|
|
"topology/core_siblings",
|
|
"topology/core_siblings_list",
|
|
"topology/cpu_capacity",
|
|
"topology/max_cpu_capacity",
|
|
"topology/physical_package_id",
|
|
"topology/thread_siblings",
|
|
"topology/thread_siblings_list",
|
|
]
|
|
|
|
CACHE_FILES = [
|
|
"allocation_policy",
|
|
"coherency_line_size",
|
|
"level",
|
|
"number_of_sets",
|
|
"shared_cpu_list",
|
|
"shared_cpu_map",
|
|
"size",
|
|
"type",
|
|
"ways_of_associativity",
|
|
"write_policy",
|
|
]
|
|
|
|
def c_escape(string):
|
|
c_string = ""
|
|
for c in string:
|
|
if c == "\\":
|
|
c_string += "\\\\"
|
|
elif c == "\"":
|
|
c_string += "\\\""
|
|
elif c == "\t":
|
|
c_string += "\\t"
|
|
elif c == "\n":
|
|
c_string += "\\n"
|
|
elif c == "\r":
|
|
c_string += "\\r"
|
|
elif ord(c) == 0:
|
|
c_string += "\\0"
|
|
elif 32 <= ord(c) < 127:
|
|
c_string += c
|
|
else:
|
|
c_string += "x%02X" % ord(c)
|
|
return c_string
|
|
|
|
def adb_shell(commands):
|
|
env = os.environ.copy()
|
|
env["LC_ALL"] = "C"
|
|
|
|
adb = subprocess.Popen(["adb", "shell"] + commands, env=env, stdout=subprocess.PIPE)
|
|
stdout, _ = adb.communicate()
|
|
if adb.returncode == 0:
|
|
return stdout
|
|
|
|
def adb_push(local_path, device_path):
|
|
env = os.environ.copy()
|
|
env["LC_ALL"] = "C"
|
|
|
|
adb = subprocess.Popen(["adb", "push", local_path, device_path], env=env)
|
|
adb.communicate()
|
|
return adb.returncode == 0
|
|
|
|
def adb_pull(device_path, local_path):
|
|
if any(device_path.startswith(prefix) for prefix in SHELL_PREFIX):
|
|
content = adb_shell(["cat", device_path])
|
|
if content is not None:
|
|
if not content.rstrip().endswith("No such file or directory"):
|
|
with open(local_path, "wb") as local_file:
|
|
local_file.write(content)
|
|
return True
|
|
else:
|
|
env = os.environ.copy()
|
|
env["LC_ALL"] = "C"
|
|
|
|
adb = subprocess.Popen(["adb", "pull", device_path, local_path], env=env)
|
|
adb.communicate()
|
|
return adb.returncode == 0
|
|
|
|
def adb_getprop():
|
|
properties = adb_shell(["getprop"])
|
|
properties_list = list()
|
|
while properties:
|
|
assert properties.startswith("[")
|
|
properties = properties[1:]
|
|
key, properties = properties.split("]", 1)
|
|
properties = properties.strip()
|
|
assert properties.startswith(":")
|
|
properties = properties[1:].strip()
|
|
assert properties.startswith("[")
|
|
properties = properties[1:]
|
|
value, properties = properties.split("]", 1)
|
|
properties = properties.strip()
|
|
properties_list.append((key, value))
|
|
return properties_list
|
|
|
|
def add_mock_file(stream, path, content):
|
|
assert content is not None
|
|
stream.write("\t{\n")
|
|
stream.write("\t\t.path = \"%s\",\n" % path)
|
|
stream.write("\t\t.size = %d,\n" % len(content))
|
|
if len(content.splitlines()) > 1:
|
|
stream.write("\t\t.content =")
|
|
for line in content.splitlines(True):
|
|
stream.write("\n\t\t\t\"%s\"" % c_escape(line))
|
|
stream.write(",\n")
|
|
else:
|
|
stream.write("\t\t.content = \"%s\",\n" % c_escape(content))
|
|
stream.write("\t},\n")
|
|
|
|
|
|
def dump_device_file(stream, path, prefix_line=None):
|
|
temp_fd, temp_path = tempfile.mkstemp()
|
|
os.close(temp_fd)
|
|
try:
|
|
if adb_pull(path, temp_path):
|
|
with open(temp_path, "rb") as temp_file:
|
|
content = temp_file.read()
|
|
if prefix_line is not None:
|
|
stream.write(prefix_line)
|
|
add_mock_file(stream, path, content)
|
|
return content
|
|
finally:
|
|
if os.path.exists(temp_path):
|
|
os.remove(temp_path)
|
|
|
|
|
|
def main(args):
|
|
options = parser.parse_args(args)
|
|
|
|
dmesg_content = adb_shell(["dmesg"])
|
|
if dmesg_content is not None and dmesg_content.strip() == "klogctl: Operation not permitted":
|
|
dmesg_content = None
|
|
if dmesg_content is not None:
|
|
with open(os.path.join("test", "dmesg", options.prefix + ".log"), "w") as dmesg_dump:
|
|
dmesg_dump.write(dmesg_content)
|
|
|
|
build_prop_content = None
|
|
proc_cpuinfo_content = None
|
|
proc_cpuinfo_content32 = None
|
|
kernel_max = 0
|
|
with open(os.path.join("test", "mock", options.prefix + ".h"), "w") as file_header:
|
|
file_header.write("struct cpuinfo_mock_file filesystem[] = {\n")
|
|
android_props = adb_getprop()
|
|
abi = None
|
|
for key, value in android_props:
|
|
if key == "ro.product.cpu.abi":
|
|
abi = value
|
|
for path in SYSTEM_FILES:
|
|
arm64_prefix = None
|
|
if path == "/proc/cpuinfo" and abi == "arm64-v8a":
|
|
arm64_prefix = "#if CPUINFO_ARCH_ARM64\n"
|
|
content = dump_device_file(file_header, path, prefix_line=arm64_prefix)
|
|
if content is not None:
|
|
if path == "/proc/cpuinfo":
|
|
proc_cpuinfo_content = content
|
|
elif path == "/system/build.prop":
|
|
build_prop_content = content
|
|
elif path == "/sys/devices/system/cpu/kernel_max":
|
|
kernel_max = int(content.strip())
|
|
if arm64_prefix:
|
|
cpuinfo_dump_binary = os.path.join(root_dir, "..", "build", "android", "armeabi-v7a", "cpuinfo-dump")
|
|
assert os.path.isfile(cpuinfo_dump_binary)
|
|
adb_push(cpuinfo_dump_binary, "/data/local/tmp/cpuinfo-dump")
|
|
proc_cpuinfo_content32 = adb_shell(["/data/local/tmp/cpuinfo-dump"])
|
|
if proc_cpuinfo_content32:
|
|
proc_cpuinfo_content32 = "\n".join(proc_cpuinfo_content32.splitlines())
|
|
file_header.write("#elif CPUINFO_ARCH_ARM\n")
|
|
add_mock_file(file_header, "/proc/cpuinfo", proc_cpuinfo_content32)
|
|
file_header.write("#endif\n")
|
|
|
|
for cpu in range(kernel_max + 1):
|
|
for filename in CPU_FILES:
|
|
path = "/sys/devices/system/cpu/cpu%d/%s" % (cpu, filename)
|
|
dump_device_file(file_header, path)
|
|
for index in range(5):
|
|
for filename in CACHE_FILES:
|
|
path = "/sys/devices/system/cpu/cpu%d/cache/index%d/%s" % (cpu, index, filename)
|
|
dump_device_file(file_header, path)
|
|
file_header.write("\t{ NULL },\n")
|
|
file_header.write("};\n")
|
|
file_header.write("#ifdef __ANDROID__\n")
|
|
file_header.write("struct cpuinfo_mock_property properties[] = {\n")
|
|
for key, value in android_props:
|
|
file_header.write("\t{\n")
|
|
file_header.write("\t\t.key = \"%s\",\n" % c_escape(key))
|
|
file_header.write("\t\t.value = \"%s\",\n" % c_escape(value))
|
|
file_header.write("\t},\n")
|
|
file_header.write("\t{ NULL },\n")
|
|
file_header.write("};\n")
|
|
file_header.write("#endif /* __ANDROID__ */\n")
|
|
|
|
if proc_cpuinfo_content is not None:
|
|
with open(os.path.join("test", "cpuinfo", options.prefix + ".log"), "w") as proc_cpuinfo_dump:
|
|
proc_cpuinfo_dump.write(proc_cpuinfo_content)
|
|
if proc_cpuinfo_content32 is not None:
|
|
with open(os.path.join("test", "cpuinfo", options.prefix + ".armeabi.log"), "w") as proc_cpuinfo_dump32:
|
|
proc_cpuinfo_dump32.write(proc_cpuinfo_content32)
|
|
if build_prop_content is not None:
|
|
with open(os.path.join("test", "build.prop", options.prefix + ".log"), "w") as build_prop_dump:
|
|
build_prop_dump.write(build_prop_content)
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv[1:])
|