该系列文章总纲链接:专题分纲目录 android 开机启动流程分析
本章关键点总结 & 说明:
说明:思维导图是基于之前文章不断迭代的,本章内容我们关注➕"bootchart"部分即可
1 bootchart源码框架分析
bootchart框架关键代码实现如下:
#if BOOTCHART
queue_builtin_action(bootchart_init_action, "bootchart_init");//->bootchart_init
#endif
...
for(;;) {
...
#if BOOTCHART
if (bootchart_count > 0) {
if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
timeout = BOOTCHART_POLLING_MS;
if (bootchart_step() < 0 || --bootchart_count == 0) {
bootchart_finish();//资源释放相关操作
bootchart_count = 0;
}
}
#endif
...
}
这里着重分析bootchart_init和bootchart_step
1.1 bootchart_init的实现如下:
#define LOG_ROOT "/data/bootchart"
#define LOG_STAT LOG_ROOT"/proc_stat.log"
#define LOG_PROCS LOG_ROOT"/proc_ps.log"
#define LOG_DISK LOG_ROOT"/proc_diskstats.log"
#define LOG_HEADER LOG_ROOT"/header"
#define LOG_ACCT LOG_ROOT"/kernel_pacct"
#define LOG_STARTFILE "/data/bootchart-start"
#define LOG_STOPFILE "/data/bootchart-stop"
/* called to setup bootcharting */
int bootchart_init( void )
{
...
buff[0] = 0;
proc_read( LOG_STARTFILE, buff, sizeof(buff) );//读取LOG_STARTFILE,获取超时信息,即采样频率
...//超时的处理{读取失败会从kernel中读取默认值,超时最大值10*60}
count = (timeout*1000 + BOOTCHART_POLLING_MS-1)/BOOTCHART_POLLING_MS;
//创建文件夹LOG_ROOT并打开文件LOG_STAT,LOG_PROCS,LOG_DISK
do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR);
file_buff_open(log_stat, LOG_STAT);
file_buff_open(log_procs, LOG_PROCS);
file_buff_open(log_disks, LOG_DISK);
{/* create kernel process accounting file */
int fd = open( LOG_ACCT, O_WRONLY|O_CREAT|O_TRUNC,0644);
...//open错误处理
}
log_header();//向文件LOG_HEADER中写入log头,即一些基本信息
return count;
}
bootchart_init本质上就是创建文件夹与一些初始文件,并打开,准备写入数据
1.2 bootchart_step的实现如下:
/* called each time you want to perform a bootchart sampling op */
int bootchart_step( void )
{
//从proc文进系统下读取各类文件节点的信息,写入到bootchart文件夹下的各类文件中
do_log_file(log_stat, "/proc/stat");
do_log_file(log_disks, "/proc/diskstats");
do_log_procs(log_procs);
//读取文件/data/bootchart-stop,如果包含1,说明结束bootchart程序的执行
{
char buff[2];
if (proc_read(LOG_STOPFILE,buff,sizeof(buff)) > 0 && buff[0] == '1') {
return -1;
}
}
return 0;
}
bootchart_step本质上就是从proc文件系统中读取日志,将其部分加工后写入对应的bootchart目录下的相应文件中
2 bootchart使用流程
2.1 设备端操作
开启宏BOOTCHART,编译全新的android镜像,重新烧写编译了bootchart的boot.img,并且启动系统
在系统data目录创建文件/data/bootchart-start,其内容是bootchart的采样时间:
adb shell 'echo $TIMEOUT > /data/bootchart-start'
#其中$TIMEOUT是期望采样的时间,单位为秒,例如要采样两分钟,则执行:
adb shell 'echo 120 > /data/bootchart-start'
在系统data目录创建/data/bootchart,执行
adb shell 'mkdir /data/bootchart'
#后面要利用这些文件生成可视化图片。
重新启动开发板,在开发板的Android系统的/data/bootchart/目录下将看到以下5个文件组成:
到此为止,bootchart执行测量后生成的测量数据已经完成,看上面有3个log文件
{注意:运行bootchart采样完成后若不再使用bootchart则需手工删除文件/data/bootchart-start,否则开发板每次重启时都会运行bootchart}
在data/bootchart目录执行以下命令生成bootchart.tgz{或者使用android源码打包工具中提供的 grab-bootchart.sh
busybox tar -czf bootchart.tgz *
将生成的bootchart.tgz拷贝到PC端
2.2 PC端操作
ubuntu上安装软件{执行sudo apt-get install bootchart pybootchartgui librsvg2-bin}
使用bootchart bootchart.tgz,生成bootchart.png图表
bootchart ./bootchart.tgz
生成后的png图片如下所示:
效果如上所示,这样就可以很好的分析 开机运行相关问题了。