安卓内核调试

61

我一直在尝试让 kgdb 在 Nexus One 上工作。

我从 https://android.googlesource.com 获取了内核,并在使用 menuconfig 时启用了与 kgdb 有关的所有内容,包括 kgdbts 测试。成功构建了内核,并刷入了设备(该设备已解锁,带 root 权限,运行 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

然后连接到内核的调试会话。

我还测试了使用/proc/sysrq-triggerbc确认我能够向sysrq传递一些命令。

所以,根据我尽可能提供的信息,我要问的问题是为什么g不能触发调试器?

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

(我还尝试在内核命令行中放置kdgbwait,但没有成功,因为我认为这在Android内核中尚未得到支持)


所以我继续研究了一下,并发现了以下内容... - metta world peace
13
好奇你找到了什么 :) - Tyler
1
以下内容在哪里? - Mouna Cheikhna
2
他不小心把整个解释都删掉了。 - Cam Jackson
我认为你能够回答我的问题。你能否请回答我的问题?:http://stackoverflow.com/questions/18973701/debugging-android-kernel-passing-arguments-to-android-kernel-while-booting - sattu
显示剩余3条评论
3个回答

6

在[SO]上很少有关于Android内核的问题,因为没有其他人回答,我提供了我在这个问题上的发现。不幸的是,我没有Nexus One来测试这个问题,所以这个答案并不意味着要逐步解决你的问题,但应该指出你应该查找的方向。

我在这个问题上找到的唯一有用的资源是Dongdong Deng的LKML补丁,因此这不太可能是配置问题,因为这些通常很丰富和广泛宣传。

这表明您的内核构建存在问题。我建议您从最新版本的CM开始重新尝试,并查看问题是否会自动解决。

如果失败,请尝试向Cyanogen团队报告此问题,看看是否已知问题或是否有简单的解决方法。

如果万不得已,如果版本兼容,您可以尝试使用补丁。另外一个选择是卷起袖子开始修改CM内核以包含该补丁。

祝你好运。


2

发现了一个相关的帖子,想说一下,我刚刚发布了一些我在Nexus 6上调试内核时所做的工作,如果有人感兴趣:

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

有趣的是,OP关于sysrq的问题我也遇到过。这种行为的原因是KGDB没有正确初始化,因此无法安装'g'(kgdb)触发器的处理程序。这就是为什么所有其他sysrq命令仍然有效的原因。

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

要使其工作,我必须制作一个基于Accuvant博客的UART调试电缆。这是一个相当简单的电路,包括一个FTDI 3.3v基本断路器(目前在SparkFun上可用),以及4个电阻(2 x 1K欧姆,1 x 1.2K欧姆和1 x 100欧姆)和一个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 Kernel主线代码中移植了这些更改,因为一个名叫Stephen Boyd的人已经完成了完整的MSM(Qualcomm)串行驱动程序msm_serial.c的艰苦工作。他的更改可以在这里找到,或者在Google上搜索“msm_serial:add support for poll_”。端口不难,我的代码可以在Github上找到

除此之外,您需要能够为您的N6构建自定义内核,Google提供了大量信息。然后,您需要创建一个包含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上启动ARM版本的GDB并使用未压缩内核作为参数(例如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触发的),然后你可以开始调试。


你能否也添加一些来自链接的内容? - Robert
1
嗨@Robert。我本来想问为什么这是必要的,但我猜你的意思是以防将来链接失效?我会在帖子中尝试总结。谢谢。 - Andy Monaghan
嗨,安迪,是的,那正是我想表达的意思。抱歉,应该说得更清楚些。 - Robert

2
我对Android硬件没有经验,但我曾经将kgdb编译的内核作为VirtualBox客户端运行,并通过虚拟串口从主机连接到客户端,并使用gdb(使用标准的“target remote”命令)可以使用kgdbwait帮助我跟踪整个虚拟客户端内核的引导过程。如果没有这个,我可以编写一个内核模块,该模块除了实现调用“int 13”(即0xcc)的内联汇编外,什么都不做。一旦加载,主机端的串口连接会出现断点,然后我就可以设置断点并继续执行内核。这是因为kgdb处理异常“int 13”。如果您明确创建其他类型的异常,例如“*p = 0”,其中p指向空值,则仍会出现断点,但我怀疑您是否可以继续执行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接