【问题标题】:Android Kernel DebuggingAndroid 内核调试
【发布时间】:2017-07-24 17:59:38
【问题描述】:

我一直在尝试让kgdb 使用 Nexus One。

我已从https://android.googlesource.com 中提取内核并启用与kgdb 相关的所有内容,包括使用menuconfig 进行kgdbts 测试。成功构建内核并将其刷入设备(已解锁并运行 CyanogenMod 7)

我还按照http://bootloader.wikidot.com/android:kgdb 上的说明启用 USB 连接作为kgdb 要求的串行连接(并成功测试了从ttyACM0ttyGS0 的通信)。

存在以下文件夹,表明kgdbockgdbts 已内置到内核中:

/sys/modules/kgdboc/parameters
/sys/modules/kgdbts/parameters

以下是 dmesg 的输出,显示正在完成的 kgdbts 测试显示(我认为)成功完成了测试:

# dmesg | grep kgdb
<6>[   12.974060] kgdb: Registered I/O driver kgdbts.
<6>[   12.981781] kgdbts:RUN plant and detach test
<6>[   12.995178] kgdbts:RUN sw breakpoint test
<6>[   13.002441] kgdbts:RUN bad memory access test
<6>[   13.010864] kgdbts:RUN singlestep test 1000 iterations
<6>[   13.019042] kgdbts:RUN singlestep [0/1000]
<6>[   13.077850] kgdbts:RUN singlestep [100/1000]
<6>[   13.132720] kgdbts:RUN singlestep [200/1000]
<6>[   13.187500] kgdbts:RUN singlestep [300/1000]
<6>[   13.242370] kgdbts:RUN singlestep [400/1000]
<6>[   13.297149] kgdbts:RUN singlestep [500/1000]
<6>[   13.351928] kgdbts:RUN singlestep [600/1000]
<6>[   13.406829] kgdbts:RUN singlestep [700/1000]
<6>[   13.461578] kgdbts:RUN singlestep [800/1000]
<6>[   13.516540] kgdbts:RUN singlestep [900/1000]
<6>[   13.570922] kgdbts:RUN do_fork for 100 breakpoints
<6>[   21.117645] kgdb: Unregistered I/O driver kgdbts, debugger disabled.

我相信我遇到的问题是让内核触发kgdb

# echo -n g > /proc/sysrq-trigger

只是导致我回到命令提示符并且(我认为)假设冻结所有内容并通过 USB 发送一个提示,该 USB 被用作伪串行端口,因为手机没有真正的串行端口。

根据我从研究中收集到的信息,提示应该是允许我发出问题的触发器

(gdb) target remote /dev/ttyACM0

并连接到与内核的调试会话。

我还用bc 测试了/proc/sysrq-trigger,只是确认我能够将一些命令传递给sysrq

所以在我冗长的尝试提供尽可能多的信息之后,我的问题是为什么g 没有触发调试器?

这是我第一次尝试在任何系统上进行内核调试,我已经用尽了在谷歌上搜索的方法,所以我求助于你。谢谢!

(我也尝试将 kdgbwait 放在内核命令行中但没有成功,因为我认为 android 内核尚不支持)

【问题讨论】:

  • 所以我继续研究这个并发现了以下......
  • 好奇你发现了什么:)
  • 以下在哪里?
  • 他不小心把全部解释完了。
  • 你发现了什么?只是想知道。

标签: android debugging kernel


【解决方案1】:

Android 内核问题在 [SO] 上很少见,因为没有其他人回答我已经提供了我对这个问题的发现。不幸的是,我没有一个可以测试这个的关系,所以这个答案不是为了逐步解决你的问题,而是应该指出你在哪里寻找的正确方向。

我在此问题上找到的唯一有用资源是 LKML patch by Dongdong Deng,因此不太可能是配置问题,因为这些资源通常很丰富且广为人知。

这表明您的内核构建存在问题。我很想从最新版本的 CM 重新开始,看看问题是否会消失。

如果失败,请尝试向 cyanogen 团队报告此问题,看看这是一个已知问题还是有简单的解决方法。

作为最后的手段,如果版本兼容,您可以尝试该补丁。唯一的选择是卷起袖子,开始破解 CM 内核以整合补丁。

祝你好运。

【讨论】:

    【解决方案2】:

    我没有使用Android硬件的经验,但是我已经完成了kgdb编译的内核作为VirtualBox客户端运行,并通过虚拟串口从主机连接到guest,并使用gdb(使用标准的“目标远程”命令)我可以在 kgdbwait 的帮助下逐步完成虚拟客户内核的整个启动过程。没有这个,我可以编写一个内核模块,除了实现一个名为“int 13”的内联程序集(即 0xcc)之外什么都不做。加载后,串口连接的主机端会出现一个断点,然后我可以设置断点并继续执行内核。这是因为 kgdb 处理异常“int 13”。如果你明确地创建了其他类型的异常,比如“*p = 0”,并且 p 指向 NULL,你仍然会得到一个断点,但我怀疑你是否可以继续执行。

    【讨论】:

      【解决方案3】:

      related post 找到这篇文章,并想说我刚刚发布了一些我为在 Nexus 6 上运行所做的工作,如果有人感兴趣的话:

      http://www.contextis.com/resources/blog/kgdb-android-debugging-kernel-boss/

      有趣的是,OP 的 sysrq 问题也是我遇到的一个问题。此行为的原因是 KGDB 未正确初始化,因此无法为“g”(kgdb)触发器安装处理程序。这就是所有其他 sysrq 命令仍然有效的原因。

      更长的解释(感谢@Robert):

      为了使这项工作正常进行,我必须制作基于this Accuvant blog 的 UART 调试电缆。这是一个非常简单的电路,由一个 FTDI 3.3v 基本分线器(撰写本文时可从 SparkFun 获得)以及 4 个电阻器(2 x 1K Ohm、1 x 1.2K Ohm 和 1 x 100Ohm)和一个4 元素 Tip-Ring-Ring-Sleeve (TRRS) 耳机插孔。电阻器本质上提供了一个分压器,以将 3.3v 降低到对您的手机更安全的水平。通过将另一端连接到电路板的音频插孔插入,音频子系统会识别出其中一个引脚上有电压(~2.8V),并且知道通过该电缆提供 UART 接口。 FTDI 分线器通过 USB 插入您的 PC,从这里您可以通过 minicom 等终端仿真器访问控制台消息。但是,您现在可以通过相同的机制获得一个串行接口,这就是我们可以用于 KGDB 连接的方式。

      因此,此时需要对 Nexus 6 的串行驱动程序 (msm_serial_hs_lite.c) 进行一些相对较小的更改,以支持 KGDB(特别是执行原子字符 I/O 操作的能力)。我刚刚从 Linux 内核主线代码中移植了这些更改,因为一个名为 Stephen Boyd 的小伙子为完整的 MSM (Qualcomm) 串行驱动程序 msm_serial.c 做了艰苦的工作。他的更改可以是found here,或者只是在 Google 上搜索“msm_serial:添加对 poll_ 的支持”。移植并不难,我的代码可以是found on github

      除此之外,您还需要能够为您的 N6 构建自定义内核,谷歌提供了 lots of information on。然后,您需要在 github 存储库中创建一个包含 KGDB 修改的引导映像。我从https://developers.google.com/android/nexus/images 获取了库存内核,提取了它(使用 abootimg -x),然后使用以下命令用我的自定义内核(zImage-dtb)和其他命令行参数重新打包它,以确保 KGDB 将被加载并指向我的串口是这样的:

      abootimg -u boot.img -k zImage-dtb -c 'cmdline=console=ttyHSL0,115200,n8 kgdboc=ttyHSL0,115200 kgdbretry=4'
      

      创建 boot.img 后,我可以使用命令 fastboot boot boot.img 启动它,打开 adb shell,然后使用以下命令在 Android 内核中触发断点:

      echo -n g > /proc/sysrq-trigger
      

      值得一提的是,您需要超级用户权限才能访问 /proc/sysrq-trigger,因此您需要拥有 root 权限。

      在电话停止并连接调试电缆的情况下,在主机 PC 上启动 GDB for ARM 版本,并将未压缩的内核作为参数(例如 arm-eabi-gdb ./vmlinux)。注意:我正在运行 Ubuntu 14.04 并使用 AOSP 源存储库中“prebuilts”目录中的 arm-eabi-gdb。最后,输入以下命令:

      set remoteflow off
      set remotebaud 115200
      target remote /dev/ttyUSB0
      

      一切顺利,这应该会立即进入 kgdb 断点(您对 /proc/sysrq-trigger 的写入产生的断点),然后您就可以开始调试了。

      【讨论】:

      • 你能从链接中添加一些内容吗?
      • 嗨@罗伯特。我想问为什么这是必要的,但我想你的意思是万一链接将来消失?我会尝试在帖子中进行总结。谢谢。
      • 嗨,安迪,是的,这正是我的意思。对不起,应该更清楚。
      猜你喜欢
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 2013-03-17
      • 2018-02-08
      • 2020-01-27
      • 2011-10-03
      • 2019-03-19
      相关资源
      最近更新 更多