Linux系统调用

本文深入探讨Linux系统调用,涵盖x86和arm平台,包括查看系统调用的方法、声明与定义(C和汇编)、调用过程(应用和内核空间),以及不同平台的系统调用表。详细解析了系统调用的实现和使用。
摘要由CSDN通过智能技术生成

0 前言

    本文以x86和arm平台的为例重点分析Linux各版本的系统调用的实现和使用方法。

1 查看

    可通过man查看有哪些系统调用,以及特定函数是否为系统调用[4]:

(1)方法1:man syscalls

图1.1

(2)方法2:man <func_name>

图1.2

2 声明

    从linux-2.6.12到6.5.13,都可在下面头文件之一找到系统调用的声明:

头文件 说明
include/linux/syscalls.h

Linux syscall interfaces (non-arch-specific)

例如:sys_open、sys_read、sys_write

arch/x86/include/asm/syscalls.h

Linux syscall interfaces (arch-specific)

例如:sys_mmap

include/asm-generic/syscalls.h

Calling conventions for these system calls can differ, so it's possible to override them.

例如:sys_mmap

include/trace/events/syscalls.h ftrace相关接口

     例如平台无关部分声明如下:

...
asmlinkage long sys_time(time_t __user *tloc);
asmlinkage long sys_stime(time_t __user *tptr);
asmlinkage long sys_gettimeofday(struct timeval __user *tv,
                struct timezone __user *tz);
...
// @file: linux-2.6.39/include/linux/syscalls.h

3 定义

    多数系统调用都以C函数,但有一些特殊系统调用是汇编定义的。

3.1 汇编

    例如arm的sys_syscall、sys_mmap2等系统调用,都是直接使用汇编定义的:

/*============================================================================
 * Special system call wrappers
 */
sys_syscall:
...
ENDPROC(sys_syscall)

...

sys_mmap2:
...
ENDPROC(sys_mmap2)

...
// @file: linux-6.5.13/arch/arm/kernel/entry-common.S

3.2 C

(1)linux-2.6.31-

    直接采用下面方式进行定义:

asmlinkage long sys_<func_name>(...)
{
    ...
}

    具体案例详见后面mmap的定义。 

(2)linux-2.6.32+

    提供了如下宏来简化系统调用的定义:

#ifdef CONFIG_FTRACE_SYSCALLS
...
#define SYSCALL_DEFINE0(sname)                  \
    SYSCALL_TRACE_ENTER_EVENT(_##sname);            \
    SYSCALL_TRACE_EXIT_EVENT(_##sname);         \
    static const struct syscall_metadata __used     \
      __attribute__((__aligned__(4)))           \
      __attribute__((section("__syscalls_metadata")))   \
      __syscall_meta_##sname = {                \
        .name       = "sys_"#sname,         \
        .nb_args    = 0,                \
        .enter_event    = &event_enter__##sname,    \
        .exit_event = &event_exit__##sname,     \
    };                          \
    asmlinkage long sys_##sname(void)
#else
#define SYSCALL_DEFINE0(name)      asmlinkage long sys_##name(void)
#endif

#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__)
// @file: linux-2.6.32/include/linux/syscalls.h

    上述SYSCALL_DEFINEx的定义因是否支持ftrace而异:

#ifdef CONFIG_FTRACE_SYSCALLS
#define SYSCALL_DEFINEx(x, sname, ...)              \
    static const char *types_##sname[] = {          \
        __SC_STR_TDECL##x(__VA_ARGS__)          \
    };                          \
    static const char *args_##sname[] = {           \
        __SC_STR_ADECL##x(__VA_ARGS__)          \
    };                  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OneSea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值