Skip to content

Commit fd57f24

Browse files
committed
cumulated update
boot editor: support dtb in linux lazybox: more commands
1 parent f18f99a commit fd57f24

File tree

5 files changed

+297
-9
lines changed

5 files changed

+297
-9
lines changed

bbootimg/src/main/kotlin/packable/DeviceTreeParser.kt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,24 @@ class DeviceTreeParser : IPackable {
8787

8888
//pull
8989
"adb root".check_call()
90-
"adb push tools/bin/dtc-android /data/vendor/dtc-android".check_call()
91-
val hw = "adb shell getprop ro.hardware".check_output()
92-
log.info("ro.hardware=$hw")
93-
"adb shell /data/vendor/dtc-android -I fs /proc/device-tree -o /data/vendor/file.to.pull".check_call()
90+
var hw = "linux"
91+
if ("adb shell which getprop".check_output().isBlank()) { //linux
92+
"adb push tools/bin/dtc-linux /data/vendor/dtc".check_call()
93+
} else { //android
94+
"adb push tools/bin/dtc-android /data/vendor/dtc".check_call()
95+
hw = "adb shell getprop ro.hardware".check_output()
96+
log.info("ro.hardware=$hw")
97+
}
98+
"adb shell /data/vendor/dtc -I fs /proc/device-tree -o /data/vendor/file.to.pull".check_call()
9499
"adb pull /data/vendor/file.to.pull $workDir$hw.dts".check_call()
95-
"adb shell /data/vendor/dtc-android -I fs -O dtb /proc/device-tree -o /data/vendor/file.to.pull".check_call()
100+
"adb shell /data/vendor/dtc -I fs -O dtb /proc/device-tree -o /data/vendor/file.to.pull".check_call()
96101
"adb pull /data/vendor/file.to.pull $hw.dtb".check_call()
97102
"adb shell rm /data/vendor/file.to.pull".check_call()
98-
"adb shell rm /data/vendor/dtc-android".check_call()
103+
"adb shell rm /data/vendor/dtc".check_call()
99104
if (fileName != "$hw.dtb") {
100105
File(fileName).delete()
101106
log.warn("deleting intermediate dtb file: $fileName")
102107
}
103-
104108
//print summary
105109
val prints: MutableList<Pair<String, String>> = mutableListOf()
106110
prints.add(Pair("source", "/proc/device-tree"))

lazybox/src/main/kotlin/cfig/lazybox/App.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cfig.lazybox
22

33
import cfig.lazybox.staging.DiffCI
4+
import cfig.lazybox.staging.Perfetto
45
import cfig.lazybox.staging.RepoWorker
56
import cfig.lazybox.sysinfo.BootChart
67
import cfig.lazybox.sysinfo.CpuInfo
@@ -32,6 +33,7 @@ fun main(args: Array<String>) {
3233
println("diffci : find changelist files from CI server based on date and time ranges")
3334
println("repo_lfs : pull LFS files from Git repositories managed by 'repo'")
3435
println("repo_unshallow: unshallow Git repositories managed by 'repo'")
36+
println("perfetto : generate a Perfetto configuration file")
3537
exitProcess(0)
3638
}
3739
if (args[0] == "cpuinfo") {
@@ -111,4 +113,7 @@ fun main(args: Array<String>) {
111113
if (args[0] == "repo_unshallow") {
112114
RepoWorker().unshallowRepo(args.drop(1).toTypedArray())
113115
}
116+
if (args[0] == "perfetto") {
117+
Perfetto().run(args.drop(1).toTypedArray())
118+
}
114119
}
Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
package cfig.lazybox.staging
2+
3+
import java.io.File
4+
import org.slf4j.LoggerFactory
5+
6+
class Perfetto {
7+
private val log = LoggerFactory.getLogger(Perfetto::class.java.simpleName)
8+
9+
/**
10+
* Main entry method to generate the configuration file.
11+
*/
12+
fun run(args: Array<String>) {
13+
val options = args.toSet()
14+
15+
// Check for help flags
16+
if ("-h" in options || "--help" in options) {
17+
printUsage()
18+
return
19+
}
20+
21+
log.info("Running Perfetto configuration generation with arguments: ${args.joinToString(", ")}")
22+
val outputFileName = "pftrace.cfg"
23+
val finalConfig = generatePerfettoConfig(options)
24+
25+
try {
26+
File(outputFileName).writeText(finalConfig)
27+
log.info("Successfully wrote Perfetto configuration to '$outputFileName'.")
28+
log.info("Options used: ${options.ifEmpty { setOf("default") }}")
29+
30+
if ("+boot" in options) {
31+
val adbCommands = """
32+
33+
--------------------------------------------------------------------
34+
Boot trace config enabled. To capture a boot trace, run these commands:
35+
36+
[enable tracing]
37+
adb root
38+
adb push pftrace.cfg /data/misc/perfetto-configs/boottrace.pbtxt
39+
adb shell setprop persist.debug.perfetto.boottrace 1
40+
41+
[pull trace result after reboot]
42+
adb pull /data/misc/perfetto-traces/boottrace.perfetto-trace
43+
--------------------------------------------------------------------
44+
""".trimIndent()
45+
println(adbCommands)
46+
}
47+
} catch (e: Exception) {
48+
log.error("Failed to write to file '$outputFileName'. Reason: ${e.message}")
49+
}
50+
}
51+
52+
/**
53+
* Prints the help/usage message for the script.
54+
*/
55+
private fun printUsage() {
56+
val usage = """
57+
Usage: kotlin Perfetto.main.kts [options...]
58+
59+
Generates a pftrace.cfg file for Perfetto tracing based on specified options.
60+
The output file is named 'pftrace.cfg'.
61+
62+
Options:
63+
-h, --help Show this help message and exit.
64+
65+
+power Include ftrace power events and Android power rail data sources.
66+
+atrace Include a wide range of atrace categories for detailed app tracing.
67+
+lmk Include Low Memory Killer (LMK) and OOM score ftrace events.
68+
+cpu_usage Include detailed CPU time and process fork count statistics.
69+
+logcat Include all Android logcat buffers in the trace.
70+
+sf Include SurfaceFlinger frame timeline data.
71+
+boot Enable boot tracing. After generating the config, this prints the
72+
necessary adb commands to set up the trace for the next boot.
73+
""".trimIndent()
74+
println(usage)
75+
}
76+
77+
/**
78+
* Builds the Perfetto configuration string based on the provided options.
79+
*/
80+
fun generatePerfettoConfig(options: Set<String> = emptySet()): String {
81+
log.info("Generating Perfetto configuration with options: $options")
82+
val configBuilder = StringBuilder()
83+
84+
// --- 1. Base Config: Buffers ---
85+
log.info("Adding buffers")
86+
configBuilder.append(
87+
"""
88+
# === Buffers ===
89+
buffers: {
90+
size_kb: 63488
91+
fill_policy: DISCARD
92+
}
93+
buffers: {
94+
size_kb: 2048
95+
fill_policy: DISCARD
96+
}
97+
98+
""".trimIndent()
99+
)
100+
101+
// --- 2. Base Config: Core Data Sources (excluding sys_stats) ---
102+
log.info("Adding core data sources")
103+
configBuilder.append(
104+
"""
105+
# === Base Data Sources ===
106+
data_sources: {
107+
config {
108+
name: "linux.process_stats"
109+
process_stats_config {
110+
scan_all_processes_on_start: true
111+
proc_stats_poll_ms: 250
112+
}
113+
}
114+
}
115+
data_sources: {
116+
config {
117+
name: "android.packages_list"
118+
target_buffer: 1
119+
}
120+
}
121+
""".trimIndent()
122+
)
123+
124+
// --- 3. Dynamic and Optional Config ---
125+
126+
// Dynamically build linux.sys_stats config
127+
val sysStatsLines = mutableListOf(
128+
"meminfo_period_ms: 250",
129+
"vmstat_period_ms: 250",
130+
"cpufreq_period_ms: 250"
131+
)
132+
if ("+cpu_usage" in options) {
133+
log.info("Adding data sources for: +cpu_usage")
134+
sysStatsLines.add("stat_period_ms: 250")
135+
sysStatsLines.add("stat_counters: STAT_CPU_TIMES")
136+
sysStatsLines.add("stat_counters: STAT_FORK_COUNT")
137+
}
138+
139+
log.info("Appending sys_stats data source to config")
140+
configBuilder.append("\n\n# === System-wide Stats ===")
141+
configBuilder.append(
142+
"""
143+
data_sources: {
144+
config {
145+
name: "linux.sys_stats"
146+
sys_stats_config {
147+
""".trimIndent()
148+
)
149+
sysStatsLines.forEach { configBuilder.append("\n $it") }
150+
configBuilder.append(
151+
"""
152+
}
153+
}
154+
}
155+
""".trimIndent()
156+
)
157+
158+
// Dynamically build ftrace config
159+
val ftraceEvents = mutableListOf<String>()
160+
val atraceCategories = mutableListOf<String>()
161+
val atraceApps = mutableListOf<String>()
162+
163+
if ("+power" in options) {
164+
ftraceEvents.add("power/*")
165+
}
166+
if ("+atrace" in options) {
167+
ftraceEvents.add("ftrace/print")
168+
atraceCategories.addAll(
169+
listOf(
170+
"adb", "aidl", "am", "audio", "binder_driver", "binder_lock",
171+
"bionic", "camera", "dalvik", "database", "gfx", "hal",
172+
"input", "network", "nnapi", "pm", "power", "res", "rro",
173+
"rs", "sm", "ss", "vibrator", "video", "view", "webview", "wm"
174+
)
175+
)
176+
}
177+
if ("+lmk" in options) {
178+
log.info("Adding data sources for: +lmk")
179+
ftraceEvents.add("lowmemorykiller/lowmemory_kill")
180+
ftraceEvents.add("oom/oom_score_adj_update")
181+
atraceApps.add("lmkd")
182+
}
183+
184+
if (ftraceEvents.isNotEmpty() || atraceCategories.isNotEmpty() || atraceApps.isNotEmpty()) {
185+
log.info("Appending ftrace data source to config")
186+
configBuilder.append("\n\n# === Optional Ftrace/Atrace Tracing ===")
187+
configBuilder.append(
188+
"""
189+
data_sources: {
190+
config {
191+
name: "linux.ftrace"
192+
ftrace_config {
193+
""".trimIndent()
194+
)
195+
ftraceEvents.forEach { configBuilder.append("\n ftrace_events: \"$it\"") }
196+
atraceCategories.forEach { configBuilder.append("\n atrace_categories: \"$it\"") }
197+
atraceApps.forEach { configBuilder.append("\n atrace_apps: \"$it\"") }
198+
configBuilder.append(
199+
"""
200+
}
201+
}
202+
}
203+
""".trimIndent()
204+
)
205+
}
206+
207+
if ("+power" in options) {
208+
log.info("Adding data sources for: android.power")
209+
configBuilder.append(
210+
"""
211+
212+
# === Optional Android Power Tracing ===
213+
data_sources: {
214+
config {
215+
name: "android.power"
216+
android_power_config {
217+
battery_poll_ms: 250
218+
battery_counters: BATTERY_COUNTER_CAPACITY_PERCENT
219+
battery_counters: BATTERY_COUNTER_CHARGE
220+
battery_counters: BATTERY_COUNTER_CURRENT
221+
collect_power_rails: true
222+
}
223+
}
224+
}
225+
""".trimIndent()
226+
)
227+
}
228+
229+
if ("+logcat" in options) {
230+
log.info("Adding data sources for: +logcat")
231+
configBuilder.append(
232+
"""
233+
# === Optional Logcat Tracing ===
234+
data_sources {
235+
config {
236+
name: "android.log"
237+
android_log_config {
238+
log_ids: LID_CRASH
239+
log_ids: LID_DEFAULT
240+
log_ids: LID_EVENTS
241+
log_ids: LID_KERNEL
242+
log_ids: LID_RADIO
243+
log_ids: LID_SECURITY
244+
log_ids: LID_STATS
245+
log_ids: LID_SYSTEM
246+
}
247+
}
248+
}
249+
""".trimIndent()
250+
)
251+
}
252+
253+
// (REVISED) Add SurfaceFlinger data source if option is present
254+
if ("+sf" in options) {
255+
log.info("Adding data sources for: +sf")
256+
configBuilder.append(
257+
"""
258+
# === Optional SurfaceFlinger Tracing ===
259+
data_sources {
260+
config {
261+
name: "android.surfaceflinger.frametimeline"
262+
}
263+
}
264+
""".trimIndent()
265+
)
266+
}
267+
268+
// --- 4. Trace Duration ---
269+
log.info("Adding trace duration")
270+
configBuilder.append(
271+
"""
272+
# === Trace Duration ===
273+
# The total duration of the trace in milliseconds.
274+
duration_ms: 15000
275+
""".trimIndent()
276+
)
277+
278+
return configBuilder.toString()
279+
}
280+
}

lazybox/src/main/kotlin/cfig/lazybox/staging/RepoWorker.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ class RepoWorker {
5151
gitRepositories.forEach { repoDir ->
5252
val relativePath = repoDir.toRelativeString(startDir).ifEmpty { "." }
5353
if (checker(repoDir)) {
54-
log.info("Checking [$relativePath]...")
55-
log.info(" -> ✅ $checkerName")
54+
log.info("Checking [$relativePath]... ✅ $checkerName")
5655
ret.add(repoDir)
5756
} else {
5857
//log.info("Checking [$relativePath]...")

tools/bin/dtc-linux

97.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)