1.power reason 是怎么得到的?
首先,通过PMIC API pm_get_power_on_status(&pwr_on_status) 来探测出power reason, 然后把power reason 写入共享内存。
这部分主要是在SBL3的代码里实现的。SBL3的code可以在modem的代码里找到。
然后, 在LK里可以通过读取共享内存的函数:
- smem_read_alloc_entry(SMEM_POWER_ON_STATUS_INFO,&power_on_status, status_len);
得到power reason, 我们可以探测到的power reason 有如下:
#define PM_PWR_ON_EVENT_KEYPAD 0x1 #define PM_PWR_ON_EVENT_RTC 0x2 #define PM_PWR_ON_EVENT_CABLE 0x4 #define PM_PWR_ON_EVENT_SMPL 0x8 #define PM_PWR_ON_EVENT_WDOG 0x10 #define PM_PWR_ON_EVENT_USB_CHG 0x20 #define PM_PWR_ON_EVENT_WALL_CHG 0x40
如果你想在LK里判断是否是alarm开机, 你就可以通过函数smem_read_alloc_entry读出power reason 然后判断它是否
等于PM_PWR_ON_EVENT_RTC , 如果相等, 则是alarm开机。
2. 怎么在kernel里得到power reason?
由于power reason是在SBL3里写入共享内存的, 也就是我们的DDR,我们可以找到该物理内存地址,然后在kernel里读取
该内存里的power reason 即可, 但是别忘了在读取该内存地址之前需将该物理地址转换为虚拟地址, 你可以尝试
ioremap_nocache(phy_addr,size)把物理地址转换为虚拟地址, 然后readl(var_addr)读取该地址的内容。
3.如何得到reboot reason?
Reboot reason 是存放在寄存器里的, 寄存器的地址是0x2A05F65C。 在LK里你可以直接读取该地址里的值。
但在kernel里, 你仍然需要按照读取power reason的方式先把物理地址转换为虚拟地址, 然后读取该地址里的
reboot reason。 目前reboot reason 有:
#define RECOVERY_MODE 0x77665502 #define FASTBOOT_MODE 0x77665500