Android系统关机的全流程解析

2019-12-10 19:02:04刘景俊

其被指定了一个固定的偏移量,在被调用的时候就是通过这个偏移量去内核中寻找对应的入口的,由此可见,内核中一定有着相同的定义,否则将不能成功调用。内核中对syscall偏移量的定义在内核源码中的arch/arm/include/asm/unistd.h,相关信息完全一致。
已经找到了内核中的对应映射,那么下一步就要去找寻真正的实现函数了,在include/asm-generic/unistd.h中可以找到内核对__NR_reboot的syscall函数映射,即

/* kernel/sys.c */ 
#define __NR_setpriority 140 
__SYSCALL(__NR_setpriority, sys_setpriority) 
#define __NR_getpriority 141 
__SYSCALL(__NR_getpriority, sys_getpriority) 
#define __NR_reboot 142 
__SYSCALL(__NR_reboot, sys_reboot) 

同时,能够发现如此温馨的一幕,内核已经指引我们下一步该去哪里寻找sys_reboot,即kernel/sys.c。

9.kernel/sys.c
在进入这个文件前,我们先去include/linux/syscalls.h中查看一下sys_reboot的定义:

asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, 
        void __user *arg); 

与__reboot的调用参数一致。
进入sys.c文件后,并没有找到名为sys_reboot的函数,而通过仔细查找,发现一个很有趣的函数,其定义为SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg),对比__reboot的参数,能够符合。究竟是不是这个函数?
同样在include/linux/syscalls.h文件中,能够找到这样几个定义:

#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) 
#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) 
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) 
#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) 
#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) 
#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) 
... 
 
#define SYSCALL_DEFINEx(x, sname, ...)        
  __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) 
... 
 
#define __SYSCALL_DEFINEx(x, name, ...)          
  asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))