You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核4.14.255中sys_mount等sys_前缀函数的定义问询

Linux 4.14.255内核中sys_前缀函数的定义机制

在4.14.255版本内核里,sys_前缀的系统调用函数并不是用你猜想的简单宏直接定义的,而是靠一套宏包装+系统调用表注册的机制实现的,下面拆解具体细节:

1. 核心宏:SYSCALL_DEFINE*系列

sys_xxx函数的定义是通过SYSCALL_DEFINE*宏展开生成的,这个宏族定义在include/linux/syscalls.h中。

比如你提到的sys_unlink,实际代码里是用SYSCALL_DEFINE1(unlink, const char __user *, pathname)来定义的,这个宏会被预处理器展开为:

asmlinkage long sys_unlink(const char __user *pathname)
{
    // 函数实现逻辑
}

其中asmlinkage是内核属性,强制函数从栈中获取参数——这是系统调用的标准要求,因为用户态和内核态的参数传递规则不同。

2. 为什么直接搜sys_xxx找不到定义?

因为sys_xxx是宏展开后的产物,你直接用文本搜索sys_unlink(大概率找不到,得搜SYSCALL_DEFINE1(unlink才能定位到实际实现:

  • sys_mount的实现在fs/namespace.c里,用SYSCALL_DEFINE5(mount, ...)定义;
  • sys_unlink的实现在fs/namei.c里,用SYSCALL_DEFINE1(unlink, ...)定义。

3. 系统调用表的关联

定义好的sys_xxx函数需要注册到系统调用表,才能被内核的系统调用入口逻辑找到。不同架构的表位置不一样:

  • x86_64:arch/x86/entry/syscalls/syscall_64.tbl,每行格式是调用号 ABI 函数名,比如87 common unlink sys_unlink;
  • x86_32:arch/x86/entry/syscalls/syscall_32.tbl;
  • ARM:arch/arm/kernel/syscall_table.S。

看宏的具体展开逻辑

如果你想深入看SYSCALL_DEFINE*是怎么生成sys_xxx的,打开include/linux/syscalls.h,核心展开逻辑是这样的(简化版):

#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
#define SYSCALL_DEFINEx(x, sname, ...)                  \
    asmlinkage long sys##sname(__SC_DECL##x(__VA_ARGS__)) \
    __attribute__((alias(__stringify(SyS##sname))));    \
    static inline long SYSC##sname(__SC_DECL##x(__VA_ARGS__)); \
    asmlinkage long SyS##sname(__SC_DECL##x(__VA_ARGS__))   \
    {                                                     \
        return SYSC##sname(__SC_ARGS##x(__VA_ARGS__));    \
    }                                                     \
    static inline long SYSC##sname(__SC_DECL##x(__VA_ARGS__))

这个宏会生成sys_xxx的函数声明,并把它和实际实现的SyS_xxx函数做别名关联,最终完成系统调用的定义。

内容的提问来源于stack exchange,提问作者Yanel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 09:50:50