Linux suspend-to-disk 流程分析

1. 实验平台

cpu: omap4460 blaze tablet

memory: 1-GB DRAM

OS: android 4.0.3, kernel 3.0.31


2.流程分析

2.1 create and save image procedure
1).  echo "disk" > /sys/power/state
2). state_store() kernel/power/main.c
3). hibernate()  kernel/power/hibernate.c
         pm_prepare_console()
         pm_notifier_call_chain(PM_HIBERNATION_PREPARE)
         usermodehelper_disable()
             //usermode enables multiple virtual linux systems (known as guests) to run as an application within a normal Linux system (known as the host)
             //from wiki usermode
         create_basic_memory_bitmaps()
             //create bitmaps needed for marking page frames that should not be saved and free page frames.
             //forbidden_pages_map, free_pages_map
         sys_sync()
         prepare_processes()
             freeze_processes() kernel/power/process.c
                 //freeze user space process and kernel task  
         hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM)
             //hibernation_mode=HIBERNATION_SHUTDOWN
             //Quiesce devices and create a hibernation image  
4). hibernation_snapshot() 
         dpm_prepare(PMSG_FREEZE) drivers/base/power/main.c
             //execute ->prepare() callback for all non-sysdev devices, device list movement dpm_list-->dpm_prepared_list
         hibernate_preallocate_memory()  kernel/power/snapshot.c
             //Preallocate memory for hibernation image
         suspend_console()
         pm_restrict_gfp_mask()
             //avoid i/o and fs to allocate memory during suspend procedure
             //clear bit GFP_IOFS of gfp_allowed_mask
         dpm_suspend(PMSG_FREEZE)
             //execute ->suspend() callback for all non-sysdev devices, device list movement dpm_prepared_list-->dpm_suspended_list 
5). create_image()
         dpm_suspend_noirq(PMSG_FREEZE) 
             //execute "late suspend"
             suspend_device_irqs() kernel/irq/pm.c
                 //disable all currently enabled interrupt lines
                 //after this function, device will can't receive interrupt
             device_suspend_noirq()
                 //execute -->suspend_noirq callback for all non-sysdev devices, device list movement dpm_suspended_list-->dpm_noirq_list             
         disable_nonboot_cpus()
         local_irq_disable()
         syscore_suspend()  driver/base/syscore.c
             //execute all the registered system core suspend callbacks
             //all system core devices linked with syscore_ops_list 
         pm_wakeup_pending()
             //Check if power transition in progress should be aborted.
         //set in_suspend to 1 ,it is saved in nosave section of ELF format
         save_processor_state()  include/linux/suspend.h
             preempt_disable()  include/linux/preempt.h
         swsusp_arch_suspend()  arch/arm/kernel/swsusp.S <patch from swsusp>
             //Save the current CPU state to memory
             //store cpu's registers to memory address ctx in turn
             //system mode register:cpsr,r0--14
             //supervisor mode register: spsr,sp,lr             
	adr	r0, ctx
	mrs	r1, cpsr
	stm	r0!, {r1}		/* current CPSR */
	msr	cpsr_c, #SYSTEM_MODE
	stm	r0!, {r0-r14}		/* user regs */
	msr	cpsr_c, #SVC_MODE
	mrs	r2, spsr
	stm	r0!, {r2, sp, lr}	/* SVC SPSR, SVC regs */
	msr	cpsr, r1		/* restore original mode */
             __save_processor_state  arch/arm/mach-omap2/sleep44xx.S
                 //store r0--12,lr to stack
                 //store CPU CP15 registers to memory address ctx in turn
                 // sp,spsr,lr
                 //c1,c2,c3,c10,c12,c13,cpsr,c1_controler_register
                 blv7_flush_dcache_all
                     //Flush all data from the L1 data cache before disabling SCTLR.C bit
                 //Clear the SCTLR.C bit to prevent further data cache allocation. Clearing SCTLR.C would make all the data accesses strongly ordered and would not hit the cache.
                 //pop stack to r0--12,pc; so this is sub function(__save_processor_state) return
         b swsusp_save  
             //swsusp_save is a C-function, it exit will cause  swsusp_arch_suspend return
             swsusp_save()  kernel/power/snapshot.c
                 //Creating hibernation image
                 swsusp_alloc()
                     //allocate memory for the suspend image
                 drain_local_pages(NULL)  mm/page_alloc.c
                     //Spill all of this CPU's per-cpu pages back into the buddy allocator
                 copy_data_pages(&copy_bm, &orig_bm)                     
         restore_processor_state()  include/linux/suspend.h
             preempt_enable()   
         syscore_resume()
             //Execute all the registered system core resume callbacks.  
         local_irq_enable()
         enable_nonboot_cpus()
         dpm_resume_noirq(PMSG_RECOVER)
             device_resume_noirq()
                 //Execute an "early resume" callback for given device, device list movement dpm_noirq_list-->dpm_suspended_list
             resume_device_irqs() kernel/irq/pm.c
                 //enable interrupt lines disabled by suspend_device_irqs()  
         dpm_resume( PMSG_RECOVER)
         resume_console()
         dpm_complete( PMSG_RECOVER)  
         swsusp_write()
         swsusp_free()
         power_down()

2.2 power on and restore procedure
              

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值