找MTK相关请查看微博:天川一水的ChinaUnix博客 http://blog.chinaunix.net/uid-29728680-id-5514223.html
下面是一叶梧桐的博客
http://blog.csdn.net/huangyabin001/article/details/44056493
Andorid屏幕唤醒异常,Power按键无法点亮屏幕的分析
http://blog.csdn.net/huangyabin001/article/details/42777703
Android开机时间分析
http://blog.csdn.net/huangyabin001/article/details/41210927Android 系统启动过程
(1)若能抓取mobilelog,则可以在APLog_xxxx文件夹中找到bootprof文件。或者直接cat /proc/bootprof
----------------------------------------
0 BOOT PROF (unit:msec)
----------------------------------------
1077 : preloader // 这里会记录preloader和lk的执行时间,单位为毫秒。
3667 : lk
----------------------------------------
47.188307 : ON
95.973922 : of_init 16992539 ns
124.732076 : ramoops_init 27976001 ns
155.463384 : init_mtk_governor 28810077 ns
208.009307 : arm64_device_init 40170846 ns
245.649461 : pm_sysrq_init 28632231 ns
305.320923 : event_trace_init 25269538 ns
328.487538 : pmic_mt_init 18462461 ns
398.533231 : populate_rootfs 67385539 ns
481.464077 : mtkfb_init 16279692 ns
631.410616 : modem_cd_init 128015693 ns
817.579693 : md_ccif_init 186129616 ns
894.852462 : gf_init 40584231 ns
940.017616 : mt_i2c_init 45137231 ns
1013.895463 : eem_init 23476462 ns
1059.026771 : acc_init 32313847 ns
1116.455540 : gyro_init 57412308 ns
2363.018851 : fpc1022_init 1232834464 ns
2382.414158 : battery_init 18354616 ns
2417.481312 : clk_debug_init 33775692 ns
2450.348466 : mt_soc_snd_init 32818538 ns
2451.768543 : Kernel_init_done
2875.773313 : INIT: on init start
2881.017236 : INIT:Mount_START
3546.686469 : INIT:Mount_END
3550.746930 : start mobicore (on fs)
3553.768623 : start mobicore end (on fs)
3675.040623 : post-fs-data: on modem start
5971.898167 : BOOT_Animation:START // 这里表明已经进入上层。
6684.275630 : Zygote:Preload Start
7112.275554 : Zygote:Preload Start
8761.911327 : Zygote:Preload 3831 classes in 1319ms
8847.152943 : Zygote:Preload 3831 classes in 1424ms
9055.208867 : Zygote:Preload 342 obtain resources in 206ms
9059.303559 : Zygote:Preload 41 resources in 2ms
9076.121251 : Zygote:Preload 342 obtain resources in 313ms
9081.294482 : Zygote:Preload 41 resources in 3ms
9323.764175 : Zygote:Preload End
9481.360175 : Zygote:Preload End
9550.741483 : Android:SysServerInit_START
10059.694100 : Android:PackageManagerService_Start
10326.429639 : Android:PMS_scan_START
10516.254332 : Android:PMS_scan_data_done:/system/framework
11297.080180 : Android:PMS_scan_data_done:/system/priv-app
12650.057491 : Android:PMS_scan_data_done:/system/app
12736.916952 : Android:PMS_scan_data_done:/system/vendor/operator/app
12768.057183 : Android:PMS_scan_data_done:/system/plugin
12771.374414 : Android:PMS_scan_data_done:/data/app
12780.415645 : Android:PMS_scan_END
12952.868184 : Android:PMS_READY
22793.776438 : Android:SysServerInit_END
24645.384365 : BOOT_Animation:END // 这里表示已经开进home界面。
24646.324673 : OFF
----------------------------------------
================ END of FILE ===============
(2) 若不能抓取mobielog,可以直接用uart log抓取,时间的分析可以参考FAQ14851 进入kernel前开机时间分析方法。
Android 系统重启关机流程分析
1.5 Android 系统重启关机流程分析
1.5.1 C语言中调用 reboot 函数
bionic/libc/unistd/reboot.c:33:
int reboot (int mode)
{
return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode,NULL );
}
1.5.2 通过 adb 让系统重启
adb reboot recovery 进入 recovery 模式
adb reboot bootloader 进入 fastboot 模式
adb reboot-bootloader
adb reboot 不带参数 系统正常重启
adb 是pc端工具,adbd是服务端,运行在手机
adbd 读取 socket 解析由 adb 传过来的命令串
int service_to_fd(const char *name)
if(!strncmp(name, "reboot:", 7)) {
void* arg = strdup(name + 7);
if(arg == 0) return -1;
ret = create_service_thread(reboot_service, arg);
system/core/adb/services.c:176:
void reboot_service(int fd, void *arg)
{
。。。
ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_RESTART2, (char *)arg);
。。。
}
bionic/libc/kernel/common/Linux/reboot.h
#define LINUX_REBOOT_CMD_RESTART 0x01234567
#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
kernel/include/linux/reboot.h:33:
#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
arg 对应字符串: recovery bootloader
./kernel/arch/arm/mach-msm/pm2.c
system/core/adb/commandline.c
if (!strcmp(argv[0], "reboot-bootloader"))
snprintf(command, sizeof(command), "reboot:bootloader");
如果输入 adb reboot-bootloader adb 会对该命令进行转换 相当于执行 adb rebootbootloader
1.5.3 fastboot 模式下系统重启
fastboot reboot 系统正常重启
fastboot reboot-bootloader 重启进入fastboot 模式
fastboot 是 appboot 提供的功能,可以用它来烧写 system 等镜像文件
bootable/bootloader/lk/app/aboot/aboot.c
APP_START(aboot)
.init = aboot_init,
void aboot_init(const struct app_descriptor *app)
{
。。。
fastboot_register("reboot", cmd_reboot);
fastboot_register("reboot-bootloader",cmd_reboot_bootloader);
。。。
}
void cmd_reboot(const char *arg, void *data, unsigned sz)
{
dprintf(INFO, "rebooting the device\n");
fastboot_okay("");
reboot_device(0);
}
void cmd_reboot_bootloader(const char *arg, void *data, unsignedsz)
{
dprintf(INFO, "rebooting the device\n");
fastboot_okay("");
reboot_device(FASTBOOT_MODE);
}
bootable/bootloader/lk/target/msm7630_surf/init.c:311:
void reboot_device(unsigned reboot_reason)
bootable/bootloader/lk/target/msm7627_ffa/init.c:174:
void reboot_device(unsigned reboot_reason)
void reboot_device(unsigned reboot_reason)
{
reboot(reboot_reason);
}
调用的是c函数:
bionic/libc/unistd/reboot.c:33:
int reboot (int mode)
{
return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode,NULL );
}
bootable/bootloader/lk/app/aboot/aboot.c:59:
#define FASTBOOT_MODE 0x77665500
if (!strcmp(cmd, "bootloader")) {
restart_reason = 0x77665500;
}
1.5.4 系统关机
正常按键关机
./frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.Java
void showGlobalActionsDialog()
mGlobalActions.showDialog(keyguardShowing,isDeviceProvisioned());
调用文件:
./frameworks/policies/base/phone/com/android/internal/policy/impl/GlobalActions.java
中的函数:
public void showDialog(boolean keyguardShowing, booleanisDeviceProvisioned)
mDialog = createDialog();
调用本文件中的函数:
private AlertDialog createDialog()
public void onPress() {
ShutdownThread.shutdownAfterDisablingRa
}
调用文件:
./frameworks/policies/base/phone/com/android/internal/policy/impl/ShutdownThread.java
中的函数:
public static void shutdownAfterDisablingRa
beginShutdownSequence(context)
调用本文件中的函数:
private static void beginShutdownSequence(Context context)
sInstance.start()
进入关机线程的run函数:
public void run() {
首先关蓝牙,关射频,然后再关电源
...
sBluetooth.disable(false)
...
sPhone.setRadio(false)
...
SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
...
Power.shutdown()
}
frameworks/base/core/java/android/os/Power.java:92:
public static native void shutdown();
frameworks/base/core/jni/android_os_Power.cpp:107:
{ "shutdown", "()V", (void*)android_os_Power_shutdown },
jni 调用
static void android_os_Power_shutdown(JNIEnv *env, jobjectclazz)
{
sync();
#ifdef HAVE_ANDROID_OS
reboot(RB_POWER_OFF);
#endif
}
因为有 bionic/libc/include/sys/reboot.h:42:
#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF
所以实际相对执行
reboot(LINUX_REBOOT_CMD_POWER_OFF);
__reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,LINUX_REBOOT_CMD_POWER_OFF, NULL );
这里的 __reboot 是libc中的系统调用
bionic/libc/arch-x86/syscalls/__reboot.S
#include<sys/linux-syscalls.h>
.text
.type __reboot, #function
.globl __reboot
.align 4
.fnstart
__reboot:
.save {r4, r7}
stmfd sp!, {r4, r7}
ldr r7, =__NR_reboot
swi #0
ldmfd sp!, {r4, r7}
movs r0, r0
bxpl lr
b __set_syscall_errno
.fnend
1.5.5 内核中的系统调用 reboot
__NR_reboot 执行的是内核中的系统调用:
kernel/kernel/sys.c:310:
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int,cmd,
void __user *, arg)
{
char buffer[256];
int ret = 0;
if (!capable(CAP_SYS_BOOT))
return -EPERM;
if (magic1 != LINUX_REBOOT_MAGIC1 ||
(magic2 != LINUX_REBOOT_MAGIC2&&
magic2 != LINUX_REBOOT_MAGIC2A&&
magic2 != LINUX_REBOOT_MAGIC2B&&
magic2 != LINUX_REBOOT_MAGIC2C))
return -EINVAL;
if ((cmd == LINUX_REBOOT_CMD_POWER_OFF)&& !pm_power_off)
cmd = LINUX_REBOOT_CMD_HALT;
lock_kernel();
switch (cmd) {
case LINUX_REBOOT_CMD_RESTART:
kernel_restart(NULL);
break;
case LINUX_REBOOT_CMD_CAD_ON:
C_A_D = 1;
break;
case LINUX_REBOOT_CMD_CAD_OFF:
C_A_D = 0;
break;
case LINUX_REBOOT_CMD_HALT:
kernel_halt();
unlock_kernel();
do_exit(0);
panic("cannot halt");
case LINUX_REBOOT_CMD_POWER_OFF:
kernel_power_off();
unlock_kernel();
do_exit(0);
break;
case LINUX_REBOOT_CMD_RESTART2:
if (strncpy_from_user(&buffer[0], arg,sizeof(buffer) - 1) < 0) {
unlock_kernel();
return -EFAULT;
}
buffer[sizeof(buffer) - 1] = '\0';
kernel_restart(buffer);
break;
#ifdef CONFIG_KEXEC
case LINUX_REBOOT_CMD_KEXEC:
ret = kernel_kexec();
break;
#endif
#ifdef CONFIG_HIBERNATION
case LINUX_REBOOT_CMD_SW_SUSPEND:
ret = hibernate();
break;
#endif
default:
ret = -EINVAL;
break;
}
unlock_kernel();
return ret;
}
void kernel_restart(char *cmd)
{
kernel_restart_prepare(cmd);
if (!cmd)
printk(KERN_EMERG "Restarting system.\n");
else
printk(KERN_EMERG "Restarting system with command '%s'.\n",cmd);
machine_restart(cmd);
}
kernel/kernel/sys.c:341:
void kernel_power_off(void)
{
kernel_shutdown_prepare(SYSTEM_POWER_OFF);
if (pm_power_off_prepare)
pm_power_off_prepare();
disable_nonboot_cpus();
sysdev_shutdown();
printk(KERN_EMERG "Power down.\n");
machine_power_off();
}
./kernel/arch/arm/kernel/process.c:219:
void machine_restart(char *cmd)
{
arm_pm_restart(reboot_mode, cmd);
}
void machine_power_off(void)
{
if (pm_power_off)
pm_power_off();
}
因为./kernel/arch/arm/mach-msm/pm2.c:1740:中有:
arm_pm_restart = msm_pm_restart;
pm_power_off = msm_pm_power_off;
所以 arm_pm_restart 调用的是:
static void msm_pm_restart(char str, const char *cmd)
{
msm_rpcrouter_close();
msm_proc_comm(PCOM_RESET_CHIP, &restart_reason,0);
for (;;)
;
}
pm_power_off 调用的是:
static void msm_pm_power_off(void)
{
msm_rpcrouter_close();
msm_proc_comm(PCOM_POWER_DOWN, 0, 0);
for (;;)
;
}
msm_proc_comm 是芯片级别的操作
msm_proc_comm_reset_modem_now 对modem芯片进行重启
kernel/arch/arm/mach-msm/proc_comm.c:98:
int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned*data2)
{
。。。
writel(cmd, base + APP_COMMAND);
writel(data1 ? *data1 : 0, base + APP_DATA1);
writel(data2 ? *data2 : 0, base + APP_DATA2);
。。。
}
内核里面writel是如何实现的
http://blog.chinaunix.NET/u2/77776/showart_1404857.html
补充信息:
static int msm_reboot_call
(struct notifier_block *this, unsigned long code, void*_cmd)
{
if ((code == SYS_RESTART) &&_cmd) {
char *cmd = _cmd;
if (!strcmp(cmd, "bootloader")) {
restart_reason = 0x77665500;
} else if (!strcmp(cmd, "recovery")) {
restart_reason = 0x77665502;
} else if (!strcmp(cmd, "eraseflash")) {
restart_reason = 0x776655EF;
} else if (!strncmp(cmd, "oem-", 4)) {
unsigned code = simple_strtoul(cmd + 4, 0, 16) &0xff;
restart_reason = 0x6f656d00 | code;
} else {
restart_reason = 0x77665501;
}
}
return NOTIFY_DONE;
}
static struct notifier_block msm_reboot_notifier = {
.notifier_call = msm_reboot_call,
};
static int __init msm_pm_init(void)
register_reboot_notifier(&msm_reboot_notifier);
内核编译相关:
kernel/arch/arm/mach-msm/pm2.c:1701: restart_reason =0x77665500;
kernel/arch/arm/mach-msm/pm.c:696: restart_reason =0x77665500;
kernel/arch/arm/mach-msm/Makefile:84:
ifdef CONFIG_MSM_N_WAY_SMSM
obj-$(CONFIG_PM) += pm2.o
else
obj-$(CONFIG_PM) += pm.o
endif
kernel/arch/arm/configs/msm7630-perf_defconfig:256:CONFIG_MSM_N_WAY_SMSM=y
kernel/arch/arm/configs/msm7627-perf_defconfig:247:CONFIG_MSM_N_WAY_SMSM=y
make -C kernelO=../out/target/product/msm7627_ffa/obj/KERNEL_OBJ ARCH=armCROSS_COMPILE=arm-eabi- msm7627-perf_defconfig
out/target/product/msm7627_ffa/obj/KERNEL_OBJ/.config
CONFIG_MSM_N_WAY_SMSM=y