• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2
3import os
4import sys
5import string
6import argparse
7import subprocess
8import tempfile
9
10
11root_dir = os.path.abspath(os.path.dirname(__file__))
12
13
14parser = argparse.ArgumentParser(description='Android system files extractor')
15parser.add_argument("-p", "--prefix", metavar="NAME", required=True,
16                    help="Prefix for stored files, e.g. galaxy-s7-us")
17
18
19# System files which need to be read with `adb shell cat filename`
20# instead of `adb pull filename`
21SHELL_PREFIX = [
22    "/sys/class/kgsl/kgsl-3d0/",
23]
24
25SYSTEM_FILES = [
26    "/proc/cpuinfo",
27    "/system/build.prop",
28    "/sys/class/kgsl/kgsl-3d0/bus_split",
29    "/sys/class/kgsl/kgsl-3d0/clock_mhz",
30    "/sys/class/kgsl/kgsl-3d0/deep_nap_timer",
31    "/sys/class/kgsl/kgsl-3d0/default_pwrlevel",
32    "/sys/class/kgsl/kgsl-3d0/dev",
33    "/sys/class/kgsl/kgsl-3d0/devfreq/available_frequencies",
34    "/sys/class/kgsl/kgsl-3d0/devfreq/available_governors",
35    "/sys/class/kgsl/kgsl-3d0/devfreq/cur_freq",
36    "/sys/class/kgsl/kgsl-3d0/devfreq/governor",
37    "/sys/class/kgsl/kgsl-3d0/devfreq/gpu_load",
38    "/sys/class/kgsl/kgsl-3d0/devfreq/max_freq",
39    "/sys/class/kgsl/kgsl-3d0/devfreq/min_freq",
40    "/sys/class/kgsl/kgsl-3d0/devfreq/polling_interval",
41    "/sys/class/kgsl/kgsl-3d0/devfreq/suspend_time",
42    "/sys/class/kgsl/kgsl-3d0/devfreq/target_freq",
43    "/sys/class/kgsl/kgsl-3d0/devfreq/trans_stat",
44    "/sys/class/kgsl/kgsl-3d0/device/op_cpu_table",
45    "/sys/class/kgsl/kgsl-3d0/freq_table_mhz",
46    "/sys/class/kgsl/kgsl-3d0/ft_fast_hang_detect",
47    "/sys/class/kgsl/kgsl-3d0/ft_hang_intr_status",
48    "/sys/class/kgsl/kgsl-3d0/ft_long_ib_detect",
49    "/sys/class/kgsl/kgsl-3d0/ft_pagefault_policy",
50    "/sys/class/kgsl/kgsl-3d0/ft_policy",
51    "/sys/class/kgsl/kgsl-3d0/gpu_available_frequencies",
52    "/sys/class/kgsl/kgsl-3d0/gpu_busy_percentage",
53    "/sys/class/kgsl/kgsl-3d0/gpu_clock_stats",
54    "/sys/class/kgsl/kgsl-3d0/gpu_llc_slice_enable",
55    "/sys/class/kgsl/kgsl-3d0/gpu_model",
56    "/sys/class/kgsl/kgsl-3d0/gpubusy",
57    "/sys/class/kgsl/kgsl-3d0/gpuclk",
58    "/sys/class/kgsl/kgsl-3d0/gpuhtw_llc_slice_enable",
59    "/sys/class/kgsl/kgsl-3d0/hwcg",
60    "/sys/class/kgsl/kgsl-3d0/idle_timer",
61    "/sys/class/kgsl/kgsl-3d0/lm",
62    "/sys/class/kgsl/kgsl-3d0/max_gpuclk",
63    "/sys/class/kgsl/kgsl-3d0/max_pwrlevel",
64    "/sys/class/kgsl/kgsl-3d0/min_clock_mhz",
65    "/sys/class/kgsl/kgsl-3d0/min_pwrlevel",
66    "/sys/class/kgsl/kgsl-3d0/num_pwrlevels",
67    "/sys/class/kgsl/kgsl-3d0/pmqos_active_latency",
68    "/sys/class/kgsl/kgsl-3d0/popp",
69    "/sys/class/kgsl/kgsl-3d0/preempt_count",
70    "/sys/class/kgsl/kgsl-3d0/preempt_level",
71    "/sys/class/kgsl/kgsl-3d0/preemption",
72    "/sys/class/kgsl/kgsl-3d0/pwrscale",
73    "/sys/class/kgsl/kgsl-3d0/reset_count",
74    "/sys/class/kgsl/kgsl-3d0/skipsaverestore",
75    "/sys/class/kgsl/kgsl-3d0/sptp_pc",
76    "/sys/class/kgsl/kgsl-3d0/thermal_pwrlevel",
77    "/sys/class/kgsl/kgsl-3d0/throttling",
78    "/sys/class/kgsl/kgsl-3d0/usesgmem",
79    "/sys/class/kgsl/kgsl-3d0/wake_nice",
80    "/sys/class/kgsl/kgsl-3d0/wake_timeout",
81    "/sys/devices/soc0/accessory_chip",
82    "/sys/devices/soc0/build_id",
83    "/sys/devices/soc0/chip_family",
84    "/sys/devices/soc0/chip_name",
85    "/sys/devices/soc0/family",
86    "/sys/devices/soc0/foundry_id",
87    "/sys/devices/soc0/hw_platform",
88    "/sys/devices/soc0/image_crm_version",
89    "/sys/devices/soc0/image_variant",
90    "/sys/devices/soc0/image_version",
91    "/sys/devices/soc0/images",
92    "/sys/devices/soc0/machine",
93    "/sys/devices/soc0/ncluster_array_offset",
94    "/sys/devices/soc0/ndefective_parts_array_offset",
95    "/sys/devices/soc0/nmodem_supported",
96    "/sys/devices/soc0/nproduct_id",
97    "/sys/devices/soc0/num_clusters",
98    "/sys/devices/soc0/num_defective_parts",
99    "/sys/devices/soc0/platform_subtype",
100    "/sys/devices/soc0/platform_subtype_id",
101    "/sys/devices/soc0/platform_version",
102    "/sys/devices/soc0/pmic_die_revision",
103    "/sys/devices/soc0/pmic_model",
104    "/sys/devices/soc0/raw_device_family",
105    "/sys/devices/soc0/raw_device_number",
106    "/sys/devices/soc0/raw_id",
107    "/sys/devices/soc0/raw_version",
108    "/sys/devices/soc0/revision",
109    "/sys/devices/soc0/select_image",
110    "/sys/devices/soc0/serial_number",
111    "/sys/devices/soc0/soc_id",
112    "/sys/devices/soc0/vendor",
113    "/sys/devices/system/b.L/big_threads",
114    "/sys/devices/system/b.L/boot_cluster",
115    "/sys/devices/system/b.L/core_status",
116    "/sys/devices/system/b.L/little_threads",
117    "/sys/devices/system/b.L/down_migrations",
118    "/sys/devices/system/b.L/up_migrations",
119    "/sys/devices/system/cpu/isolated",
120    "/sys/devices/system/cpu/kernel_max",
121    "/sys/devices/system/cpu/modalias",
122    "/sys/devices/system/cpu/offline",
123    "/sys/devices/system/cpu/online",
124    "/sys/devices/system/cpu/possible",
125    "/sys/devices/system/cpu/present",
126    "/sys/devices/system/cpu/sched_isolated",
127    "/sys/devices/system/cpu/clusterhotplug/cur_hstate",
128    "/sys/devices/system/cpu/clusterhotplug/down_freq",
129    "/sys/devices/system/cpu/clusterhotplug/down_tasks",
130    "/sys/devices/system/cpu/clusterhotplug/down_threshold",
131    "/sys/devices/system/cpu/clusterhotplug/sampling_rate",
132    "/sys/devices/system/cpu/clusterhotplug/time_in_state",
133    "/sys/devices/system/cpu/clusterhotplug/up_freq",
134    "/sys/devices/system/cpu/clusterhotplug/up_tasks",
135    "/sys/devices/system/cpu/clusterhotplug/up_threshold",
136    "/sys/devices/system/cpu/cpufreq/all_time_in_state",
137    "/sys/devices/system/cpu/cpufreq/current_in_state",
138    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/big_cpu_num",
139    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/big_max_freq",
140    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/big_min_freq",
141    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/hmp_boost_type",
142    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/hmp_prev_boost_type",
143    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_cpu_num",
144    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_divider",
145    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_max_freq",
146    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_min_freq",
147    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/ltl_min_lock",
148    "/sys/devices/system/cpu/cpufreq/cpufreq_limit/requests",
149    "/sys/devices/system/cpu/cpuidle/current_driver",
150    "/sys/devices/system/cpu/cpuidle/current_governor_ro",
151    "/sys/devices/system/cpu/cputopo/cpus_per_cluster",
152    "/sys/devices/system/cpu/cputopo/big_cpumask",
153    "/sys/devices/system/cpu/cputopo/glbinfo",
154    "/sys/devices/system/cpu/cputopo/is_big_little",
155    "/sys/devices/system/cpu/cputopo/is_multi_cluster",
156    "/sys/devices/system/cpu/cputopo/little_cpumask",
157    "/sys/devices/system/cpu/cputopo/nr_clusters",
158    "/sys/devices/system/sched/idle_prefer",
159    "/sys/devices/system/sched/sched_boost",
160]
161
162CPU_FILES = [
163    "core_ctl/active_cpus",
164    "core_ctl/busy_up_thres",
165    "core_ctl/busy_down_thres",
166    "core_ctl/enable",
167    "core_ctl/global_state",
168    "core_ctl/is_big_cluster",
169    "core_ctl/max_cpus",
170    "core_ctl/min_cpus",
171    "core_ctl/need_cpus",
172    "core_ctl/not_preferred",
173    "core_ctl/offline_delay_ms",
174    "core_ctl/task_thres",
175    "current_driver",
176    "current_governor_ro",
177    "cpuidle/driver/name",
178    "cpufreq/affected_cpus",
179    "cpufreq/cpuinfo_max_freq",
180    "cpufreq/cpuinfo_min_freq",
181    "cpufreq/cpuinfo_transition_latency",
182    "cpufreq/related_cpus",
183    "cpufreq/scaling_available_frequencies",
184    "cpufreq/scaling_available_governors",
185    "cpufreq/scaling_cur_freq",
186    "cpufreq/scaling_driver",
187    "cpufreq/scaling_governor",
188    "cpufreq/scaling_max_freq",
189    "cpufreq/scaling_min_freq",
190    "cpufreq/sched/down_throttle_nsec",
191    "cpufreq/sched/up_throttle_nsec",
192    "cpufreq/stats/time_in_state",
193    "cpufreq/stats/total_trans",
194    "cpufreq/stats/trans_table",
195    "isolate",
196    "regs/identification/midr_el1",
197    "regs/identification/revidr_el1",
198    "sched_load_boost",
199    "topology/core_id",
200    "topology/core_siblings",
201    "topology/core_siblings_list",
202    "topology/cpu_capacity",
203    "topology/max_cpu_capacity",
204    "topology/physical_package_id",
205    "topology/thread_siblings",
206    "topology/thread_siblings_list",
207]
208
209CACHE_FILES = [
210    "allocation_policy",
211    "coherency_line_size",
212    "level",
213    "number_of_sets",
214    "shared_cpu_list",
215    "shared_cpu_map",
216    "size",
217    "type",
218    "ways_of_associativity",
219    "write_policy",
220]
221
222def c_escape(string):
223    c_string = ""
224    for c in string:
225        if c == "\\":
226            c_string += "\\\\"
227        elif c == "\"":
228            c_string += "\\\""
229        elif c == "\t":
230            c_string += "\\t"
231        elif c == "\n":
232            c_string += "\\n"
233        elif c == "\r":
234            c_string += "\\r"
235        elif ord(c) == 0:
236            c_string += "\\0"
237        elif 32 <= ord(c) < 127:
238            c_string += c
239        else:
240            c_string += "x%02X" % ord(c)
241    return c_string
242
243def adb_shell(commands):
244    env = os.environ.copy()
245    env["LC_ALL"] = "C"
246
247    adb = subprocess.Popen(["adb", "shell"] + commands, env=env, stdout=subprocess.PIPE)
248    stdout, _ = adb.communicate()
249    if adb.returncode == 0:
250        return stdout
251
252def adb_push(local_path, device_path):
253    env = os.environ.copy()
254    env["LC_ALL"] = "C"
255
256    adb = subprocess.Popen(["adb", "push", local_path, device_path], env=env)
257    adb.communicate()
258    return adb.returncode == 0
259
260def adb_pull(device_path, local_path):
261    if any(device_path.startswith(prefix) for prefix in SHELL_PREFIX):
262        content = adb_shell(["cat", device_path])
263        if content is not None:
264            if not content.rstrip().endswith("No such file or directory"):
265                with open(local_path, "wb") as local_file:
266                    local_file.write(content)
267                    return True
268    else:
269        env = os.environ.copy()
270        env["LC_ALL"] = "C"
271
272        adb = subprocess.Popen(["adb", "pull", device_path, local_path], env=env)
273        adb.communicate()
274        return adb.returncode == 0
275
276def adb_getprop():
277    properties = adb_shell(["getprop"])
278    properties_list = list()
279    while properties:
280        assert properties.startswith("[")
281        properties = properties[1:]
282        key, properties = properties.split("]", 1)
283        properties = properties.strip()
284        assert properties.startswith(":")
285        properties = properties[1:].strip()
286        assert properties.startswith("[")
287        properties = properties[1:]
288        value, properties = properties.split("]", 1)
289        properties = properties.strip()
290        properties_list.append((key, value))
291    return properties_list
292
293def add_mock_file(stream, path, content):
294    assert content is not None
295    stream.write("\t{\n")
296    stream.write("\t\t.path = \"%s\",\n" % path)
297    stream.write("\t\t.size = %d,\n" % len(content))
298    if len(content.splitlines()) > 1:
299        stream.write("\t\t.content =")
300        for line in content.splitlines(True):
301            stream.write("\n\t\t\t\"%s\"" % c_escape(line))
302        stream.write(",\n")
303    else:
304        stream.write("\t\t.content = \"%s\",\n" % c_escape(content))
305    stream.write("\t},\n")
306
307
308def dump_device_file(stream, path, prefix_line=None):
309    temp_fd, temp_path = tempfile.mkstemp()
310    os.close(temp_fd)
311    try:
312        if adb_pull(path, temp_path):
313            with open(temp_path, "rb") as temp_file:
314                content = temp_file.read()
315                if prefix_line is not None:
316                    stream.write(prefix_line)
317                add_mock_file(stream, path, content)
318                return content
319    finally:
320        if os.path.exists(temp_path):
321            os.remove(temp_path)
322
323
324def main(args):
325    options = parser.parse_args(args)
326
327    dmesg_content = adb_shell(["dmesg"])
328    if dmesg_content is not None and dmesg_content.strip() == "klogctl: Operation not permitted":
329        dmesg_content = None
330    if dmesg_content is not None:
331        with open(os.path.join("test", "dmesg", options.prefix + ".log"), "w") as dmesg_dump:
332            dmesg_dump.write(dmesg_content)
333
334    build_prop_content = None
335    proc_cpuinfo_content = None
336    proc_cpuinfo_content32 = None
337    kernel_max = 0
338    with open(os.path.join("test", "mock", options.prefix + ".h"), "w") as file_header:
339        file_header.write("struct cpuinfo_mock_file filesystem[] = {\n")
340        android_props = adb_getprop()
341        abi = None
342        for key, value in android_props:
343            if key == "ro.product.cpu.abi":
344                abi = value
345        for path in SYSTEM_FILES:
346            arm64_prefix = None
347            if path == "/proc/cpuinfo" and abi == "arm64-v8a":
348                arm64_prefix = "#if CPUINFO_ARCH_ARM64\n"
349            content = dump_device_file(file_header, path, prefix_line=arm64_prefix)
350            if content is not None:
351                if path == "/proc/cpuinfo":
352                    proc_cpuinfo_content = content
353                elif path == "/system/build.prop":
354                    build_prop_content = content
355                elif path == "/sys/devices/system/cpu/kernel_max":
356                    kernel_max = int(content.strip())
357            if arm64_prefix:
358                cpuinfo_dump_binary = os.path.join(root_dir, "..", "build", "android", "armeabi-v7a", "cpuinfo-dump")
359                assert os.path.isfile(cpuinfo_dump_binary)
360                adb_push(cpuinfo_dump_binary, "/data/local/tmp/cpuinfo-dump")
361                proc_cpuinfo_content32 = adb_shell(["/data/local/tmp/cpuinfo-dump"])
362                if proc_cpuinfo_content32:
363                    proc_cpuinfo_content32 = "\n".join(proc_cpuinfo_content32.splitlines())
364                    file_header.write("#elif CPUINFO_ARCH_ARM\n")
365                    add_mock_file(file_header, "/proc/cpuinfo", proc_cpuinfo_content32)
366                file_header.write("#endif\n")
367
368        for cpu in range(kernel_max + 1):
369            for filename in CPU_FILES:
370                path = "/sys/devices/system/cpu/cpu%d/%s" % (cpu, filename)
371                dump_device_file(file_header, path)
372            for index in range(5):
373                for filename in CACHE_FILES:
374                    path = "/sys/devices/system/cpu/cpu%d/cache/index%d/%s" % (cpu, index, filename)
375                    dump_device_file(file_header, path)
376        file_header.write("\t{ NULL },\n")
377        file_header.write("};\n")
378        file_header.write("#ifdef __ANDROID__\n")
379        file_header.write("struct cpuinfo_mock_property properties[] = {\n")
380        for key, value in android_props:
381            file_header.write("\t{\n")
382            file_header.write("\t\t.key = \"%s\",\n" % c_escape(key))
383            file_header.write("\t\t.value = \"%s\",\n" % c_escape(value))
384            file_header.write("\t},\n")
385        file_header.write("\t{ NULL },\n")
386        file_header.write("};\n")
387        file_header.write("#endif /* __ANDROID__ */\n")
388
389    if proc_cpuinfo_content is not None:
390        with open(os.path.join("test", "cpuinfo", options.prefix + ".log"), "w") as proc_cpuinfo_dump:
391            proc_cpuinfo_dump.write(proc_cpuinfo_content)
392    if proc_cpuinfo_content32 is not None:
393        with open(os.path.join("test", "cpuinfo", options.prefix + ".armeabi.log"), "w") as proc_cpuinfo_dump32:
394            proc_cpuinfo_dump32.write(proc_cpuinfo_content32)
395    if build_prop_content is not None:
396        with open(os.path.join("test", "build.prop", options.prefix + ".log"), "w") as build_prop_dump:
397            build_prop_dump.write(build_prop_content)
398
399if __name__ == "__main__":
400    main(sys.argv[1:])
401