最近遇到一个问题,项目初期阶段,刚开机串口输入输出都正常,高通平台Android O kernel 3.18跑起来大概30-40s串口没有打印输出了,只有输入, eng/userdebug/user都一样。

先看kernel log:

[    4.891514] msm_hsl_console_setup: console setup on port #0
[ 4.896076] console [ttyHSL0] enabled
[ 4.903353] bootconsole [uart0] disabled
[ 4.912299] msm_serial_hsl_init: driver initialized

看下代码kernel/printk/printk.c:register_console

/*   
* By unregistering the bootconsoles after we enable the real console
* we get the "console xxx enabled" message on all the consoles -
* boot consoles, real consoles, etc - this is to ensure that end
* users know there might be something in the kernel's log buffer that
* went to the bootconsole (that they do not see on the real console)
*/
pr_info("%sconsole [%s%d] enabled\n",
(newcon->flags & CON_BOOT) ? "boot" : "" ,
newcon->name, newcon->index);

ttyHSL0才是real console,bootconsole disable和这个问题没关系。

怀疑被重定向, 杀log相关进程不好使,改脚本去掉log进程服务,删log apk,因bringup阶段版本问题较多,稍耗时。

init.rc会起个console进程:

on property:ro.debuggable=1
# Give writes to anyone for the trace folder on debug builds.
# The folder is used to store method traces.
chmod 0773 /data/misc/trace
start console

cmd窗口下ps能看到

shell     6825  1     8060   1692  n_tty_read 7f98bac438 S /system/bin/sh

试了下stop console串口就不能输入了,再start console,可以输入但问题还在,dmesg看了下,有个错误:

[   17.338918] init: setpgid failed for console: Operation not permitted

权限问题? BoardConfig.mk的cmdline加入selinux=permissive,问题还在,看了下是Android O新加的,具体在system/core/init/service.cpp:

void Service::SetProcessAttributes() {
// Keep capabilites on uid change.
if (capabilities_.any() && uid_) {
if (prctl(PR_SET_SECUREBITS, SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED) != 0) {
PLOG(FATAL) << "prtcl(PR_SET_KEEPCAPS) failed for " << name_;
}
}

// TODO: work out why this fails for `console` then upgrade to FATAL.
if (setpgid(0, getpid()) == -1) PLOG(ERROR) << "setpgid failed for " << name_;

浏览kernel/logcat,忽然想到kernel log level, 和Android N对比,确实有差异。

最后到device一看, 居然是msm 默认行为:]