完成在标准内核基础上的android系统的suspend to disk后,又采取了tuxonice补丁的方式进行比较,发现由于压缩的缘故,速度有所提高10s左右。
该范方案的实现我是根据我的一位离职的同事写学习笔记进行测试,实验证明是可行的,以下部分程序的讲解我也直接进行了引用。
要是大家遇到啥问题,可以一起讨论。。。。。
概要:
5. 性能指标及优化
1、加快开机时间
2、对镜像进行压缩,减小镜像的大小,用以保证存储速度。
研发平台:
硬件:grus开发板(JZ4780)
软件:Android(4.1)
参考文档:
kernel/Documenation/power下的:
swsusp.txt
swsusp-and-swap-files.txt
swsusp-dmcrypt.txt
文档摘要:
You need to appendresume=/dev/your_swap_partition to kernel command
line. Then you suspend by
echo shutdown > /sys/power/disk; echo disk > /sys/power/state
Make sure the disk drivers are built into kernel, not modules.
In the meantime while the system is suspended you should not add/remove any
of the hardware, write to the filesystems, etc.
c. Bootloaderconfiguration.
Using TuxOnIce also requires that you add an extra parameter to
your lilo.conf or equivalent. Here's an example for a swap partition:
append="resume=swap:/dev/hda1"
This would tell TuxOnIce that /dev/hda1 is a swap partition you
have. TuxOnIce will use the swap signature of this partition as a
pointer to your data when you hibernate. This means that (in this example)
/dev/hda1 doesn't need to be _the_ swap partition where all of your data
is actually stored. It just needs to be a swap partition that has a
valid signature.
1、使用的补丁的演变流程:
swsusp( software suspend) -> suspend2 -> TuxOnIce
官网下载内核补丁:http://tuxonice.net/(版本和平台很多,自己去选,但是没有给出MIPS的实现。)
2、打补丁:
patch -p1 < current-tuxonice-for-3.0.patch
或者
catcurrent-tuxonice-for-3.0.patch | patch -p1
打补丁时会出现冲突,若两个文件有冲突,手动合并。
3、配置内核选项:
CONFIG_HIBERNATION
4、编译会报错,请修改修改mm/ashmem.c 第312行参数少一个(请根据实际情况)
5、镜像保存
(1)使用文件保存image:
echo "TuxOnIce" > /hibernation-file
dd if=/dev/zero bs=1M count=512 >> /flash/hibernation-file
echo /flash/hibernation-file > /sys/power/tuxonice/file/target
cat /sys/power/tuxonice/resume
(2)创建swap分区:
使用fdisk,先创建分区,然后使用命令“t”,转换为Linux Swap格式的分区(82)
设置swap分区:
busybox mkswap /dev/block/mmcblk0p4
激活swap分区:
busybox swapon /dev/block/mmcblk0p4
查看swap是否激活:
busybox free
出现的问题及解决方案:
如果在bootloader中配置resume=swap:/dev/block/mmcblk0p4的话,会报找不到signature。不加的话,会报No image found。
TuxOnIce: Can't translate"/dev/block/mmcblk0p4" into a device id yet.
出现的原因以及解决方法:
do_mounts.c中的name_to_dev_t()函数没有很好的机制处理“/dev/block/mmcblk0p4”这个字符窜,只能改为”/dev/mmcblk0p4"了,然后再在resume函数中字节写入设备的设备号。
MMC驱动或NAND驱动初始化的时间比较靠后,自己想办法解决,我才去的是调驱动加载顺序和在调用try_to_open_resume_device前加延时来解决的。
当我们执行echo > /sys/power/tuxonice/do_hibernate时:
toi_main_wrapper -> toi_try_hibernate:
1). do_toi_step(STEP_HIBERNATE_PREPARE_IMAGE) -> do_prepare_image() 准备存储介质
(a)如果有有效的介质,直接返回。
(b)否则的话,通过can_hibernate() ->toi_attemp_to_parse_resume_device(0)遍历Allocator链表(其实就file或swap两种),如果某一种使能了,调用其parse_sig_location(resume_file)方法。resume_file的内容就是commandline中增加的“swap:XXX或file:XXX”。
toi_bio_parse_sig_location():
(a)首先通过try_to_open_resume_device()把swap:DEVNAME中的DEVNAME转化为dev_t类型,以mmcblk0p4为例,返回“TuxOnIce got bdev 8c0104e0 for dev_tb300004”,并将dev_t设备打开。
(b)然后通过toi_bio_image_exists()判断是否存在image。主要是通过toi_check_for_signature()检查是否存在相应的signature.现在因为还没有存储过image,返回的是“TuxOnIce: No image found."。”TOI_CAN_HIBERNATE和TOI_CAN_RESUME”会被置位。
2). toi_init 开始一个hibernate流程
pm_notifier_call_chain(PM_HIBERNATION_PREPARE):通知链广播; toi_start_other_threads()可能跟多核操作有关,现在没有启动任何线程。
usermodehelper_disable():内核态调用用户态命令的方法
toi_get_zeroed_page(37, TOI_ATOMIC_GFP):分配这个缓冲区。
3).toi_prepare_image(): freeze process, 检查image size的限定条件是否满足, 做其他跟保存image相关的所有操作。
attemp_to_freeze(): try to freezeprocess.正常Android界面无法freeze process,现在是在Recovery界面,除了sh外无其他用户进程。
toi_bio_storage_available():计算有多大可用存储空间,包括swap和file。
toi_recalculate_image_contents():计算Memory大小。
eat_memory():释放内存。
但是当前空闲内存是足够用的,但是抛出来“Seeking to free 83MB of memory.”内存不够用,问题和前面说的是一样的,处理方法也是一样的。
4). save image。
5). 后处理 STEP_HIBERNATE_POWERDOWN 主要是power down。do_post_image_write()
测了一下开关机速度,在正常Android待机画面,关机40秒(其中sync文件系统15-18秒),开机20秒
增加pmem后的速度:关机45秒,开机24秒。
先算出压缩前后的镜像大小。
TOI: manually save pmem in highmem zone.
Count data pages with pmem: Set1 (19497) + Set2 (79895) + Nosave (161885) +NumFree (25443) = 286720.
<< before write pageset2 -- toi_images_bytes:0 >>
<< before write pageset2 -- toi_compress_bytes_in:0,toi_compress_bytes_out:0. >>
Writing caches...
...20%...40%...60%...80%
<< after write pageset2 -- toi_images_bytes:175481656 >>
<< after write pageset2 -- toi_compress_bytes_in:327249920,toi_compress_bytes_out:175521730. >>
注:327249920 = Set2(79895) * 4K 压缩率:53.6%
........
Count data pages without pmem: Set1 (19449) + Set2 (55319) + Nosave (161885) +NumFree (25491) = 262144.
TOI: manually save pmem in highmem zone.
Count data pages with pmem: Set1 (19449) + Set2 (79895) + Nosave (161885) +NumFree (25491) = 286720.
Writing kernel & process data...
...20%...40%...60%...80%
<< after write pageset1 -- toi_images_bytes:211295406 >>
<< after write pageset1 -- toi_compress_bytes_in:406913024,toi_compress_bytes_out:211348757. >>
注:406913024 -327249920 = 79663104 = Set1 (19449) * 4K 压缩率:(211295406 - 175481656)/ 79663104 = 45%
合计:压缩前镜像大小388M, 镜像大小202M,压缩率:52%
优化的几个方法:
· 关机时做一次GC
· kill掉除系统服务以外的其他应用程序