1. 程式人生 > >電源管理之android核心suspend to disk的實現(九)--tuxonice實現方案

電源管理之android核心suspend to disk的實現(九)--tuxonice實現方案

完成在標準核心基礎上的android系統的suspend to disk後,又採取了tuxonice補丁的方式進行比較,發現由於壓縮的緣故,速度有所提高10s左右。

該範方案的實現我是根據我的一位離職的同事寫學習筆記進行測試,實驗證明是可行的,以下部分程式的講解我也直接進行了引用。

要是大家遇到啥問題,可以一起討論。。。。。

概要:

1.目標

2.概要

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掉除系統服務以外的其他應用程式

·        不是儲存任意時刻的狀態,而是儲存系統啟動必經的checkpoint,之後再去啟動其他應用。