电源管理之android内核suspend to disk的实现(七)--方案的选择与问题解决
一、实现android系统hibernation的方案分析:实现方案分析: 方案一: linux标准内核实现 android标准内核的代码是由linux内核演变而来,只要解决android系统独特的wakelock问题,并提供交换分区的支持,就能实现android系统的hibernation。 方案二: tuxonice内核补丁实现 t
五、实现android系统hibernation的方案分析:
实现方案分析:
方案一: linux标准内核实现
android标准内核的代码是由linux内核演变而来,只要解决android系统独特的wakelock问题,并提供交换分区的支持,就能实现android系统的hibernation。
方案二: tuxonice内核补丁实现
tuxonice是专门为实现android系统hibernation的补丁,但是由于大部分是支持arm架构的,故代码有部分存在兼容性差的问题,而且补丁本身也存在部分问题,依照网上的例程来看,对于移动设备而言,开机时间时间大约在50+秒。(后面还会介绍该方案的实现。)
存储方案分析:
方案一、image存储在SD卡
能够创建swap分区,支持android系统的hibernation功能;并且sd卡驱动加载靠前,能够完成resume操作。
方案二、image存储在nand flash
能够创建swap分区,支持android系统的hibernation功能;但是分区的创建在resume之后,现阶段还不能够resume功能。
随后,我解决了该项问题,在内核中配置了early_init(Machineselection),让驱动的加载的时间提前了,但是问题又出来了,nand的读取速度并没有SD卡的读取速度快,且读取时超级不稳定,造成后期系统起不来的,需擦出后再烧写才能正常工作。(这就涉及到前面说的驱动加载顺序的调整问题。)
综上所述:
优先选择在SD卡创建交换分区的linux标准内核实现方案。
具体的实现:
1、内核配置使其支持hibernation功能;
2、解决android wake_lock问题:a、直接强制解锁,需要借鉴STR(suspend to RAM)中的解锁方法wake_unlock;b、直接借鉴STR浅度睡眠方式。这两种方法对STR流程比较熟悉才行,看好前面的文章哦。
3、解决开机启动的问题,需要提供存放镜像的路径,再开机加载resume的时候能够找到镜像。
4、解决以下问题。
六、实现过程中遇到的问题及问题的解决方案:
1、在冻结进程过程中由于存在非超时锁进程被终止。
原因分析:Android相比标准的Linux内核,在电源管理中加入了wake lock机制。
WakeLock在Android的电源管理系统中扮演一个核心的角色.Wake Lock是一种锁的机制,只要有人拿着这个锁,系统就无法进入休眠,可以被用户态程序和内核获得。这个锁可以是有超时的或者是没有超时的,超时的锁会在时间过去以后自动解锁。如果没有锁了或者超时了,内核就会启动休眠的那套机制来进入休眠。
当进入到suspend_prepare()中以后, 它会给suspend分配一个虚拟终端来输出信 息, 然后广播一个系统要进入suspend的Notify, 关闭掉用户态的helper进程, 然后一次调用suspend_freeze_processes()冻结所有的进程, 这里会保存所有进程 当前的状态, 也许有一些进程会拒绝进入冻结状态, 当有这样的进程存在的时候, 会导致冻结失败,此函数就会放弃冻结进程,并且解冻刚才冻结的所有进程.
解决方案:在冻结进程前,调用修改过的 wake_unlock(&main_wake_lock);对main锁进行解锁操作,具体操作可以询问,这里就不多讲了。
2、在creat image过程中出现内存不足的问题。
原因分析:经检查内存中内存还足够使用,但是会报内存不足的问题,这个问题确实很纠结,找了还长时间。
在内核中计算NORMAL_ZONE的方法与我们平台的实际情况不符合。根据bootloader传递来的“mem=...”的参数,kernel算出最大和最小的PFN范围,这部分涉及到内核高低端内存的计算与适用平台是否兼容的问题,这个问题对于JZ4780是存在的,其他平台可能兼容。(具体操作请询问)
解决方案:根本原因在于kernel与君正的内核不兼容的缘故,我们需要调整内核中内存的布局才能解决该问题,添加了NORMALMEM_END宏,定义为256M。
3、创建swap分区。
原因分析:hibernation功能是基于交换分区实现的,主要是将image写到swap分区,予以保存image,但是我们的android使用的存储介质是nand falsh,不存在交换分区,故需要在SD卡或者nand flash上创建是swap分区。
解决方案:
busyboxfdisk /dev/block/mmcblk0
busyboxmkswap /dev/block/mmcblk0p1
busyboxswapon /dev/block/mmcblk0p1
4、resume问题。
原因分析:内核文档中“You need to appendresume=/dev/your_swap_partition to kernel command”,我们需要向内核中传递image所在的设备节点。但是又出现了问题,我直接在内核中进行了修改
解决方案:如果在bootloader中配置resume=swap:/dev/block/mmcblk0p1
但是问题是不能解决的,在bootloader中配置resume=swap:/dev/block/mmcblk0p4的话,会报找不到signature。不加的话,会报No image found。原因是:do_mounts.c中的name_to_dev_t()函数没有很好的机制处理“/dev/block/mmcblk0p4”这个字符窜,暂时改为”/dev/mmcblk0p4"了,从网上来看可能还存在另一个原因,MMC驱动初始化的时间比较靠后,通过blk_lookup_devt()函数去查找block设备时还没有注册呢。暂时在调用try_to_open_resume_device前加了个1s的延时。
个人观点,有问题请斧正!!
转载请注明出处:http://blog.csdn.net/wang_zheng_kai
更多推荐
所有评论(0)