bootchart本是一个开源工具,用可视化的方式对GUN/LINUX的开机启动过程进行性能分析,包括资源的使用,如CPU,磁盘等,各进程的执行时间等信息。根据分析结果,确定系统启动的性能瓶颈,制定相应的优化策略。关于bootchart的来历和说明件其官方网站:点击打开链接
Android系统中已有一份bootchart的c实现,位于system/core/init/bootchart.c中。bootchart对Android开机测量是通过内建在init进程中实现的,在后台执行测量。不过bootchart的测量时段是从bootchart被初始化之后到home screen出来之前,不包括bootloader和kernel的执行时间。
我的系统是UBuntu10.04,现将整个使用步骤归纳如下:
1)、UBuntu下bootchart工具的安装
2)、bootchart在Android下的编译
3)、bootchart在Android下的执行
4)、bootchart测量结果的图形化过程
下面依次对上述四个步骤进行详细说明。
1、UBuntu下bootchart工具的安装
需要安装的工具有两个bootchart和pybootchartgui,执行命令如下:
- sudo apt-get install bootchart
- sudo apt-get install pybootchartgui
2、bootchart在Android下的编译
Android系统编译时,默认的没有打开bootchart的编译开关,即没有把bootchart编译进系统中。要把bootchart编进系统分为两种情况了:
1)、系统没有被编译过或者执行了make clean命令,可以执行以下命令:
- $ cd mydroid
- $ export INIT_BOOTCHART=true
- $ make clean
- $ make
- $ touch system/core/init/init.c
- $ m INIT_BOOTCHART=true
其中touch命令的作用就是将init.c文件的最后修改时间改为当前时间,这样保证init.c文件会被重新make,而bootchart就是在init.c中被调用的,从而保证bootchart会被编进系统中。
3、bootchart在Android下的执行
1}、将编译生成的带有bootchart工具的Android系统重新烧录到开发板上,并启动系统
2)、在UBuntu上通过adb connect连接到开发板,然后执行:
- $ adb shell 'echo 120 > /data/bootchart-start'
3)、执行命令:
- $ adb shell 'mkdir /data/bootchart'
4)、重新启动开发板,在开发板的Android系统的/data/bootchart/目录下将看到以下文件:
- # ls -l
- -rw-rw-rw- root root 452 2010-01-01 00:00 header
- -rw-r--r-- root root 0 2010-01-01 00:00 kernel_pacct
- -rwxr-xr-x root root 1020195 2010-01-01 00:02 proc_diskstats.log
- -rwxr-xr-x root root 4252966 2010-01-01 00:02 proc_ps.log
- -rwxr-xr-x root root 138215 2010-01-01 00:02 proc_stat.log
4、bootchart测量结果的图形化过程
1)、到这里要夸奖下android做的比较贴心,已经写好了脚本将bootchart测量生成的数据直接从开发板上打包出来,生成bootchart.tgz。这个打包脚是源码的system/core/init/grab-bootchart.sh文件,和bootchart源码位于同一目录下。脚本的内容如下:
- #!/bin/sh
- #
- # this script is used to retrieve the bootchart log generated
- # by init when compiled with INIT_BOOTCHART=true.
- #
- # for all details, see //device/system/init/README.BOOTCHART
- #
- TMPDIR=/tmp/android-bootchart
- rm -rf $TMPDIR
- mkdir -p $TMPDIR
- LOGROOT=/data/bootchart
- TARBALL=bootchart.tgz
- FILES="header proc_stat.log proc_ps.log proc_diskstats.log kernel_pacct"
- for f in $FILES; do
- adb pull $LOGROOT/$f $TMPDIR/$f 2>&1 > /dev/null
- done
- (cd $TMPDIR && tar -czf $TARBALL $FILES)
- cp -f $TMPDIR/$TARBALL ./$TARBALL
- echo "look at $TARBALL"
2)、在bootchart.tgz所在目录下执行命令:
- $bootchart ./bootchart.tgz
5、问题总结
在执行第4步的2)时,即执行命令:
- $bootchart ./bootchart.tgz
- parsing './bootchart.tgz'
- parsing 'header'
- parsing 'proc_stat.log'
- parsing 'proc_ps.log'
- warning: no parent for pid '2' with ppid '0'
- parsing 'proc_diskstats.log'
- parsing 'kernel_pacct'
- merged 0 logger processes
- pruned 61 process, 0 exploders, 2 threads, and 0 runs
- False
- Traceback (most recent call last):
- File "/usr/bin/bootchart", line 23, in <module>
- sys.exit(main())
- File "/usr/lib/pymodules/python2.7/pybootchartgui/main.py", line 137, in main
- render()
- File "/usr/lib/pymodules/python2.7/pybootchartgui/main.py", line 128, in render
- batch.render(writer, res, options, filename)
- File "/usr/lib/pymodules/python2.7/pybootchartgui/batch.py", line 41, in render
- draw.render(ctx, options, *res)
- File "/usr/lib/pymodules/python2.7/pybootchartgui/draw.py", line 282, in render
- draw_chart(ctx, IO_COLOR, True, chart_rect, [(sample.time, sample.util) for sample in disk_stats], proc_tree)
- File "/usr/lib/pymodules/python2.7/pybootchartgui/draw.py", line 201, in draw_chart
- yscale = float(chart_bounds[3]) / max(y for (x,y) in data)
- ZeroDivisionError: float division by zero
- bootchart ./bootchart.tgz