作為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后進入對應的模式。
新聞熱點
疑難解答