您好,欢迎来到爱go旅游网。
搜索
您的当前位置:首页关机充电cmdline进入充电流程简要分析

关机充电cmdline进入充电流程简要分析

来源:爱go旅游网


目 录

1. 概述 .......................................................................................................................... 2 2. modm部分开机原因 ................................................................................................ 2 3. LK与kernel部分设置充电模式 ............................................................................. 4 4. Android进入充电模式 ............................................................................................. 6

i

深圳国速科技有限公司

1. 概述

本文档将要分析手机充电模式下的流程,用android4.0的代码分析在关机时插入USB到android识别为充电模式的大致过程。主要涉及模块有高通modem部分、LK的cmdline部分、kernel的cmdline部分、android的init部分和android的charger部分。最为关键的是LK部分使启动模式进入充电模式,android才能具体的识别为充电模式。 2. modm部分开机原因

在USB插入时最先检测到USB插入的是PMIC,这时会触发一个上电时序,在代码执行到oemsbl_mc.c的oemsbl_shared_ram_init( )函数用于初始化共享内存时,会进入如下流程:

oemsbl_shared_ram_init( Adjust_pwr_on_status( )

最终在Adjust_pwr_on_status( )这个函数里面会根据文件hsu_chg_boot.c中的函数Get_Power_On_Composite_Event( )所得到的开机原因来判断最终的开机原因。

int Adjust_pwr_on_status(int * PowerOnReason)

)

->

oemsbl_smem_store_pon_status(

)

->

{

int temp = (Pwr_Composite_Event | Pwr_Original_Composite_Event);

int AdjustedPowerReason = pwr_on_status;

int i;

2

深圳国速科技有限公司

if(PM_PWR_ON_EVENT_USB_CHG & temp)

{ // usb chg

AdjustedPowerReason = PM_PWR_ON_EVENT_USB_CHG;

}

if(PM_PWR_ON_EVENT_WALL_CHG & temp)

{ // wall chg

AdjustedPowerReason = PM_PWR_ON_EVENT_WALL_CHG;

}

if(PM_PWR_ON_EVENT_KEYPAD & temp)

{ // keypad

AdjustedPowerReason = PM_PWR_ON_EVENT_KEYPAD;

}

******

3

深圳国速科技有限公司

*PowerOnReason = AdjustedPowerReason;

return 0;

}

在关机插入USB后会执行AdjustedPowerReason =

PM_PWR_ON_EVENT_USB_CHG,将开机原因设置为充电模式,已经过验证不管是插入USB还是AC都是执行这一段代码。开机原因保存在共享内存后,在LK中就可以通过读取共享内存的数据获取开机原因。 3. LK与kernel部分设置充电模式

在进入到LK后,会执行主函数void kmain(void),在这个函数中会创建一个线程bootstrap2用于执行bootstrap2(void *arg)这个函数,bootstrap2( )中调用函数apps_init( )对app进行初始化,这个函数所调用的函数都是已经通过宏定义#define APP_START(appname)声明,bootable\\bootloader\\lk\\app\\aboot.c

中使用

APP_START(aboot) .init = aboot_init, APP_END对aboot_init进行了声明。在apps_init( )中就会调用aboot_init( ),然后进入如下调用流程,

aboot_init( ) -> aboot_init( ) -> boot_linux_from_mmc( ) -> boot_linux( ) 在boot_linux( )中,通过以下代码判断是否需要进入充电模式,通过将pause_at_bootup赋值为1来标识是USB插入开机,在下面的代码中通过这个标识来决定是否进入充电模式。

if (target_pause_for_battery_charge() == PWR_ON_EVENT_USB_CHG && enter_charging_pause)

4

深圳国速科技有限公司

{

pause_at_bootup = 1;

cmdline_len += strlen(battchg_pause);

}

其中函数target_pause_for_battery_charge( )就是通过读取modem写入共享内存的数据来判断开机原因,调用流程如下:target_pause_for_battery_charge( ) –> target_check_power_on_reason( ) -> smem_read_alloc_entry( )

接下来通过如下代码将设置为充电模式的字符串char *battchg_pause = \" androidboot.mode=charger\"保存到cmdline中。最后调用entry(0, machtype, tags)通过tags将cmdline传入并启动kernel。

if (pause_at_bootup)

{

src = battchg_pause;

if (have_cmdline) --dst;

while ((*dst++ = *src++));

}

5

深圳国速科技有限公司

在通过函数void __init start_kernel(void)进入到kernel后,需要执行的函数setup_arch( )和setup_command_line( )读取boot中的cmdline,并且解析里面的信息保存到saved_command_line字符串中,\\qics1003\\kernel\\fs\\proc\\ cmdline.c文件中的proc_cmdline_init( )会创建proc/cmdline节点输出saved_command_line中的信息,android在初始化时就会读取这个节点里面保存的启动模式。 4. Android进入充电模式

在进入到android后会根据LK里面所获取的cmdline来决定是否进入充电模式,首先进入qics1003\\system\\core\\init.c中的main( )函数开始对android进行初始化。这里会调用函数import_kernel_cmdline(0, import_kernel_nv)读取proc/cmdline节点的数据,并且通过函数import_kernel_nv( )将充电的开机原因保存在bootmode中:

static void import_kernel_nv(char *name, int in_qemu)

{

******

} else if (!strcmp(name,\"androidboot.console\")) {

strlcpy(console, value, sizeof(console));

} else if (!strcmp(name,\"androidboot.mode\")) {

strlcpy(bootmode, value, sizeof(bootmode));

6

深圳国速科技有限公司

} else if (!strcmp(name,\"androidboot.serialno\")) {

strlcpy(serialno, value, sizeof(serialno));

******

}

其中androidboot.mode就是在进入充电模式后会是字符串\"

androidboot.mode=charger\"。

通过函数queue_builtin_action(set_init_properties_action, \"set_init_properties\")设置android系统的属性,其中set_init_properties_action( )函数中:

static int set_init_properties_action(int nargs, char **args)

{

char tmp[PROP_VALUE_MAX];

if (qemu[0])

import_kernel_cmdline(1, import_kernel_nv);

if (!strcmp(bootmode,\"factory\"))

property_set(\"ro.factorytest\

7

深圳国速科技有限公司

else if (!strcmp(bootmode,\"factory2\"))

property_set(\"ro.factorytest\

else

property_set(\"ro.factorytest\

property_set(\"ro.serialno\

property_set(\"ro.bootmode\

property_set(\"ro.baseband\

property_set(\"ro.carrier\

property_set(\"ro.bootloader\

property_set(\"ro.bootupmode\

if (modelno[0])

property_set(\"ro.boot.modelno\

property_set(\"ro.hardware\

8

深圳国速科技有限公司

snprintf(tmp, PROP_VALUE_MAX, \"%d\

property_set(\"ro.revision\

property_set(\"ro.emmc\

return 0;

}

通过函数property_set( )设置ro.bootmode为charger,就会触发qics1003\\system\\core\\init.rc中定义的配置文件:

on charger

class_start charger

这里会调用所有声明为class_start类的服务,在

qics1003\\system\\core\\rootdir\\init.qcom.rc中就配置了所需要执行的服务。

service charger /charger

class charger

oneshot

service chg-post-boot /system/bin/sh /system/etc/init.qcom.post_boot.sh

9

深圳国速科技有限公司

class charger

oneshot

在进入到充电服务后就进入\\qics1003\\system\\core\\charger.c文件中的main(int argc, char **argv),这里主要是关机状态充电图标显示、长按按键开机检测和USB拔出后的关机动作。

进入到event_loop( )中。 handle_input_state(charger,

now)

->

process_key(

)

->

exit_offmode_charging( ) 函数实现了在充电模式下长按按键开机功能,update_screen_state(charger, now)实现充电模式下电池图标的显示。

以下代码实现了在充电模式拔下USB后关机功能: if (curr_time_ms() - first_time > 2000){

if ((!is_usb_exist()) && (!is_ac_exist()) && (!is_unknown_exist())){

LOGI(\"[%lld] shutting down\\n\

android_reboot(ANDROID_RB_POWEROFF, 0, 0);

}

}

10

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igat.cn 版权所有 赣ICP备2024042791号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务