一、系统启动日志分析——从按下电源键开始

做Android系统开发这些年,我有个习惯:每次拿到一台新设备,第一件事就是抓一份完整的启动日志。为什么?因为启动过程就像系统的“出生证明”,里面藏着太多信息了。

说白了,系统启动就是一场接力赛。从Bootloader到Kernel,从init进程到Zygote,再到System Server,最后到Launcher。每个环节都有特定的日志输出。今天我就带你走一遍这个流程。

1.1 启动流程概览

先看一张图,把整个启动链路串起来。我画这张图的时候,特意把关键日志输出点标了出来。

Android 系统启动全链路日志分析 Bootloader 日志: 无(串口输出) Linux Kernel 日志: dmesg / kernel log init 进程 日志: logcat -b main Zygote 日志: logcat -b main System Server 日志: logcat -b system Launcher 日志: logcat -b events 关键日志输出点 • Bootloader → Kernel: 无标准logcat输出,需通过串口或dmesg查看 • Kernel → init: 出现 "init: init first stage started!" 标志性日志 • init → Zygote: 出现 "init: starting service 'zygote'..." 日志 • Zygote → System Server: 出现 "SystemServer: Entered the Android system server!" • System Server → Launcher: 出现 "ActivityManager: Start proc Launcher"

1.2 各阶段日志特征

每个阶段的日志都有独特的“味道”。我整理了一个表格,方便你对照着看。

启动阶段 日志缓冲区 关键Tag 典型日志内容
Bootloader 无(串口) - 串口输出,logcat不可见
Kernel kernel / main kernel, init init: init first stage started!
init main init, ueventd init: starting service 'zygote'
Zygote main, system Zygote, dalvikvm Zygote: Preloading classes...
System Server system, events SystemServer, ActivityManager SystemServer: Entered the Android system server!
Launcher events, main Launcher, WindowManager ActivityManager: Start proc Launcher

1.3 实战抓取启动日志

嗯,这里要注意一个细节:抓启动日志不能用普通的 adb logcat,因为那只能抓到当前时刻之后的日志。要抓完整的启动过程,得用 -b all -d 参数。

我个人习惯用这条命令:

# 抓取所有缓冲区的历史日志
adb logcat -b all -d > boot_log.txt

# 如果想实时看启动过程,先清空缓冲区再重启
adb logcat -c
adb reboot
adb logcat -b all > boot_log.txt
小技巧: 我建议在抓日志前先执行 adb logcat -G 16M 把缓冲区扩大到16MB。默认只有256KB,启动日志很容易被冲掉。这个坑我踩过好几次。

1.4 关键日志解读

拿到日志后,怎么快速定位关键节点?我总结了几个“灯塔”日志,看到它们就知道启动到哪一步了。

1.4.1 Kernel 启动完成

// 搜索 "init first stage" 或 "Freeing unused kernel memory"
[    5.123456] init: init first stage started!
[    5.234567] Freeing unused kernel memory: 1024K

看到这条日志,说明Kernel已经完成初始化,init进程开始运行了。我记得有一次设备卡在这里,查了半天发现是Kernel的initramfs损坏了。

1.4.2 Zygote 启动

// 搜索 "starting service 'zygote'"
01-01 00:00:12.345   123   123 I init    : starting service 'zygote' 
01-01 00:00:12.456   456   456 I Zygote  : Preloading classes...
01-01 00:00:15.678   456   456 I Zygote  : ...preloaded 5234 classes in 3.2s

Zygote启动时有个关键动作:预加载类。预加载的类数量和时间,直接反映了系统性能。如果预加载时间超过5秒,那启动速度肯定有问题。

1.4.3 System Server 就绪

// 搜索 "Entered the Android system server"
01-01 00:00:16.789   789   789 I SystemServer: Entered the Android system server!
01-01 00:00:16.790   789   789 I SystemServer: Starting services...
01-01 00:00:20.123   789   789 I SystemServer: Services started in 3.3s
重点: System Server 启动时间是一个关键指标。正常应该在3-5秒内完成。如果超过10秒,说明某个服务初始化出了问题。我曾经遇到一个案例,就是因为Wifi服务初始化卡住了,导致整个系统启动慢了8秒。

1.4.4 Launcher 启动

// 搜索 "Start proc" 和 "Launcher"
01-01 00:00:21.456   789   789 I ActivityManager: Start proc 1234:com.android.launcher3/u0a1 for activity 
01-01 00:00:22.789  1234  1234 I Launcher: Launcher started. Time to first frame: 1.2s

看到Launcher的进程启动日志,说明系统已经基本就绪了。从按下电源键到Launcher显示,这个总时间就是“开机时间”。

1.5 常见问题排查

实战中,启动问题是最让人头疼的。我整理了几个高频问题,你可以直接对照着查。

  1. 卡在Bootloader:日志里没有任何输出。检查电源、硬件连接,或者刷boot.img。
  2. Kernel panic:dmesg里有 Kernel panic - not syncing。通常是驱动问题。
  3. init 进程崩溃:日志停在 init first stage 之后。检查init.rc语法。
  4. Zygote 预加载超时:预加载类时间超过10秒。检查是否有自定义的preload-classes。
  5. System Server 启动慢:某个服务初始化卡住。用 logcat -b system | grep "ServiceManager" 定位。
  6. Launcher 黑屏:Launcher进程启动但没显示。检查SurfaceFlinger和WindowManager日志。
避坑指南: 我曾经遇到一个奇葩问题——每次开机都卡在Zygote预加载阶段。查了三天,最后发现是/data分区空间不足,导致Zygote无法写入odex缓存。所以,排查启动问题时,别忘了检查磁盘空间。

1.6 实战演练:分析一次完整的启动日志

来,我们动手做一次完整的分析。假设你拿到了下面这段日志(我简化了时间戳):

// 阶段1: Kernel 启动
[    0.000] Booting Linux on physical CPU 0
[    3.456] init: init first stage started!
[    4.567] Freeing unused kernel memory: 1024K

// 阶段2: init 启动服务
01-01 00:00:05.678 I init    : starting service 'zygote'
01-01 00:00:05.679 I init    : starting service 'servicemanager'

// 阶段3: Zygote 预加载
01-01 00:00:06.890 I Zygote  : Preloading classes...
01-01 00:00:10.234 I Zygote  : ...preloaded 5234 classes in 3.3s

// 阶段4: System Server
01-01 00:00:11.345 I SystemServer: Entered the Android system server!
01-01 00:00:11.346 I SystemServer: Starting services...
01-01 00:00:15.678 I SystemServer: Services started in 4.3s

// 阶段5: Launcher
01-01 00:00:16.789 I ActivityManager: Start proc 1234:com.android.launcher3
01-01 00:00:18.012 I Launcher: Launcher started. Time to first frame: 1.2s

分析一下:

  • Kernel启动耗时:3.456秒(正常)
  • Zygote预加载耗时:3.3秒(正常范围)
  • System Server启动耗时:4.3秒(正常)
  • 总开机时间:约18秒(从Kernel开始算)

这个启动速度属于中等水平。如果总时间超过30秒,就需要优化了。

我的经验: 优化启动速度,优先看Zygote预加载和System Server这两个阶段。它们占了启动时间的大头。我曾经把一个设备的启动时间从35秒优化到22秒,主要就是减少了预加载的类数量,以及优化了Wifi服务的初始化流程。

好了,这一章的内容就到这里。启动日志分析是个熟能生巧的活,多抓几次、多分析几次,你就能一眼看出问题在哪。下一章我们会深入分析应用启动过程中的日志,到时候再聊。


公众号:蓝海资料掘金营,微信deep3321