ThinkNotes

Simple is not easy | 化繁为简,知易行难

0%

Android驱动调试技术

Android驱动调试技术

Android嵌入式平台的系统要抓取驱动模块的log,一般不能像Linux系统直接在系统终端内配置,需要通过ADB(Android Debug Bridge)联机调试通道抓log。

ADB查看kernel log

ADB主机环境安装

windows主机可通过ADB连接Android板子,登录到开发板的系统root文件目录操作rootfs,并配置和抓取板子的kernel log打印。

Windows主机装ADB环境需要两个东西:

  1. 安装ADB exe包

在google andoid下载platform tools,即adb包

https://www.thecustomdroid.com/google-android-usb-drivers/

  1. 安装USB-ADB驱动

不装驱动连接soc板子(启动成功情况下),会有yellow-bang设备

驱动安装过程:

(1)右键yellow-bang设备,选择更新驱动 -> “通用串行总线”驱动类 -> 找到WinUSB的ADB设备类驱动,不管警告,安装。

图片1

(2)安装正常,设备会归为USB类,没有yellowbang

图片2

使用ADB抓log

方式1 使用**动态调试(Dynamic Debug)**和dmesg

需要设备已经root,并且adbd以root权限运行(adb root),如果没有root权限,可能只能依赖系统已有的日志输出,或者使用一些不需要root的调试方法(如logcat内核日志,如果系统支持)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# 启用MMC动态调试
adb root
adb wait-for-device
# 挂载debugfs类型(-t)的设备(debugfs)到节点/sys/kernel/debug
adb shell "mount -t debugfs debugfs /sys/kernel/debug"
# 打开mmc模块的动态调试
adb shell "echo 'file drivers/mmc/* +p' > /sys/kernel/debug/dynamic_debug/control"
adb shell "echo 'module mmc_core +p' >> /sys/kernel/debug/dynamic_debug/control"
adb shell "echo 'module sdhci +p' >> /sys/kernel/debug/dynamic_debug/control"
# 设置printk级别
adb shell "echo 7 > /proc/sys/kernel/printk"
# 清除旧日志
adb shell "dmesg -c"
# 开始捕获日志(两种都行)
adb shell "dmesg -w > mmc_log.txt"
adb shell "cat /proc/kmsg" | tee mmc_log.txt

以上很多adb shell命令可以先进入adb shell终端模式里面,之后就可以像linux终端内一样直接输入echo,dmesg命令,最后exit退出adb shell

1
2
3
4
5
6
7
adb shell
mount -t debugfs debugfs /sys/kernel/debug
echo 'file drivers/mmc/* +p' > /sys/kernel/debug/dynamic_debug/control
echo 'module mmc_core +p' >> /sys/kernel/debug/dynamic_debug/control
echo 'module sdhci +p' >> /sys/kernel/debug/dynamic_debug/control
...
exit

最后adb pull拉取mmc_log.txt

一个示例:

图片3

方式2 使用kernel logcat

Android 有自己的日志系统:logcat,可以直接打印日志

1
2
3
4
5
6
7
8
# 查看内核消息
adb logcat -b kernel
# 查看内核日志(-verbose带时间戳,-select关键词)
adb logcat -b kernel -v time -s mmc,sdhci

# 清除日志并重新开始
adb logcat -c
adb logcat -b kernel -v time

一个示例:

图片4

QA:为什么Android系统不能像Linux一样直接操作shell

Android和传统Linux主机有着根本不同的设计目标和安全架构

  1. 应用沙箱与权限模型:每个应用(包括可能运行的Shell应用)都被严格隔离在独立的“沙箱”中,无法直接访问系统日志文件等核心资源。即使你安装了终端模拟器,它本质上也是一个普通应用,权限受到严格限制。
  2. 强化的内核安全(SELinux):这是最关键的一层。从Android 5.0开始,系统会强制所有进程(包括拥有root权限的进程)都必须在SELinux的强制模式(Enforcing) 下运行。这意味着,即使你通过某种方式获得了root身份,SELinux策略规则(Policy)也会严格规定你这个“root”能做什么、不能做什么,通常禁止直接访问/proc/kmsg/sys/kernel/debug等调试节点。这回答了之前提到的为什么有时即使使用su命令也无法访问某些节点。
  3. 厂商的深度定制:为了进一步控制权限,一些设备制造商会在原生Android系统之上增加额外限制。例如,小米的MIUI系统就曾定制限制Shell对“工作空间”用户的访问

ADB在PC和Android设备之间建立了一个受控的、权限更高的调试通道

  • 它是如何工作的:当设备设置中启用“USB调试”后,设备上的adbd守护进程会以较高权限运行(但仍受SELinux策略约束)。通过PC端的ADB命令,你可以执行许多在设备内部Shell中无法直接完成的操作。
  • 实际应用:可以使用 adb shell 进入一个功能更强的设备端Shell,然后挂载debugfs或通过dmesg查看内核日志。也可以直接通过 adb logcat 命令抓取系统和应用日志

如果你想获取完全的访问权限,通常有两种途径:

  • 在开发阶段:编译一个用户调试(userdebug)版本的系统镜像并刷入设备。这类版本通常会放宽SELinux策略(设为宽容模式Permissive),并默认启用ADB的root访问。
  • 对已发布设备:这通常需要解锁Bootloader并刷入提供完整root权限的自定义内核或系统,但这会使设备失去官方保修并带来安全风险。