当前位置:   article > 正文

Android中的linux 系统调用_android syscall

android syscall

Android中的linux 系统调用

在用户空间和内核空间之间,通过Syscall(系统调用, system call)的中间层来通信,连接用户态和内核态的桥梁。在ARM架构中,用户态程序通过swi 软中断进入内核态执行对应的系统调用,对于每一个系统调用都有对应的系统调用号,定义在unistd.h中。通过系统调用的方式,在一定程度上保护了系统的安全。


相关代码位置:

binonic
bionic/libc/kernel/uapi/asm-generic/unistd.h
bionic/libc/kernel/uapi/asm-arm64/asm/unistd.h 
bionic/libc/arch-arm64/bionic/syscall.S
out/soong/.intermediates/bionic/libc/syscalls-arm.S

kernel
arch/arm64/include/asm/unistd32.h
arch/arm64/kernel/entry.S:947:        bl      el0_svc_compat_handler
arch/arm64/kernel/syscall.c:167:asmlinkage void el0_svc_compat_handler(struct pt_regs *regs)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

系统调用号

unistd32.h (arch/arm64/include/asm/unistd32.h)

#define __NR_restart_syscall 0
__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
#define __NR_exit 1
__SYSCALL(__NR_exit, sys_exit)
#define __NR_fork 2
__SYSCALL(__NR_fork, sys_fork)
#define __NR_read 3
__SYSCALL(__NR_read, sys_read)
#define __NR_write 4
__SYSCALL(__NR_write, sys_write)
#define __NR_open 5
__SYSCALL(__NR_open, compat_sys_open)
#define __NR_close 6
__SYSCALL(__NR_close, sys_close)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Android bionic库中将syscalls-arm64.S编译到libc库中

生成路径: out/soong/.intermediates/bionic/libc/syscalls-arm.S

genrule {
    name: "syscalls-arm64.S",
    out: ["syscalls-arm64.S"],
    srcs: ["SYSCALLS.TXT"],
    tool_files: [":bionic-gensyscalls"],
    cmd: "$(location :bionic-gensyscalls) arm64 $(in) > $(out)",
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

syscalls-arm.S

用户态程序通过read,write等系统调用,最终跑到syscalls-arm.S中,通过swi 软中断进入内核态,最终调用到内核entry.S所对应的函数为el0_svc_compat函数,一些汇编相关的指令不懂。

ENTRY(read)
    mov     ip, r7
    .cfi_register r7, ip
    ldr     r7, =__NR_read
    swi     #0
    mov     r7, ip
    .cfi_restore r7
    cmn     r0, #(MAX_ERRNO + 1)
    bxls    lr
    neg     r0, r0
    b       __set_errno_internal
END(read)


ENTRY(write)
    mov     ip, r7
    .cfi_register r7, ip
    ldr     r7, =__NR_write
    swi     #0
    mov     r7, ip
    .cfi_restore r7
    cmn     r0, #(MAX_ERRNO + 1)
    bxls    lr
    neg     r0, r0
    b       __set_errno_internal
END(write)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

entry.S

通过bl指令跳转到el0_svc_compat_handler函数,接下来是C语言的流程

el0_svc_compat:
	gic_prio_kentry_setup tmp=x1
	mov	x0, sp
	bl	el0_svc_compat_handler
	b	ret_to_user
  • 1
  • 2
  • 3
  • 4
  • 5

syscall.c

el0_svc_common函数中间没有复杂逻辑,将寄存器参数和syscall_table传给了invoke_syscall函数,invoke_syscall中判断对应的系统号在syscall_table中是否存在,如果存在则调用对应的sys_xx函数,比如SYSCALL(__NR_exit, sys_exit),不存在则返回错误吗

static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
{
	return syscall_fn(regs);
}

static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
			   const syscall_fn_t syscall_table[])
{
	invoke_syscall(regs, scno, sc_nr, syscall_table);
}

static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
			   unsigned int sc_nr,
			   const syscall_fn_t syscall_table[])
{
	long ret;

	if (scno < sc_nr) {
		syscall_fn_t syscall_fn;
		syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
		ret = __invoke_syscall(regs, syscall_fn);
	} else {
		ret = do_ni_syscall(regs, scno);
	}

	if (is_compat_task())
		ret = lower_32_bits(ret);

	regs->regs[0] = ret;
}

#ifdef CONFIG_COMPAT
asmlinkage void el0_svc_compat_handler(struct pt_regs *regs)
{
	el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls,
		       compat_sys_call_table);
}
#endif

const syscall_fn_t compat_sys_call_table[__NR_compat_syscalls] = {
	[0 ... __NR_compat_syscalls - 1] = __arm64_sys_ni_syscall,
#include <asm/unistd32.h>
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

unistd32.h

#define __NR_restart_syscall 0
__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
#define __NR_exit 1
__SYSCALL(__NR_exit, sys_exit)
#define __NR_fork 2
__SYSCALL(__NR_fork, sys_fork)
#define __NR_read 3
__SYSCALL(__NR_read, sys_read)
#define __NR_write 4
__SYSCALL(__NR_write, sys_write)
#define __NR_open 5
__SYSCALL(__NR_open, compat_sys_open)
#define __NR_close 6
__SYSCALL(__NR_close, sys_close)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

总体流程:

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/214557
推荐阅读
相关标签
  

闽ICP备14008679号