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