在调试Android的Linux内核时,我们往往会通过打开对应模块的调试Log来查看一些关键信息。通常我们可以使用一些简单的查看方法,比如:
在pc端装有adb工具时,使用adb shell dmesg >D:/Kernel.log
但是dmesg通常只能打印部分Log信息,如果连续输入命令,在保存的日志文件中可能会出现很多重复内容,这是因为dmesg会打印启动后到目前的Log信息。
或者使用:adb shell cat /proc/kmsg
proc/kmsg,不会再打印已经打印的信息,只打印上一次执行之后打印出来的新的信息,但是同样因为缓冲区的原因,kmsg会出现中断。如果在主机端编写脚本定制调用kmesg,由于每次Kmesg结束的时间可能不固定,所以很难设置时间间隔,从而导致Log日志文件出现先后顺序不一样的打印,对于我们分析Log非常不利。
如何让一台android调试手机,能够像Android开发板一样在串口实时打印信息呢?通过各种尝试终于找到了一种解决方案。
软件环境:android 8.0.0 原生代码,msm内核源码,win7系统+CH341驱动。(要使用对应的源码分支和内核分支)
硬件环境:Pixel 手机一部,CH341 USB转串口板2个(淘宝上大把卖,大概十几块钱一个)。
首先请保证你的开发环境可以正常使用,pixel手机可以正常运行你编译的android系统和内核。
三、配置过程
1.在内核编译时,使用make menuconfig或者是直接修改.config文件(如果你有按照android官方内核编译步骤进行过一次config配置,就会生成这个隐藏的.config文件),需要打开这几个配置:CONFIG_USB_SERIAL; CONFIG_USB_SERIAL_CH341;
编译好新内核后,烧入手机。
2.添加CH341的串口设备到内核打印终端列表。这里涉及到了Linux的内核启动和printk的打印机制,推荐大家可以了解下关于这方面的相关知识。
推荐个地址:https://blog.csdn.net/Luoshengyang/article/details/6595744 老罗写的,虽然内核版本有点老了,但是基本原理都是一样的。
https://blog.csdn.net/code__L/article/details/68061455。关于printk的。
这一步的总体思路是这样的,当Linux启动时,boot会传入一些启动参数,其中就包括内核打印使用的串口终端。通过解析console_cmdline参数。例如console=ttyS0,115200 console=tty0,115200。
通过一个type C转USB的数据线将手机和CH341连接起来,然后用adb shell查看串口设备名称,比如插拔后新增了ttyUSB0。把这个名称记下来。
如果你能找到boot的启动参数,在console_cmdline中增加console=ttyUSB0,115200即可。
如果找不到,就需要修改printk的代码了。
在static int __init console_setup(char *str)代码中解析了console_cmdline的参数,然后通过__add_preferred_console加入控制台列表中,可以添加参数实现,具体的分析就不累述了。
或者__add_preferred_console(buf, idx, options, brl_options);在这后面重新调用__add_preferred_console(“ttyUSB”, 0, 115200, brl_options);也可实现。
修改后重新编译内核,烧入手机。
三、连接调试
按上图连接好后,在PC上就可以打开串口软件查看内核的打印信息了。
本文仅供参考学习,如要转载请注明出处,谢谢!