作为adb adb_commandline是主要的命令处理函数。
作为adbd service_to_fd是接收到socket命令后的处理函数。
adb_main
transport_registration_func
transport_socket_events
handle_packet
create_local_service_socket
service_to_fd
以下部分是reboot的代码执行流程
__reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,LINUX_REBOOT_CMD_RESTART2, (char *)arg);
这个__reboot是调用了bionic/libc/arch-arm/syscalls/__reboot.S
01 | .text |
02 | .type __reboot, #function |
03 | .globl __reboot |
04 | .align 4 |
05 | .fnstart |
06 | __reboot: |
07 | .save {r4, r7} |
08 | stmfd sp!, {r4, r7} |
09 | ldr r7, =__NR_reboot |
10 | swi #0 |
11 | ldmfd sp!, {r4, r7} |
12 | movs r0, r0 |
13 | bxpl lr |
14 | b __set_syscall_errno |
15 | .fnend |
swi # 0系统调用应该等同于int 0x80
__NR_reboot调用定义在kernel/include/asm-generic/unistd.h
#define __NR_reboot 142
__SYSCALL(__NR_reboot, sys_reboot)
sys_reboot实现 LINUX_REBOOT_CMD_RESTART2应该是后来实现,用来拓展参数的。
01 | SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,void __user *, arg) |
02 | { |
03 | ..... |
04 | case LINUX_REBOOT_CMD_RESTART2: |
05 | if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) { |
06 | ret = -EFAULT; |
07 | break; |
08 | } |
09 | buffer[sizeof(buffer) - 1] = '/0'; |
10 |
|
11 | kernel_restart(buffer); |
12 | break; |
13 | ...... |
14 | } |
kernel_restart接口
kernel_restart_prepare(cmd); //这里会调用到msm_reboot_call,在这个接口里会根据str来赋值reboot reason
if ( !cmd)
printk(KERN_EMERG "Restarting system./n");
else
printk(KERN_EMERG "Restarting system with command '%s'./n", cmd);
kmsg_dump(KMSG_DUMP_RESTART);
machine_restart(cmd); //这里会调用到msm_pm_restart
msm_pm_restart 调用 msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0);
把reboot reason写到内存里,机器开启后aboot.c会判断reason后进入对应的模式。
新闻热点
疑难解答