Android Init进程打印

49 阅读3分钟

1. 启动进程init log模块

init启动过程中, logcat模块还没有启动,日志只能输出到终端,或kernel日志系统, 输出到终端会影响启动速率,所以init启动过程日志是输出到kernel日志系统的。
从下面的代码片段,知道启动过程日志是通过LOG接口输入到dev/kmsg文件的。

**

system/core/init/init.cpp
 994         // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
 995         // talk to the outside world...
 996         InitKernelLogging(argv);
 997 
 998         LOG(INFO) << "init first stage started!";
 999 
1000         if (!DoFirstStageMount()) {
1001             LOG(ERROR) << "Failed to mount required partitions early ...";
1002             panic();
1003         }
1004 

system/core/init/log.cpp
 26 void InitKernelLogging(char* argv[]) {
 27     // Make stdin/stdout/stderr all point to /dev/null.
 28     int fd = open("/sys/fs/selinux/null", O_RDWR);
 29     if (fd == -1) {
 30         int saved_errno = errno;
 31         android::base::InitLogging(argv, &android::base::KernelLogger);
 32         errno = saved_errno;
 33         PLOG(FATAL) << "Couldn't open /sys/fs/selinux/null";
 34     }
 35     dup2(fd, 0);
 36     dup2(fd, 1);
 37     dup2(fd, 2);
 38     if (fd > 2) close(fd);
 39  
 40     android::base::InitLogging(argv, &android::base::KernelLogger);
 41 }

system/core/base/logging.cpp
148 #if defined(__linux__)
149 void KernelLogger(android::base::LogId, android::base::LogSeverity severity,
150                   const char* tag, const char*, unsigned int, const char* msg) {
151   // clang-format off
152   static constexpr int kLogSeverityToKernelLogLevel[] = {
153       [android::base::VERBOSE] = 7,              // KERN_DEBUG (there is no verbose kernel log
154                                                  //             level)
155       [android::base::DEBUG] = 7,                // KERN_DEBUG
156       [android::base::INFO] = 6,                 // KERN_INFO
157       [android::base::WARNING] = 4,              // KERN_WARNING
158       [android::base::ERROR] = 3,                // KERN_ERROR
159       [android::base::FATAL_WITHOUT_ABORT] = 2,  // KERN_CRIT
160       [android::base::FATAL] = 2,                // KERN_CRIT
161   };
162   // clang-format on
163   static_assert(arraysize(kLogSeverityToKernelLogLevel) == android::base::FATAL + 1,
164                 "Mismatch in size of kLogSeverityToKernelLogLevel and values in LogSeverity");
165 
166   static int klog_fd = TEMP_FAILURE_RETRY(open("/dev/kmsg", O_WRONLY | O_CLOEXEC));
167   if (klog_fd == -1) return;
168 
169   int level = kLogSeverityToKernelLogLevel[severity];
170 
171   // The kernel's printk buffer is only 1024 bytes.
172   // TODO: should we automatically break up long lines into multiple lines?
173   // Or we could log but with something like "..." at the end?
174   char buf[1024];
175   size_t size = snprintf(buf, sizeof(buf), "<%d>%s: %s\n", level, tag, msg);
176   if (size > sizeof(buf)) {
177     size = snprintf(buf, sizeof(buf), "<%d>%s: %zu-byte message too long for printk\n",
178                     level, tag, size);
179   }
180 
181   iovec iov[1];
182   iov[0].iov_base = buf;
183   iov[0].iov_len = size;
184   TEMP_FAILURE_RETRY(writev(klog_fd, iov, 1));
185 }
186 #endif

2. 打开启动过程log

经过上面问题,init启动过程日志主要是输出到/dev/kmsg, 如果查不到日志,可能日志被刷掉,或者受限kernel日志输出频率,被丢弃掉, 所以增加kernel log缓存和输出频率限制来查看日志,内核对性能要求比较高,这些也是临时修改。

**

diff --git a/bigfish/sdk/source/kernel/linux-4.9.y/include/linux/ratelimit.h b/bigfish/sdk/source/kernel/linux-4.9.y/include/linux/ratelimit.h
index 57c9e0622..d8cc7dba9 100644
--- a/bigfish/sdk/source/kernel/linux-4.9.y/include/linux/ratelimit.h
+++ b/bigfish/sdk/source/kernel/linux-4.9.y/include/linux/ratelimit.h
@@ -6,7 +6,7 @@
 #include <linux/spinlock.h>
 
 #define DEFAULT_RATELIMIT_INTERVAL     (5 * HZ)
-#define DEFAULT_RATELIMIT_BURST                10
+#define DEFAULT_RATELIMIT_BURST                100000
 
 /* issue num suppressed message on exit */
 #define RATELIMIT_MSG_ON_RELEASE       BIT(0)
diff --git a/bigfish/sdk/source/kernel/linux-4.9.y/kernel/printk/printk.c b/bigfish/sdk/source/kernel/linux-4.9.y/kernel/printk/printk.c
index 20fc294fb..9701e0f5a 100644
--- a/bigfish/sdk/source/kernel/linux-4.9.y/kernel/printk/printk.c
+++ b/bigfish/sdk/source/kernel/linux-4.9.y/kernel/printk/printk.c
@@ -388,7 +388,7 @@ static u32 clear_idx;
 
 /* record buffer */
 #define LOG_ALIGN __alignof__(struct printk_log)
-#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
+#define __LOG_BUF_LEN ( 4*1024 *1024 )
 static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
 static char *log_buf = __log_buf;
 static u32 log_buf_len = __LOG_BUF_LEN;

通过 adb shell cat /proc/kmsg > kernel.log输出的kernel.log文件中搜索查看

作者:阿拉贡居民
链接:www.jianshu.com/p/84bda2be2…
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法二

1.  if (!(devkmsg_log & DEVKMSG_LOG_MASK_ON)) {
1.  - if (!___ratelimit(&user->rs, current->comm))
1.  - return ret;
1.  + //if (!___ratelimit(&user->rs, current->comm))
1.  + //return ret;
1.  }
1.  buf = kmalloc(len+1, GFP_KERNEL);