grep 一下 *defconfig 的 HIBERNATION。
mips, ppc, sh, x86 都有,但是 ARM 沒有。
在 kernel/power/ 下就有 hibernate.c 等需要的 source code。
在 kernel/power/Makefile 中可以看到:
obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \
block_io.o
所以只要在 .config 中 開啟 CONFIG_HIBERNATION=y 就可以了(?)
但是在 make menuconfig 中,沒有 hiberanation 可以選 (Power Management)。
找一下 kernel/power/Kconfig:
config HIBERNATION
bool "Hibernation (aka 'suspend to disk')"
depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
select SUSPEND_NVS if HAS_IOMEM
所以要找 PM 跟 SWAP 跟 ARCH_HIBERNATION_POSSIBLE。
find . -type f -name 'Kconfig' | xargs grep --color ARCH_HIBERNATION_POSSIBLE
結果 arch 下的 mips, sh, x86, s390, powerpc, 都有 這個選項, arm 沒有。
所以修改一下 arch/arm/Kconfig,抄一下其他 arch 的 ARCH_HIBERNATION_POSSIBLE 選項,,
大概就是...
config ARCH_HIBERNATION_POSSIBLE
bool
default y
學一下,寫在 ARCH_SUSPEND_POSSIBLE 後面,因為是在 Power management options ,所以待會 make menuconfig 在 Powermanagement 中會有 hibernation 可以選
因為 default y,所以是 checked
這樣做完就 build 的話,會有 error:
kernel/power/hibernate.c:27:25: error: asm/suspend.h: No such file or directory
kernel/power/hibernate.c: In function 'create_image':
kernel/power/hibernate.c:245: error: implicit declaration of function 'arch_prepare_suspend'
make[2]: *** [kernel/power/hibernate.o] Error 1
make[1]: *** [kernel/power] Error 2
make: *** [kernel] Error 2
make: *** Waiting for unfinished jobs....
缺 asm/suspend.h,就學簡單的,create 一個 arch/arm/include/suspend.h ,宣告一下..
static inline int arch_prepare_suspend(void) { return 0; }
接著 build,出現的 error 是:
arm-eabi-4.4.3/bin/arm-eabi-ld: kernel/built-in.o: in function hibernation_restore:elfcore.c(.text+0x349a8): error: undefined reference to 'save_processor_state'
arm-eabi-4.4.3/bin/arm-eabi-ld: kernel/built-in.o: in function hibernation_restore:elfcore.c(.text+0x349b8): error: undefined reference to 'swsusp_arch_resume'
arm-eabi-4.4.3/bin/arm-eabi-ld: kernel/built-in.o: in function hibernation_restore:elfcore.c(.text+0x349d8): error: undefined reference to 'restore_processor_state'
arm-eabi-ld: kernel/built-in.o: in function hibernation_snapshot:elfcore.c(.text+0x34d40): error: undefined reference to 'save_processor_state'
arm-eabi-ld: kernel/built-in.o: in function hibernation_snapshot:elfcore.c(.text+0x34d44): error: undefined reference to 'swsusp_arch_suspend'
arm-eabi-ld: kernel/built-in.o: in function hibernation_snapshot:elfcore.c(.text+0x34d5c): error: undefined reference to 'restore_processor_state'
arm-eabi-ld: kernel/built-in.o: in function saveable_page:snapshot.c(.text+0x36458): error: undefined reference to 'pfn_is_nosave'
make: *** [.tmp_vmlinux1] Error 1
沒作的有:
save_processor_state,restore_processor_state ---- kernel/power/hibernate.c使用
swsusp_arch_suspend, swsusp_arch_resume ---- kernel/power/hibernate.c 使用
pfn_is_nosave --- kernel/power/snapshot.c 使用
就抄那個 HIYOSHI 的 patch。
其中 NOSAVEDATA section in lds.S 上了 build 會有錯 (MACRO的原因?)。
ok 後,把 busybox 放上root。開始測試..
開機,make swap ...
# busybox mkswap /dev/block/mmcblk0p4
#busybox swapon /dev/block/mmcblk0p4
開始 hiberate..
# echo disk > /sys/power/state
會看到進suspend, user process 進 refrigerator. write image into partition..
最後是 manually power off ..
斷電,開機進入 uboot command console, 修改 boot argument..
要加上
resume=???
告訴 kernel 從哪一個 partition 拿 image。
原來想用
resume=/dev/block/mmcblk0p4
但是這樣 resume 會說 "/dev/block/mmcblk0p4" 是 null device。
查一下是 init/do_mount.c : name_to_dev_t( ) 的問題,好像不 support 兩層 path。
funciton 的說明是:
/*
* Convert a name into device number. We accept the following variants:
*
* 1) device number in hexadecimal represents itself
* 2) /dev/nfs represents Root_NFS (0xff)
* 3) /dev/ represents the device number of disk
* 4) /dev/ represents the device number
* of partition - device number of disk plus the partition number
* 5) /dev/p - same as the above, that form is
* used when disk name of partitioned disk ends on a digit.
*
* If name doesn't have fall into the categories above, we return (0,0).
* block_class is used to check if something is a disk name. If the disk
* name contains slashes, the device name has them replaced with
* bangs.
*/
只好用第一項 device number in hexdecimal represets itself
ls -l /dev/block 來看,
/dev/block/mmcblk0p4 是 179:4
所以改一下 boot argument..
resume=179:4
就可以正確找到 resume partition, restor
但是 resume 後...卡住...停很久....然後才出現 left refrigerator 的 message。
然後出現 console prompt...但是沒反應..