Android 日志系统logcat内核代码分析
前一篇文章:http://blog.csdn.net/andyhuabing/article/details/8547719 简要介绍了log系统的上层使用方法,本文重点分
析其log内核驱动代码,使得我们对Android日志系统有一个深刻的认识。
内核代码路径:
kernel/drivers/staging/android/logger.h
kernel/drivers/staging/android/logger.c
1、Logger驱动程序的相关数据结构
首先来看logger.h头文件的内容:
/* * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the * user-space buffer 'buf'. Returns 'count' on success. * * Caller must hold log->mutex. */static ssize_t do_read_log_to_user(struct logger_log *log, struct logger_reader *reader, char __user *buf, size_t count){size_t len;/* * We read from the log in two disjoint operations. First, we read from * the current read head offset up to 'count' bytes or to the end of * the log, whichever comes first. */len = min(count, log->size - reader->r_off);if (copy_to_user(buf, log->buffer + reader->r_off, len))return -EFAULT;/* * Second, we read any remaining bytes, starting back at the head of * the log. */if (count != len)if (copy_to_user(buf + len, log->buffer, count - len))return -EFAULT;reader->r_off = logger_offset(reader->r_off + count);return count;}根据缓冲区中数据分两段的情况,调用copy_to_user函数来把位于内核空间的日志缓冲区指定的内容拷贝到用户空间的内存缓冲区就可以了,同时,把当前读取日志进程的上下文信息中的读偏移r_off前进到下一条日志记录的开始的位置上。
5、其它函数:
logger_poll 用于log用户态调用select函数进行查询,利用
if (log->w_off != reader->r_off)
ret |= POLLIN | POLLRDNORM;
通知用户是否有有日记需要读取
logger_ioctl 用于一些常用的信息查询,
#define LOGGER_GET_LOG_BUF_SIZE_IO(__LOGGERIO, 1) /* size of log */
#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */
#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */
#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */
获取缓冲区中数据长度,下一个日志的记录,比较有意义的是 LOGGER_FLUSH_LOG:
list_for_each_entry(reader, &log->readers, list)
reader->r_off = log->w_off;
log->head = log->w_off;
清除缓冲区中的所有数据